ReXGlue SDK
Loading...
Searching...
No Matches
log_category.h
Go to the documentation of this file.
1
10
11#pragma once
12
13#include <array>
14#include <atomic>
15#include <cstddef>
16#include <cstdlib>
17#include <exception>
18#include <format>
19#include <optional>
20#include <string>
21#include <string_view>
22#include <utility>
23
24#include <rex/platform.h>
25#include <rex/result.h>
26#include <rex/types.h>
27#include <rex/utility.h>
28
29namespace rex::log {
30
32enum class Level : u8 {
35 kDebug,
36 kInfo,
38 kError,
41};
42
44inline constexpr std::array<std::string_view, 8> kLevelNames = {
45 "trace", "dev", "debug", "info", "warn", "error", "critical", "off"};
46
48inline constexpr size_t kMessageLevelCount = 7;
49
56[[nodiscard]] REX_API Result<Level> ParseLevel(std::string_view text);
57
59REX_API std::string_view LevelName(Level level);
60
61} // namespace rex::log
62
63namespace rex::log {
64
65class DetailAccess;
66
71class REX_API LogCategory : public NonCopyable {
72 public:
74 static constexpr u16 kUnresolved = 0xFFFF;
75
82 constexpr LogCategory(std::string_view name, std::string_view description) noexcept
83 : name_(name), description_(description) {}
84
85 constexpr std::string_view GetName() const { return name_; }
86
87 constexpr std::string_view GetDescription() const { return description_; }
88
94 bool IsEnabled(Level level) const;
95
96 private:
97 friend class DetailAccess;
98
99 std::string_view name_;
100 std::string_view description_;
101 mutable std::atomic<u16> slot_ = kUnresolved;
102};
103
105 std::string name;
106 std::string description;
108 std::optional<Level>
110 bool registered = false;
111};
112
113namespace detail {
114
115REX_API void Write(const LogCategory& category, Level level, std::string_view text);
116
118REX_API void WriteFailure(const LogCategory& category, const char* what) noexcept;
119
121REX_API void WriteArgs(const LogCategory& category, Level level, std::string_view fmt,
122 std::format_args args) noexcept;
123
125template <typename... Args>
126void WriteFormatted(const LogCategory& category, Level level, std::format_string<Args...> fmt,
127 Args&&... args) noexcept {
128 WriteArgs(category, level, fmt.get(), std::make_format_args(args...));
129}
130
137REX_API void WriteStub(const LogCategory& category, std::atomic_flag& seen, std::string_view name,
138 std::string_view detail);
139
141template <typename... Categories>
142constexpr std::array<const LogCategory*, sizeof...(Categories)> BuildTable(
143 const Categories&... categories) noexcept {
144 return {static_cast<const LogCategory*>(&categories)...};
145}
146
147} // namespace detail
148
149} // namespace rex::log
150
162#define REXLOG_CATEGORY(name, description) \
163 namespace rex::log { \
164 inline constinit ::rex::log::LogCategory name{#name, description}; \
165 }
166
179#define REXLOG_TABLE(table, ...) \
180 namespace rex::log { \
181 inline constexpr auto table = ::rex::log::detail::BuildTable(__VA_ARGS__); \
182 }
183
184namespace rex::log {
185
187template <size_t Count>
189 public:
195 bool IsFirst(size_t key) noexcept {
196 if (key >= Count) {
197 return true;
198 }
199 const u64 bit = u64{1} << (key % 64);
200 return (words_[key / 64].fetch_or(bit, std::memory_order_relaxed) & bit) == 0;
201 }
202
203 private:
204 std::array<std::atomic<u64>, (Count + 63) / 64> words_{};
205};
206
209
216template <typename Fn>
217void NoThrow(const LogCategory& category, Fn&& fn) noexcept {
218 try {
219 std::forward<Fn>(fn)();
220 } catch (const std::exception& error) {
221 detail::WriteFormatted(category, Level::kError, "teardown step failed, {}", error.what());
222 } catch (...) {
223 detail::WriteFormatted(category, Level::kError, "teardown step failed, unknown exception");
224 }
225}
226
227} // namespace rex::log
228
241#define REXLOG_DETAIL_WRITE(cat, level, fmt, ...) \
242 do { \
243 if ((cat).IsEnabled(level)) { \
244 ::rex::log::detail::WriteFormatted((cat), level, fmt __VA_OPT__(, ) __VA_ARGS__); \
245 } \
246 } while (0)
247
262#define REXLOG_CAT_ONCE(cat, level, once, key, fmt, ...) \
263 do { \
264 if ((cat).IsEnabled(level) && (once).IsFirst(key)) { \
265 ::rex::log::detail::WriteFormatted((cat), level, fmt __VA_OPT__(, ) __VA_ARGS__); \
266 } \
267 } while (0)
268
280#define REXLOG_CAT_TRACE(cat, fmt, ...) \
281 REXLOG_DETAIL_WRITE(cat, ::rex::log::Level::kTrace, fmt __VA_OPT__(, ) __VA_ARGS__)
282
294#define REXLOG_CAT_DEV(cat, fmt, ...) \
295 REXLOG_DETAIL_WRITE(cat, ::rex::log::Level::kDev, fmt __VA_OPT__(, ) __VA_ARGS__)
296
308#define REXLOG_CAT_DEBUG(cat, fmt, ...) \
309 REXLOG_DETAIL_WRITE(cat, ::rex::log::Level::kDebug, fmt __VA_OPT__(, ) __VA_ARGS__)
310
322#define REXLOG_CAT_INFO(cat, fmt, ...) \
323 REXLOG_DETAIL_WRITE(cat, ::rex::log::Level::kInfo, fmt __VA_OPT__(, ) __VA_ARGS__)
324
336#define REXLOG_CAT_WARN(cat, fmt, ...) \
337 REXLOG_DETAIL_WRITE(cat, ::rex::log::Level::kWarn, fmt __VA_OPT__(, ) __VA_ARGS__)
338
350#define REXLOG_CAT_ERROR(cat, fmt, ...) \
351 REXLOG_DETAIL_WRITE(cat, ::rex::log::Level::kError, fmt __VA_OPT__(, ) __VA_ARGS__)
352
364#define REXLOG_CAT_CRITICAL(cat, fmt, ...) \
365 REXLOG_DETAIL_WRITE(cat, ::rex::log::Level::kCritical, fmt __VA_OPT__(, ) __VA_ARGS__)
366
379#define REX_CAT_FAIL(cat, value, fmt, ...) \
380 do { \
381 REXLOG_CAT_ERROR(cat, fmt __VA_OPT__(, ) __VA_ARGS__); \
382 return value; \
383 } while (0)
384
396#define REX_CAT_FATAL(cat, fmt, ...) \
397 do { \
398 REXLOG_CAT_CRITICAL(cat, fmt __VA_OPT__(, ) __VA_ARGS__); \
399 ::rex::log::Flush(); \
400 ::std::abort(); \
401 } while (0)
402
415#define REX_CAT_CHECK(cat, cond, fmt, ...) \
416 do { \
417 if (!(cond)) { \
418 REX_CAT_FATAL(cat, "check failed: " #cond ". " fmt __VA_OPT__(, ) __VA_ARGS__); \
419 } \
420 } while (0)
421
422REXLOG_CATEGORY(core, "Core library, provider loading, settings and the app lifecycle")
423REXLOG_CATEGORY(system,
424 "Kernel objects, guest threads, guest memory and modules, and the host threads and "
425 "memory under them")
426REXLOG_CATEGORY(apu, "APU emulation, XMA decoding and the audio output modules")
427REXLOG_CATEGORY(filesystem, "Mount table, links and file providers")
428REXLOG_CATEGORY(gpu, "Xenos emulation, shader translation and the host graphics paths")
429REXLOG_CATEGORY(hid, "Pads, keyboard and pointer, and the hid modules")
430REXLOG_CATEGORY(cpu, "Function dispatch and the PPC context")
431REXLOG_CATEGORY(ui, "Windows, presenters, overlays and ImGui")
432REXLOG_CATEGORY(console, "Console command output")
433
449#define REXLOG_TRACE(fmt, ...) REXLOG_CAT_TRACE(::rex::log::core, fmt __VA_OPT__(, ) __VA_ARGS__)
450#define REXLOG_DEV(fmt, ...) REXLOG_CAT_DEV(::rex::log::core, fmt __VA_OPT__(, ) __VA_ARGS__)
451#define REXLOG_DEBUG(fmt, ...) REXLOG_CAT_DEBUG(::rex::log::core, fmt __VA_OPT__(, ) __VA_ARGS__)
452#define REXLOG_INFO(fmt, ...) REXLOG_CAT_INFO(::rex::log::core, fmt __VA_OPT__(, ) __VA_ARGS__)
453#define REXLOG_WARN(fmt, ...) REXLOG_CAT_WARN(::rex::log::core, fmt __VA_OPT__(, ) __VA_ARGS__)
454#define REXLOG_ERROR(fmt, ...) REXLOG_CAT_ERROR(::rex::log::core, fmt __VA_OPT__(, ) __VA_ARGS__)
455#define REXLOG_CRITICAL(fmt, ...) \
456 REXLOG_CAT_CRITICAL(::rex::log::core, fmt __VA_OPT__(, ) __VA_ARGS__)
457#define REXLOG_WARN_ONCE(once, key, fmt, ...) \
458 REXLOG_CAT_ONCE(::rex::log::core, ::rex::log::Level::kWarn, once, key, \
459 fmt __VA_OPT__(, ) __VA_ARGS__)
460#define REX_FAIL(value, fmt, ...) \
461 REX_CAT_FAIL(::rex::log::core, value, fmt __VA_OPT__(, ) __VA_ARGS__)
462#define REX_FATAL(fmt, ...) REX_CAT_FATAL(::rex::log::core, fmt __VA_OPT__(, ) __VA_ARGS__)
463#define REX_CHECK(cond, fmt, ...) \
464 do { \
465 if (!(cond)) { \
466 REX_FATAL("check failed: " #cond ". " fmt __VA_OPT__(, ) __VA_ARGS__); \
467 } \
468 } while (0)
469
470#define REXSYS_TRACE(fmt, ...) REXLOG_CAT_TRACE(::rex::log::system, fmt __VA_OPT__(, ) __VA_ARGS__)
471#define REXSYS_DEV(fmt, ...) REXLOG_CAT_DEV(::rex::log::system, fmt __VA_OPT__(, ) __VA_ARGS__)
472#define REXSYS_DEBUG(fmt, ...) REXLOG_CAT_DEBUG(::rex::log::system, fmt __VA_OPT__(, ) __VA_ARGS__)
473#define REXSYS_INFO(fmt, ...) REXLOG_CAT_INFO(::rex::log::system, fmt __VA_OPT__(, ) __VA_ARGS__)
474#define REXSYS_WARN(fmt, ...) REXLOG_CAT_WARN(::rex::log::system, fmt __VA_OPT__(, ) __VA_ARGS__)
475#define REXSYS_ERROR(fmt, ...) REXLOG_CAT_ERROR(::rex::log::system, fmt __VA_OPT__(, ) __VA_ARGS__)
476#define REXSYS_CRITICAL(fmt, ...) \
477 REXLOG_CAT_CRITICAL(::rex::log::system, fmt __VA_OPT__(, ) __VA_ARGS__)
478#define REXSYS_WARN_ONCE(once, key, fmt, ...) \
479 REXLOG_CAT_ONCE(::rex::log::system, ::rex::log::Level::kWarn, once, key, \
480 fmt __VA_OPT__(, ) __VA_ARGS__)
481#define REXSYS_FAIL(value, fmt, ...) \
482 REX_CAT_FAIL(::rex::log::system, value, fmt __VA_OPT__(, ) __VA_ARGS__)
483#define REXSYS_FATAL(fmt, ...) REX_CAT_FATAL(::rex::log::system, fmt __VA_OPT__(, ) __VA_ARGS__)
484#define REXSYS_CHECK(cond, fmt, ...) \
485 do { \
486 if (!(cond)) { \
487 REXSYS_FATAL("check failed: " #cond ". " fmt __VA_OPT__(, ) __VA_ARGS__); \
488 } \
489 } while (0)
490
491#define REXAPU_TRACE(fmt, ...) REXLOG_CAT_TRACE(::rex::log::apu, fmt __VA_OPT__(, ) __VA_ARGS__)
492#define REXAPU_DEV(fmt, ...) REXLOG_CAT_DEV(::rex::log::apu, fmt __VA_OPT__(, ) __VA_ARGS__)
493#define REXAPU_DEBUG(fmt, ...) REXLOG_CAT_DEBUG(::rex::log::apu, fmt __VA_OPT__(, ) __VA_ARGS__)
494#define REXAPU_INFO(fmt, ...) REXLOG_CAT_INFO(::rex::log::apu, fmt __VA_OPT__(, ) __VA_ARGS__)
495#define REXAPU_WARN(fmt, ...) REXLOG_CAT_WARN(::rex::log::apu, fmt __VA_OPT__(, ) __VA_ARGS__)
496#define REXAPU_ERROR(fmt, ...) REXLOG_CAT_ERROR(::rex::log::apu, fmt __VA_OPT__(, ) __VA_ARGS__)
497#define REXAPU_CRITICAL(fmt, ...) \
498 REXLOG_CAT_CRITICAL(::rex::log::apu, fmt __VA_OPT__(, ) __VA_ARGS__)
499#define REXAPU_WARN_ONCE(once, key, fmt, ...) \
500 REXLOG_CAT_ONCE(::rex::log::apu, ::rex::log::Level::kWarn, once, key, \
501 fmt __VA_OPT__(, ) __VA_ARGS__)
502#define REXAPU_FAIL(value, fmt, ...) \
503 REX_CAT_FAIL(::rex::log::apu, value, fmt __VA_OPT__(, ) __VA_ARGS__)
504#define REXAPU_FATAL(fmt, ...) REX_CAT_FATAL(::rex::log::apu, fmt __VA_OPT__(, ) __VA_ARGS__)
505#define REXAPU_CHECK(cond, fmt, ...) \
506 do { \
507 if (!(cond)) { \
508 REXAPU_FATAL("check failed: " #cond ". " fmt __VA_OPT__(, ) __VA_ARGS__); \
509 } \
510 } while (0)
511
512#define REXFS_TRACE(fmt, ...) \
513 REXLOG_CAT_TRACE(::rex::log::filesystem, fmt __VA_OPT__(, ) __VA_ARGS__)
514#define REXFS_DEV(fmt, ...) REXLOG_CAT_DEV(::rex::log::filesystem, fmt __VA_OPT__(, ) __VA_ARGS__)
515#define REXFS_DEBUG(fmt, ...) \
516 REXLOG_CAT_DEBUG(::rex::log::filesystem, fmt __VA_OPT__(, ) __VA_ARGS__)
517#define REXFS_INFO(fmt, ...) REXLOG_CAT_INFO(::rex::log::filesystem, fmt __VA_OPT__(, ) __VA_ARGS__)
518#define REXFS_WARN(fmt, ...) REXLOG_CAT_WARN(::rex::log::filesystem, fmt __VA_OPT__(, ) __VA_ARGS__)
519#define REXFS_ERROR(fmt, ...) \
520 REXLOG_CAT_ERROR(::rex::log::filesystem, fmt __VA_OPT__(, ) __VA_ARGS__)
521#define REXFS_CRITICAL(fmt, ...) \
522 REXLOG_CAT_CRITICAL(::rex::log::filesystem, fmt __VA_OPT__(, ) __VA_ARGS__)
523#define REXFS_WARN_ONCE(once, key, fmt, ...) \
524 REXLOG_CAT_ONCE(::rex::log::filesystem, ::rex::log::Level::kWarn, once, key, \
525 fmt __VA_OPT__(, ) __VA_ARGS__)
526#define REXFS_FAIL(value, fmt, ...) \
527 REX_CAT_FAIL(::rex::log::filesystem, value, fmt __VA_OPT__(, ) __VA_ARGS__)
528#define REXFS_FATAL(fmt, ...) REX_CAT_FATAL(::rex::log::filesystem, fmt __VA_OPT__(, ) __VA_ARGS__)
529#define REXFS_CHECK(cond, fmt, ...) \
530 do { \
531 if (!(cond)) { \
532 REXFS_FATAL("check failed: " #cond ". " fmt __VA_OPT__(, ) __VA_ARGS__); \
533 } \
534 } while (0)
535
536#define REXGPU_TRACE(fmt, ...) REXLOG_CAT_TRACE(::rex::log::gpu, fmt __VA_OPT__(, ) __VA_ARGS__)
537#define REXGPU_DEV(fmt, ...) REXLOG_CAT_DEV(::rex::log::gpu, fmt __VA_OPT__(, ) __VA_ARGS__)
538#define REXGPU_DEBUG(fmt, ...) REXLOG_CAT_DEBUG(::rex::log::gpu, fmt __VA_OPT__(, ) __VA_ARGS__)
539#define REXGPU_INFO(fmt, ...) REXLOG_CAT_INFO(::rex::log::gpu, fmt __VA_OPT__(, ) __VA_ARGS__)
540#define REXGPU_WARN(fmt, ...) REXLOG_CAT_WARN(::rex::log::gpu, fmt __VA_OPT__(, ) __VA_ARGS__)
541#define REXGPU_ERROR(fmt, ...) REXLOG_CAT_ERROR(::rex::log::gpu, fmt __VA_OPT__(, ) __VA_ARGS__)
542#define REXGPU_CRITICAL(fmt, ...) \
543 REXLOG_CAT_CRITICAL(::rex::log::gpu, fmt __VA_OPT__(, ) __VA_ARGS__)
544#define REXGPU_WARN_ONCE(once, key, fmt, ...) \
545 REXLOG_CAT_ONCE(::rex::log::gpu, ::rex::log::Level::kWarn, once, key, \
546 fmt __VA_OPT__(, ) __VA_ARGS__)
547#define REXGPU_FAIL(value, fmt, ...) \
548 REX_CAT_FAIL(::rex::log::gpu, value, fmt __VA_OPT__(, ) __VA_ARGS__)
549#define REXGPU_FATAL(fmt, ...) REX_CAT_FATAL(::rex::log::gpu, fmt __VA_OPT__(, ) __VA_ARGS__)
550#define REXGPU_CHECK(cond, fmt, ...) \
551 do { \
552 if (!(cond)) { \
553 REXGPU_FATAL("check failed: " #cond ". " fmt __VA_OPT__(, ) __VA_ARGS__); \
554 } \
555 } while (0)
556
557#define REXHID_TRACE(fmt, ...) REXLOG_CAT_TRACE(::rex::log::hid, fmt __VA_OPT__(, ) __VA_ARGS__)
558#define REXHID_DEV(fmt, ...) REXLOG_CAT_DEV(::rex::log::hid, fmt __VA_OPT__(, ) __VA_ARGS__)
559#define REXHID_DEBUG(fmt, ...) REXLOG_CAT_DEBUG(::rex::log::hid, fmt __VA_OPT__(, ) __VA_ARGS__)
560#define REXHID_INFO(fmt, ...) REXLOG_CAT_INFO(::rex::log::hid, fmt __VA_OPT__(, ) __VA_ARGS__)
561#define REXHID_WARN(fmt, ...) REXLOG_CAT_WARN(::rex::log::hid, fmt __VA_OPT__(, ) __VA_ARGS__)
562#define REXHID_ERROR(fmt, ...) REXLOG_CAT_ERROR(::rex::log::hid, fmt __VA_OPT__(, ) __VA_ARGS__)
563#define REXHID_CRITICAL(fmt, ...) \
564 REXLOG_CAT_CRITICAL(::rex::log::hid, fmt __VA_OPT__(, ) __VA_ARGS__)
565#define REXHID_WARN_ONCE(once, key, fmt, ...) \
566 REXLOG_CAT_ONCE(::rex::log::hid, ::rex::log::Level::kWarn, once, key, \
567 fmt __VA_OPT__(, ) __VA_ARGS__)
568#define REXHID_FAIL(value, fmt, ...) \
569 REX_CAT_FAIL(::rex::log::hid, value, fmt __VA_OPT__(, ) __VA_ARGS__)
570#define REXHID_FATAL(fmt, ...) REX_CAT_FATAL(::rex::log::hid, fmt __VA_OPT__(, ) __VA_ARGS__)
571#define REXHID_CHECK(cond, fmt, ...) \
572 do { \
573 if (!(cond)) { \
574 REXHID_FATAL("check failed: " #cond ". " fmt __VA_OPT__(, ) __VA_ARGS__); \
575 } \
576 } while (0)
577
578#define REXCPU_TRACE(fmt, ...) REXLOG_CAT_TRACE(::rex::log::cpu, fmt __VA_OPT__(, ) __VA_ARGS__)
579#define REXCPU_DEV(fmt, ...) REXLOG_CAT_DEV(::rex::log::cpu, fmt __VA_OPT__(, ) __VA_ARGS__)
580#define REXCPU_DEBUG(fmt, ...) REXLOG_CAT_DEBUG(::rex::log::cpu, fmt __VA_OPT__(, ) __VA_ARGS__)
581#define REXCPU_INFO(fmt, ...) REXLOG_CAT_INFO(::rex::log::cpu, fmt __VA_OPT__(, ) __VA_ARGS__)
582#define REXCPU_WARN(fmt, ...) REXLOG_CAT_WARN(::rex::log::cpu, fmt __VA_OPT__(, ) __VA_ARGS__)
583#define REXCPU_ERROR(fmt, ...) REXLOG_CAT_ERROR(::rex::log::cpu, fmt __VA_OPT__(, ) __VA_ARGS__)
584#define REXCPU_CRITICAL(fmt, ...) \
585 REXLOG_CAT_CRITICAL(::rex::log::cpu, fmt __VA_OPT__(, ) __VA_ARGS__)
586#define REXCPU_WARN_ONCE(once, key, fmt, ...) \
587 REXLOG_CAT_ONCE(::rex::log::cpu, ::rex::log::Level::kWarn, once, key, \
588 fmt __VA_OPT__(, ) __VA_ARGS__)
589#define REXCPU_FAIL(value, fmt, ...) \
590 REX_CAT_FAIL(::rex::log::cpu, value, fmt __VA_OPT__(, ) __VA_ARGS__)
591#define REXCPU_FATAL(fmt, ...) REX_CAT_FATAL(::rex::log::cpu, fmt __VA_OPT__(, ) __VA_ARGS__)
592#define REXCPU_CHECK(cond, fmt, ...) \
593 do { \
594 if (!(cond)) { \
595 REXCPU_FATAL("check failed: " #cond ". " fmt __VA_OPT__(, ) __VA_ARGS__); \
596 } \
597 } while (0)
598
599#define REXUI_TRACE(fmt, ...) REXLOG_CAT_TRACE(::rex::log::ui, fmt __VA_OPT__(, ) __VA_ARGS__)
600#define REXUI_DEV(fmt, ...) REXLOG_CAT_DEV(::rex::log::ui, fmt __VA_OPT__(, ) __VA_ARGS__)
601#define REXUI_DEBUG(fmt, ...) REXLOG_CAT_DEBUG(::rex::log::ui, fmt __VA_OPT__(, ) __VA_ARGS__)
602#define REXUI_INFO(fmt, ...) REXLOG_CAT_INFO(::rex::log::ui, fmt __VA_OPT__(, ) __VA_ARGS__)
603#define REXUI_WARN(fmt, ...) REXLOG_CAT_WARN(::rex::log::ui, fmt __VA_OPT__(, ) __VA_ARGS__)
604#define REXUI_ERROR(fmt, ...) REXLOG_CAT_ERROR(::rex::log::ui, fmt __VA_OPT__(, ) __VA_ARGS__)
605#define REXUI_CRITICAL(fmt, ...) REXLOG_CAT_CRITICAL(::rex::log::ui, fmt __VA_OPT__(, ) __VA_ARGS__)
606#define REXUI_WARN_ONCE(once, key, fmt, ...) \
607 REXLOG_CAT_ONCE(::rex::log::ui, ::rex::log::Level::kWarn, once, key, \
608 fmt __VA_OPT__(, ) __VA_ARGS__)
609#define REXUI_FAIL(value, fmt, ...) \
610 REX_CAT_FAIL(::rex::log::ui, value, fmt __VA_OPT__(, ) __VA_ARGS__)
611#define REXUI_FATAL(fmt, ...) REX_CAT_FATAL(::rex::log::ui, fmt __VA_OPT__(, ) __VA_ARGS__)
612#define REXUI_CHECK(cond, fmt, ...) \
613 do { \
614 if (!(cond)) { \
615 REXUI_FATAL("check failed: " #cond ". " fmt __VA_OPT__(, ) __VA_ARGS__); \
616 } \
617 } while (0)
618
619#define REXCON_TRACE(fmt, ...) REXLOG_CAT_TRACE(::rex::log::console, fmt __VA_OPT__(, ) __VA_ARGS__)
620#define REXCON_DEV(fmt, ...) REXLOG_CAT_DEV(::rex::log::console, fmt __VA_OPT__(, ) __VA_ARGS__)
621#define REXCON_DEBUG(fmt, ...) REXLOG_CAT_DEBUG(::rex::log::console, fmt __VA_OPT__(, ) __VA_ARGS__)
622#define REXCON_INFO(fmt, ...) REXLOG_CAT_INFO(::rex::log::console, fmt __VA_OPT__(, ) __VA_ARGS__)
623#define REXCON_WARN(fmt, ...) REXLOG_CAT_WARN(::rex::log::console, fmt __VA_OPT__(, ) __VA_ARGS__)
624#define REXCON_ERROR(fmt, ...) REXLOG_CAT_ERROR(::rex::log::console, fmt __VA_OPT__(, ) __VA_ARGS__)
625#define REXCON_CRITICAL(fmt, ...) \
626 REXLOG_CAT_CRITICAL(::rex::log::console, fmt __VA_OPT__(, ) __VA_ARGS__)
627#define REXCON_WARN_ONCE(once, key, fmt, ...) \
628 REXLOG_CAT_ONCE(::rex::log::console, ::rex::log::Level::kWarn, once, key, \
629 fmt __VA_OPT__(, ) __VA_ARGS__)
630#define REXCON_FAIL(value, fmt, ...) \
631 REX_CAT_FAIL(::rex::log::console, value, fmt __VA_OPT__(, ) __VA_ARGS__)
632#define REXCON_FATAL(fmt, ...) REX_CAT_FATAL(::rex::log::console, fmt __VA_OPT__(, ) __VA_ARGS__)
633#define REXCON_CHECK(cond, fmt, ...) \
634 do { \
635 if (!(cond)) { \
636 REXCON_FATAL("check failed: " #cond ". " fmt __VA_OPT__(, ) __VA_ARGS__); \
637 } \
638 } while (0)
Definition log_category.h:71
static constexpr u16 kUnresolved
Definition log_category.h:74
bool IsEnabled(Level level) const
constexpr LogCategory(std::string_view name, std::string_view description) noexcept
Definition log_category.h:82
Definition log_category.h:188
bool IsFirst(size_t key) noexcept
Definition log_category.h:195
#define REXLOG_CATEGORY(name, description)
Definition log_category.h:162
Definition log_category.h:29
Result< Level > ParseLevel(std::string_view text)
void NoThrow(const LogCategory &category, Fn &&fn) noexcept
Definition log_category.h:217
constexpr size_t kMessageLevelCount
Definition log_category.h:48
Level
Definition log_category.h:32
@ kInfo
Definition log_category.h:36
@ kCritical
Definition log_category.h:39
@ kWarn
Definition log_category.h:37
@ kDev
Definition log_category.h:34
@ kOff
Definition log_category.h:40
@ kError
Definition log_category.h:38
@ kTrace
Definition log_category.h:33
constexpr std::array< std::string_view, 8 > kLevelNames
Definition log_category.h:44
std::string_view LevelName(Level level)
void Flush()
std::expected< T, Error > Result
Definition result.h:98
Platform flags, packing macros and export markers.
#define REX_API
Definition platform.h:177
Definition log_category.h:104
Level level
Definition log_category.h:107
std::optional< Level > explicit_level
Definition log_category.h:109
bool registered
Definition log_category.h:110
Integer types, byte order wrappers and size literals.
Move only function, const propagating pointer and scope guard.