#pragma once #include #include #include #include #include #include #include #include #include #include #include namespace flow { namespace detail { template constexpr auto run_func() -> void { if (CTNode::condition) { if constexpr (not FlowName.empty()) { using log_spec_t = decltype(get_log_spec>()); CIB_LOG_ENV(logging::get_level, log_spec_t::level); CIB_LOG(typename log_spec_t::flavor, "flow.{}({})", typename CTNode::type_t{}, typename CTNode::name_t{}); } typename CTNode::func_t{}(); } } } // namespace detail template struct impl { using node_t = FunctionPtr; std::array functionPtrs{}; constexpr static auto name = Name; template constexpr static auto create_node(CTNode) -> node_t { constexpr auto fp = detail::run_func; return fp; } constexpr explicit(true) impl(stdx::span steps) { std::copy(std::cbegin(steps), std::cend(steps), std::begin(functionPtrs)); } }; namespace detail { template struct inlined_func_list { constexpr static auto active = sizeof...(FuncPtrs) > 0; constexpr static auto ct_name = Name; __attribute__((flatten, always_inline)) auto operator()() const -> void { constexpr static bool loggingEnabled = not Name.empty(); constexpr auto name = stdx::ct_string_to_type(); if constexpr (loggingEnabled) { using log_spec_t = decltype(get_log_spec()); CIB_LOG_ENV(logging::get_level, log_spec_t::level); CIB_LOG(typename log_spec_t::flavor, "flow.start({})", name); } (FuncPtrs(), ...); if constexpr (loggingEnabled) { using log_spec_t = decltype(get_log_spec()); CIB_LOG_ENV(logging::get_level, log_spec_t::level); CIB_LOG(typename log_spec_t::flavor, "flow.end({})", name); } } }; } // namespace detail } // namespace flow