nngn
Loading...
Searching...
No Matches
log.h
Go to the documentation of this file.
1#ifndef NNGN_LOG_H
2#define NNGN_LOG_H
3
4#include <array>
5#include <sstream>
6#include <string>
7#include <tuple>
8
9#define NNGN_LOG_CONTEXT(n) NNGN_LOG_CONTEXT2(n, nullptr)
10#define NNGN_LOG_CONTEXT_F() NNGN_LOG_CONTEXT2(__func__, nullptr)
11#define NNGN_LOG_CONTEXT_CF(c) NNGN_LOG_CONTEXT2(#c, __func__)
12#define NNGN_LOG_CONTEXT2(n0, n1) \
13 const auto NNGN_LOG_CONTEXT_VAR(__LINE__) = nngn::Log::context(n0, n1);
14#define NNGN_LOG_CONTEXT_VAR(l) NNGN_LOG_CONTEXT_JOIN(lc_, l)
15#define NNGN_LOG_CONTEXT_JOIN(x, y) x##y
16
17namespace nngn {
18
19class Log {
20public:
21 static constexpr uint8_t MAX_DEPTH = 16;
22private:
23 static std::ostream *stream;
24 static thread_local uint8_t depth;
25 using record = std::tuple<const char*, const char*>;
26 static thread_local std::array<record, MAX_DEPTH> stack;
27 friend std::ostream &operator<<(std::ostream &os, Log::record r);
28public:
29 struct context {
30 context(const char *name0, const char *name1);
31 context(const context&) = delete;
32 context(const context&&) = delete;
33 context &operator=(const context&) = delete;
34 context &operator=(const context&&) = delete;
36 };
37 class replace {
38 std::ostream *old;
39 public:
40 explicit replace(std::ostream *l) : old(Log::set(l)) {}
41 replace(const replace&) = delete;
42 replace(const replace&&) = delete;
43 replace &operator=(const replace&) = delete;
44 replace &operator=(const replace&&) = delete;
45 ~replace() { Log::set(this->old); }
46 };
47 static std::ostream *set(std::ostream *l);
48 static std::ostream &l();
49 static void perror(const char *s = nullptr);
50 template<typename F> static std::string capture(F f);
51 template<typename F> static decltype(auto) with_context(
52 const char *name, F f);
53};
54
55template<typename F>
56std::string Log::capture(F f) {
57 std::stringstream ss;
58 const Log::replace o(&ss);
59 f();
60 return ss.str();
61}
62
63template<typename F>
64decltype(auto) Log::with_context(const char *name, F f) {
66 return f();
67}
68
69}
70
71#endif
Definition: log.h:37
replace(const replace &&)=delete
replace(std::ostream *l)
Definition: log.h:40
std::ostream * old
Definition: log.h:38
replace & operator=(const replace &&)=delete
~replace()
Definition: log.h:45
replace(const replace &)=delete
replace & operator=(const replace &)=delete
Definition: log.h:19
static constexpr uint8_t MAX_DEPTH
Definition: log.h:21
static std::ostream * set(std::ostream *l)
Definition: log.cpp:53
std::tuple< const char *, const char * > record
Definition: log.h:25
friend std::ostream & operator<<(std::ostream &os, Log::record r)
Definition: log.cpp:29
static thread_local uint8_t depth
Definition: log.h:24
static void perror(const char *s=nullptr)
static std::ostream & l()
static std::ostream * stream
Definition: log.h:23
static thread_local std::array< record, MAX_DEPTH > stack
Definition: log.h:26
static std::ostream & l()
Definition: log.cpp:56
static std::string capture(F f)
Definition: log.h:56
static with_context(const char *name, F f)
static std::string capture(F f)
static std::ostream * set(std::ostream *l)
r
Definition: gamma.lua:7
name
Definition: cathedral.lua:11
set
Definition: camera.lua:40
function f()) end
std::chrono::seconds s
Definition: timing.cpp:6
#define NNGN_LOG_CONTEXT(n)
Definition: log.h:9
#define F(...)
Definition: pp.cpp:12
Definition: audio.cpp:7
Definition: log.h:29
context(const context &&)=delete
context(const char *name0, const char *name1)
context & operator=(const context &)=delete
context(const context &)=delete
context & operator=(const context &&)=delete