From be7d3312d9cb6a6d046fcac9e18ab5abdf4a5466 Mon Sep 17 00:00:00 2001 From: Ben Deane Date: Thu, 10 Jul 2025 16:09:56 -0600 Subject: [PATCH] :arrow_up: Update `stdx` for new formatting Problem: - `stdx` provides a formatting macro that auto-preserves the `constexpr` nature of arguments; CIB log macros do not yet do the same. Solution: - Update `stdx` and log macros. --- CMakeLists.txt | 5 ++-- include/cib/detail/runtime_conditional.hpp | 6 ++-- include/flow/graph_builder.hpp | 24 ++++++++------- include/log/log.hpp | 33 +++++--------------- include/log/pp_map.hpp | 35 ---------------------- include/msg/callback.hpp | 5 ++-- test/log/encoder.cpp | 3 +- test/log/log.cpp | 22 +++++++------- test/msg/message.cpp | 11 ++++++- 9 files changed, 51 insertions(+), 93 deletions(-) delete mode 100644 include/log/pp_map.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a869a833..70202138 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ include(cmake/string_catalog.cmake) add_versioned_package("gh:boostorg/mp11#boost-1.83.0") fmt_recipe(11.1.3) add_versioned_package("gh:intel/cpp-baremetal-concurrency#0ddce52") -add_versioned_package("gh:intel/cpp-std-extensions#effadd4") +add_versioned_package("gh:intel/cpp-std-extensions#3023efe") add_versioned_package("gh:intel/cpp-baremetal-senders-and-receivers#22c8006") set(GEN_STR_CATALOG @@ -120,8 +120,7 @@ target_sources( include/log/flavor.hpp include/log/level.hpp include/log/log.hpp - include/log/module.hpp - include/log/pp_map.hpp) + include/log/module.hpp) add_library(cib_msg INTERFACE) target_compile_features(cib_msg INTERFACE cxx_std_20) diff --git a/include/cib/detail/runtime_conditional.hpp b/include/cib/detail/runtime_conditional.hpp index 238d271f..b8dc15a9 100644 --- a/include/cib/detail/runtime_conditional.hpp +++ b/include/cib/detail/runtime_conditional.hpp @@ -82,10 +82,8 @@ operator and(runtime_condition const &lhs, return lhs; } else { - constexpr auto name = - stdx::ct_format<"{} and {}">(CX_VALUE(LhsName), CX_VALUE(RhsName)); - - return runtime_condition{}; + constexpr auto name = STDX_CT_FORMAT("{} and {}", LhsName, RhsName); + return runtime_condition{}; } } diff --git a/include/flow/graph_builder.hpp b/include/flow/graph_builder.hpp index fc318a39..cd7cc1eb 100644 --- a/include/flow/graph_builder.hpp +++ b/include/flow/graph_builder.hpp @@ -75,8 +75,8 @@ struct graph_builder { for_each( [&]( dsl::edge const &) { - auto lhs = get>(named_nodes); - auto rhs = get>(named_nodes); + auto const lhs = get>(named_nodes); + auto const rhs = get>(named_nodes); using lhs_t = std::remove_cvref_t; using rhs_t = std::remove_cvref_t; @@ -84,7 +84,7 @@ struct graph_builder { using rhs_cond_t = std::remove_cvref_t; using edge_ps_t = decltype(Cond::predicates); - auto node_ps = stdx::to_unsorted_set(stdx::tuple_cat( + constexpr auto node_ps = stdx::to_unsorted_set(stdx::tuple_cat( lhs_t::condition.predicates, rhs_t::condition.predicates)); stdx::for_each( @@ -95,11 +95,9 @@ struct graph_builder { "weaker than those on {}[{}] or {}[{}]. " "Specifically, the sequence is missing the " "predicate: {}", - CX_VALUE(lhs_t::ct_name), CX_VALUE(rhs_t::ct_name), - CX_VALUE(Cond::ct_name), CX_VALUE(lhs_t::ct_name), - CX_VALUE(lhs_cond_t::ct_name), - CX_VALUE(rhs_t::ct_name), - CX_VALUE(rhs_cond_t::ct_name), CX_VALUE(P)); + lhs_t::ct_name, rhs_t::ct_name, Cond::ct_name, + lhs_t::ct_name, lhs_cond_t::ct_name, rhs_t::ct_name, + rhs_cond_t::ct_name, P); }, node_ps); @@ -174,6 +172,7 @@ struct graph_builder { return x + ", "_ctst + y; }); + // NOLINTNEXTLINE (readability-function-cognitive-complexity) constexpr static void check_for_missing_nodes(auto nodes, auto mentioned_nodes) { constexpr auto get_name = [](N) -> @@ -187,21 +186,24 @@ struct graph_builder { using missing_nodes_t = boost::mp11::mp_set_difference; + constexpr auto missing_nodes = error_steps; STATIC_ASSERT( (std::is_same_v), "One or more steps are referenced in the flow ({}) but not " - "explicitly added with the * operator. The missing steps are: {}.", - CX_VALUE(Name), CX_VALUE(error_steps)); + "explicitly added with the * operator. The missing steps are: " + "{}.", + Name, missing_nodes); constexpr auto duplicates = stdx::transform( [](auto e) { return stdx::get<0>(e); }, stdx::filter(stdx::gather(node_names))); using duplicate_nodes_t = decltype(duplicates); + constexpr auto dup_nodes = error_steps; STATIC_ASSERT( stdx::tuple_size_v == 0, "One or more steps in the flow ({}) are explicitly added more than " "once using the * operator. The duplicate steps are: {}.", - CX_VALUE(Name), CX_VALUE(error_steps)); + Name, dup_nodes); } template diff --git a/include/log/log.hpp b/include/log/log.hpp index 096c48a3..c387e77f 100644 --- a/include/log/log.hpp +++ b/include/log/log.hpp @@ -4,12 +4,12 @@ #include #include #include -#include #include #include #include #include +#include #if __cpp_pack_indexing < 202311L #include #endif @@ -74,32 +74,13 @@ template constexpr auto cx_log_wrap(int, auto &&...args) { // NOLINTBEGIN(cppcoreguidelines-macro-usage) -#define CIB_CX_WRAP1(X) \ - [&](auto f) { \ - if constexpr (::logging::detail::is_already_ct) { \ - return f(); \ - } else if constexpr (requires { \ - stdx::ct<[&]() constexpr { return X; }()>; \ - }) { \ - return stdx::ct(); \ - } else { \ - return f(); \ - } \ - }([&] { return X; }) - -#define CIB_CX_WRAP(...) __VA_OPT__(, CIB_CX_WRAP1(__VA_ARGS__)) - -#define CIB_LOG(MSG, ...) \ - logging::log(__FILE__, __LINE__, \ - logging::detail::cx_log_wrap( \ - 0 CIB_MAP(CIB_CX_WRAP, __VA_ARGS__))) - -#define CIB_LOG_WITH_LEVEL(LEVEL, MSG, ...) \ +#define CIB_LOG(...) \ + logging::log(__FILE__, __LINE__, STDX_CT_FORMAT(__VA_ARGS__)) + +#define CIB_LOG_WITH_LEVEL(LEVEL, ...) \ logging::log< \ stdx::extend_env_t>( \ - __FILE__, __LINE__, \ - logging::detail::cx_log_wrap( \ - 0 CIB_MAP(CIB_CX_WRAP, __VA_ARGS__))) + __FILE__, __LINE__, STDX_CT_FORMAT(__VA_ARGS__)) #define CIB_TRACE(...) \ CIB_LOG_WITH_LEVEL(logging::level::TRACE __VA_OPT__(, ) __VA_ARGS__) @@ -160,7 +141,7 @@ template #define CIB_FATAL(MSG, ...) \ logging::detail::panic( \ - __FILE__, __LINE__ CIB_MAP(CIB_CX_WRAP, __VA_ARGS__)) + __FILE__, __LINE__ __VA_OPT__(, STDX_MAP(CX_WRAP, __VA_ARGS__))) #define CIB_ASSERT(expr, ...) \ ((expr) \ diff --git a/include/log/pp_map.hpp b/include/log/pp_map.hpp deleted file mode 100644 index 0e8818d3..00000000 --- a/include/log/pp_map.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -// NOLINTBEGIN(cppcoreguidelines-macro-usage) - -#define CIB_EVAL0(...) __VA_ARGS__ -#define CIB_EVAL1(...) CIB_EVAL0(CIB_EVAL0(CIB_EVAL0(__VA_ARGS__))) -#define CIB_EVAL2(...) CIB_EVAL1(CIB_EVAL1(CIB_EVAL1(__VA_ARGS__))) -#define CIB_EVAL3(...) CIB_EVAL2(CIB_EVAL2(CIB_EVAL2(__VA_ARGS__))) -#define CIB_EVAL4(...) CIB_EVAL3(CIB_EVAL3(CIB_EVAL3(__VA_ARGS__))) -#define CIB_EVAL5(...) CIB_EVAL4(CIB_EVAL4(CIB_EVAL4(__VA_ARGS__))) -#define CIB_EVAL(...) CIB_EVAL5(__VA_ARGS__) - -#define CIB_MAP_END(...) -#define CIB_MAP_OUT - -#define CIB_EMPTY() -#define CIB_DEFER(id) id CIB_EMPTY() - -#define CIB_MAP_GET_END2() 0, CIB_MAP_END -#define CIB_MAP_GET_END1(...) CIB_MAP_GET_END2 -#define CIB_MAP_GET_END(...) CIB_MAP_GET_END1 -#define CIB_MAP_NEXT0(test, next, ...) next CIB_MAP_OUT -#define CIB_MAP_NEXT1(test, next) CIB_DEFER(CIB_MAP_NEXT0)(test, next, 0) -#define CIB_MAP_NEXT(test, next) CIB_MAP_NEXT1(CIB_MAP_GET_END test, next) -#define CIB_MAP_INC(X) CIB_MAP_INC_##X - -#define CIB_MAP0(f, x, peek, ...) \ - f(x) CIB_DEFER(CIB_MAP_NEXT(peek, CIB_MAP1))(f, peek, __VA_ARGS__) -#define CIB_MAP1(f, x, peek, ...) \ - f(x) CIB_DEFER(CIB_MAP_NEXT(peek, CIB_MAP0))(f, peek, __VA_ARGS__) - -#define CIB_MAP(f, ...) \ - CIB_EVAL(CIB_MAP1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -// NOLINTEND(cppcoreguidelines-macro-usage) diff --git a/include/msg/callback.hpp b/include/msg/callback.hpp index f955308c..c32d0e21 100644 --- a/include/msg/callback.hpp +++ b/include/msg/callback.hpp @@ -28,14 +28,15 @@ struct callback { } template + // NOLINTNEXTLINE (readability-function-cognitive-complexity) [[nodiscard]] auto handle(auto const &data, Args &&...args) const -> bool { CIB_LOG_ENV(logging::get_level, logging::level::INFO); if (msg::call_with_message(matcher, data)) { CIB_APPEND_LOG_ENV(typename Msg::env_t); + auto const desc = matcher.describe(); CIB_LOG("Incoming message matched [{}], because [{}]{}, executing " "callback", - stdx::cts_t{}, matcher.describe(), - stdx::cts_t{}); + stdx::cts_t{}, desc, stdx::cts_t{}); msg::call_with_message(callable, data, std::forward(args)...); return true; diff --git a/test/log/encoder.cpp b/test/log/encoder.cpp index 4d69d438..d5d7a26f 100644 --- a/test/log/encoder.cpp +++ b/test/log/encoder.cpp @@ -355,9 +355,10 @@ TEST_CASE("injection - log implicit compile-time arg (int)", "[mipi]") { } TEST_CASE("injection - log implicit compile-time arg (string)", "[mipi]") { + using namespace stdx::literals; test_critical_section::count = 0; expected_args.clear(); - CIB_TRACE("Hello {}", stdx::ct_string{"world"}); + CIB_TRACE("Hello {}", "world"_cts); CHECK(test_critical_section::count == 2); } diff --git a/test/log/log.cpp b/test/log/log.cpp index 39de1c51..7fc4fe07 100644 --- a/test/log/log.cpp +++ b/test/log/log.cpp @@ -81,7 +81,7 @@ TEST_CASE("CIB_FATAL pre-formats arguments passed to panic", "[log]") { reset_test_state(); expected_why = "Hello 42"; - CIB_FATAL("{} {}", "Hello"_ctst, stdx::ct<42>()); + CIB_FATAL("{} {}", "Hello", 42); CAPTURE(buffer); CHECK(buffer.find("Hello 42") != std::string::npos); CHECK(panicked); @@ -115,27 +115,28 @@ TEST_CASE("CIB_FATAL can format stack arguments (2)", "[log]") { TEST_CASE("CIB_FATAL formats compile-time arguments where possible", "[log]") { using namespace stdx::literals; reset_test_state(); - expected_why = "Hello 42"; + expected_why = "Hello 17"; expected_args = std::make_tuple(stdx::make_tuple()); []() { - CIB_FATAL("{} {}", S, 42); + CIB_FATAL("{} {}", S, 17); }.template operator()<"Hello">(); CAPTURE(buffer); - CHECK(buffer.find("Hello 42") != std::string::npos); + CHECK(buffer.find("Hello 17") != std::string::npos); CHECK(panicked); } TEST_CASE("CIB_FATAL passes extra arguments to panic", "[log]") { reset_test_state(); expected_why = "Hello {}"; - expected_args = std::make_tuple(stdx::make_tuple(42), stdx::ct<17>()); + expected_args = std::make_tuple(stdx::make_tuple(17), 18); - auto x = 42; - CIB_FATAL("Hello {}", x, 17); + auto x = 17; + auto y = 18; + CIB_FATAL("Hello {}", x, y); CAPTURE(buffer); - CHECK(buffer.find("Hello 42") != std::string::npos); + CHECK(buffer.find("Hello 17") != std::string::npos); CHECK(panicked); } @@ -152,9 +153,10 @@ TEST_CASE("CIB_ASSERT is equivalent to CIB_FATAL on failure", "[log]") { TEST_CASE("CIB_ASSERT passes arguments to panic", "[log]") { reset_test_state(); expected_why = "Assertion failure: true == false"; - expected_args = std::make_tuple(stdx::make_tuple(), stdx::ct<42>()); + expected_args = std::make_tuple(stdx::make_tuple(), 17); - CIB_ASSERT(true == false, 42); + auto x = 17; + CIB_ASSERT(true == false, x); CAPTURE(buffer); CHECK(buffer.find(expected_why) != std::string::npos); CHECK(panicked); diff --git a/test/msg/message.cpp b/test/msg/message.cpp index dc54b687..972ca41b 100644 --- a/test/msg/message.cpp +++ b/test/msg/message.cpp @@ -379,7 +379,16 @@ TEST_CASE("less_than_or_equal_to matcher", "[message]") { TEST_CASE("describe a message", "[message]") { test_msg m{"f1"_field = 0xba11, "f2"_field = 0x42, "f3"_field = 0xd00d}; - CIB_INFO("{}", m.describe()); + auto const desc = m.describe(); +#if __clang_major__ == 14 + // workaround: clang-14 ICE with CIB_INFO here + logging::log>( + __FILE__, __LINE__, stdx::ct_format<"{}">(desc)); +#else + CIB_INFO("{}", desc); +#endif + CAPTURE(log_buffer); CHECK(log_buffer.find("msg(f1: 0xba11, id: 0x80, f3: 0xd00d, f2: 0x42)") != std::string::npos);