|
9 | 9 | #include <stdx/ct_format.hpp>
|
10 | 10 | #include <stdx/ct_string.hpp>
|
11 | 11 | #include <stdx/panic.hpp>
|
| 12 | +#if __cpp_pack_indexing < 202311L |
| 13 | +#include <stdx/tuple.hpp> |
| 14 | +#endif |
12 | 15 | #include <stdx/type_traits.hpp>
|
13 | 16 | #include <stdx/utility.hpp>
|
14 | 17 |
|
@@ -74,14 +77,57 @@ static auto log(TArgs &&...args) -> void {
|
74 | 77 | #define CIB_ERROR(...) \
|
75 | 78 | CIB_LOG_WITH_LEVEL(logging::level::ERROR __VA_OPT__(, ) __VA_ARGS__)
|
76 | 79 |
|
| 80 | +namespace logging::detail { |
| 81 | +template <stdx::ct_string Fmt, typename Env, typename F, typename L> |
| 82 | +[[nodiscard]] constexpr auto panic(F file, L line, auto &&...args) { |
| 83 | + STDX_PRAGMA(diagnostic push) |
| 84 | +#ifdef __clang__ |
| 85 | + STDX_PRAGMA(diagnostic ignored "-Wunknown-warning-option") |
| 86 | + STDX_PRAGMA(diagnostic ignored "-Wc++26-extensions") |
| 87 | +#endif |
| 88 | + |
| 89 | + constexpr auto N = stdx::num_fmt_specifiers<Fmt>; |
| 90 | + constexpr auto sz = sizeof...(args); |
| 91 | + using env_t = |
| 92 | + stdx::extend_env_t<Env, logging::get_level, logging::level::FATAL>; |
| 93 | + |
| 94 | +#if __cpp_pack_indexing >= 202311L |
| 95 | + auto s = [&]<std::size_t... Is>(std::index_sequence<Is...>) { |
| 96 | + return stdx::ct_format<Fmt>(FWD(args...[Is])...); |
| 97 | + }(std::make_index_sequence<N>{}); |
| 98 | + logging::log<env_t>(file, line, s); |
| 99 | + |
| 100 | + [&]<std::size_t... Is>(std::index_sequence<Is...>) { |
| 101 | + stdx::panic<decltype(s.str)::value>(std::move(s).args, |
| 102 | + FWD(args...[N + Is])...); |
| 103 | + }(std::make_index_sequence<sz - N>{}); |
| 104 | +#else |
| 105 | + auto tup = stdx::make_tuple(FWD(args)...); |
| 106 | + auto t = [&]<std::size_t... Is, std::size_t... Js>( |
| 107 | + std::index_sequence<Is...>, std::index_sequence<Js...>) { |
| 108 | + return stdx::make_tuple( |
| 109 | + stdx::make_tuple(stdx::get<Is>(std::move(tup))...), |
| 110 | + stdx::make_tuple(stdx::get<sizeof...(Is) + Js>(std::move(tup))...)); |
| 111 | + }(std::make_index_sequence<N>{}, std::make_index_sequence<sz - N>{}); |
| 112 | + |
| 113 | + auto s = stdx::get<0>(std::move(t)).apply([](auto &&...fmt_args) { |
| 114 | + return stdx::ct_format<Fmt>(FWD(fmt_args)...); |
| 115 | + }); |
| 116 | + logging::log<env_t>(file, line, s); |
| 117 | + |
| 118 | + stdx::get<1>(std::move(t)).apply([&](auto &&...extra_args) { |
| 119 | + stdx::panic<decltype(s.str)::value>(std::move(s).args, |
| 120 | + FWD(extra_args)...); |
| 121 | + }); |
| 122 | +#endif |
| 123 | + |
| 124 | + STDX_PRAGMA(diagnostic pop) |
| 125 | +} |
| 126 | +} // namespace logging::detail |
| 127 | + |
77 | 128 | #define CIB_FATAL(MSG, ...) \
|
78 |
| - [](auto &&s) { \ |
79 |
| - CIB_LOG_ENV(logging::get_level, logging::level::FATAL); \ |
80 |
| - logging::log<cib_log_env_t>(__FILE__, __LINE__, s); \ |
81 |
| - FWD(s).args.apply([](auto &&...args) { \ |
82 |
| - stdx::panic<decltype(s.str)::value>(FWD(args)...); \ |
83 |
| - }); \ |
84 |
| - }(stdx::ct_format<MSG>(__VA_ARGS__)) |
| 129 | + logging::detail::panic<MSG, cib_log_env_t>( \ |
| 130 | + __FILE__, __LINE__ __VA_OPT__(, ) __VA_ARGS__) |
85 | 131 |
|
86 | 132 | #define CIB_ASSERT(expr) \
|
87 | 133 | ((expr) ? void(0) : CIB_FATAL("Assertion failure: " #expr))
|
|
0 commit comments