Foundation
Loading...
Searching...
No Matches
Logging.hpp
Go to the documentation of this file.
1#pragma once
2// XXX: fmt gets transitively included this way.
3#define FMT_EXCEPTIONS 0
4#include <fmt/base.h>
5#include <fmt/format.h>
6#include <cstdlib>
7#if defined(_MSC_VER)
8#include <intrin.h>
9#endif
10#include <iterator>
11#include "Allocator.hpp"
19// NOLINTBEGIN
20template<bool Ansi = true>
21constexpr const char* format_as(LogLevel level)
22{
23 if constexpr (Ansi)
24 {
25 switch (level)
26 {
27 case LogDebug: return "\033[34mD";
28 case LogInfo: return "\033[37mI";
29 case LogWarn: return "\033[33mW";
30 case LogError: return "\033[31mE";
31 }
32 }
33 else
34 {
35 switch (level)
36 {
37 case LogDebug: return "D";
38 case LogInfo: return "I";
39 case LogWarn: return "W";
40 case LogError: return "E";
41 }
42 }
43 return "?";
44}
45
46// NOLINTEND
47
48extern void Foundation_LogImpl(LogLevel level, const char* tag, const char* formatted);
49// To stdout
50extern void Foundation_PrintImpl(const char* formatted, bool flush);
51
52template<typename ...Args>
53void Foundation_Log(const char* tag, LogLevel level, fmt::format_string<Args...> format, Args&&... args)
54{
55 fmt::basic_memory_buffer<char, fmt::inline_buffer_size, Foundation::Core::StlDefaultAllocator<char>> buffer;
56 fmt::format_to(std::back_inserter(buffer), format, std::forward<Args>(args)...);
57 buffer.push_back('\0');
58 Foundation_LogImpl(level, tag, buffer.data());
59}
60
61namespace Foundation::Core
62{
63 template <typename... Args>
64 void Print(fmt::format_string<Args...> format, Args&&... args)
65 {
66 fmt::basic_memory_buffer<char, fmt::inline_buffer_size, StlDefaultAllocator<char>> buffer;
67 fmt::format_to(std::back_inserter(buffer), format, std::forward<Args>(args)...);
68 buffer.push_back('\0');
69 Foundation_PrintImpl(buffer.data(), false);
70 }
71
72 template <typename... Args>
73 void Println(fmt::format_string<Args...> format, Args&&... args)
74 {
75 Print(format, std::forward<Args>(args)...);
76 Foundation_PrintImpl("\n", true);
77 }
78} // namespace Foundation::Core
79
80#define LOG(TAG, LEVEL, FORMAT, ...) Foundation_Log(#TAG, LEVEL, FORMAT __VA_OPT__(,) __VA_ARGS__);
81
82#if defined(_MSC_VER)
83#define FOUNDATION_TRAP() __debugbreak()
84#elif defined(__clang__) && __has_builtin(__builtin_debugtrap)
85#define FOUNDATION_TRAP() __builtin_debugtrap()
86#else
87#define FOUNDATION_TRAP() __builtin_trap()
88#endif
89#define FOUNDATION_STRINGIFY_2(x) #x
90#define FOUNDATION_STRINGIFY(x) FOUNDATION_STRINGIFY_2(x)
91#define FOUNDATION_SOURCE_LOC __FILE__ "@" FOUNDATION_STRINGIFY(__LINE__)
92#define CHECK(expr) do { \
93 if (!(expr)) [[unlikely]] { \
94 LOG(Core, LogError, "Check failed: {}", FOUNDATION_SOURCE_LOC ":" #expr); \
95 FOUNDATION_TRAP(); \
96 std::terminate(); \
97 } \
98} while (false);
99
100#define CHECK_MSG(expr, format_str, ...) do { \
101 if (!(expr)) [[unlikely]] { \
102 LOG(Core, LogError, "Check failed: {}", FOUNDATION_SOURCE_LOC ":" #expr); \
103 LOG(Core, LogError, format_str __VA_OPT__(,) __VA_ARGS__); \
104 FOUNDATION_TRAP(); \
105 std::terminate(); \
106 } \
107} while (false);
void Foundation_Log(const char *tag, LogLevel level, fmt::format_string< Args... > format, Args &&... args)
Definition Logging.hpp:53
void Foundation_LogImpl(LogLevel level, const char *tag, const char *formatted)
Definition Logging.cpp:7
void Foundation_PrintImpl(const char *formatted, bool flush)
Definition Logging.cpp:16
constexpr const char * format_as(LogLevel level)
Definition Logging.hpp:21
LogLevel
Definition Logging.hpp:13
@ LogWarn
Definition Logging.hpp:16
@ LogDebug
Definition Logging.hpp:14
@ LogError
Definition Logging.hpp:17
@ LogInfo
Definition Logging.hpp:15
void Foundation_PrintImpl(const char *formatted, bool flush)
Definition Logging.cpp:16
Lock-free atomic primitives and implementations of data structures.
Definition Allocator.hpp:6
void Println(fmt::format_string< Args... > format, Args &&... args)
Definition Logging.hpp:73
void Print(fmt::format_string< Args... > format, Args &&... args)
Definition Logging.hpp:64