#pragma once #include #include #include #include namespace logging { template struct prop { [[nodiscard]] CONSTEVAL static auto query(decltype(Query)) noexcept { return Value; } }; namespace detail { template concept valid_query_for = requires { Env::query(Q{}); }; template concept valid_query_over = (... or valid_query_for); template struct has_query { template using fn = std::bool_constant>; }; } // namespace detail template struct env { template Q> CONSTEVAL static auto query(Q) noexcept { using I = boost::mp11::mp_find_if_q, detail::has_query>; using E = boost::mp11::mp_at, I>; return Q{}(E{}); } }; namespace detail { template struct autowrap { // NOLINTNEXTLINE(google-explicit-constructor) CONSTEVAL autowrap(T t) : value(t) {} T value; }; // NOLINTNEXTLINE(modernize-avoid-c-arrays) template using str_lit_t = char const (&)[N]; template struct autowrap> { // NOLINTNEXTLINE(google-explicit-constructor) CONSTEVAL autowrap(str_lit_t str) : value(str) {} stdx::ct_string value; }; template autowrap(T) -> autowrap; template autowrap(str_lit_t) -> autowrap>; template struct wrap { constexpr static auto value = V; }; template struct for_each_pair; template struct for_each_pair> { template using type = env< prop...>, 2 * Is>::value.value, stdx::ct...>, 2 * Is + 1>::value.value>()>...>; }; } // namespace detail template > constexpr auto make_env = [] { using new_env_t = typename detail::for_each_pair< std::make_index_sequence>::template type; return boost::mp11::mp_append{}; }; template using make_env_t = decltype(make_env<>.template operator()()); } // namespace logging using cib_log_env_t = logging::env<>; // NOLINTBEGIN(cppcoreguidelines-macro-usage) #ifdef __clang__ #define CIB_PRAGMA_SEMI #else #define CIB_PRAGMA_SEMI ; #endif #define CIB_LOG_ENV_DECL(...) \ [[maybe_unused]] typedef decltype([] { \ using new_env_t = \ typename logging::detail::for_each_pair>::template type<_env_args...>; \ return boost::mp11::mp_append{}; \ }.template operator()<__VA_ARGS__>()) cib_log_env_t #define CIB_LOG_ENV(...) \ STDX_PRAGMA(diagnostic push) \ STDX_PRAGMA(diagnostic ignored "-Wshadow") \ CIB_LOG_ENV_DECL(__VA_ARGS__) \ CIB_PRAGMA_SEMI \ STDX_PRAGMA(diagnostic pop) #define CIB_WITH_LOG_ENV(...) \ STDX_PRAGMA(diagnostic push) \ STDX_PRAGMA(diagnostic ignored "-Wshadow") \ if constexpr (CIB_LOG_ENV_DECL(__VA_ARGS__); true) \ STDX_PRAGMA(diagnostic pop) // NOLINTEND(cppcoreguidelines-macro-usage)