FE 0.15.0
A C++23 toolkit for writing compiler/interpreter frontends.
Loading...
Searching...
No Matches
log.h
Go to the documentation of this file.
1#pragma once
2
3#include <cassert>
4#include <concepts>
5
6#include <ostream>
7#include <print>
8#include <source_location>
9#include <sstream>
10#include <string_view>
11#include <type_traits>
12
13#include "fe/assert.h"
14#include "fe/format.h"
15#include "fe/loc.h"
16#include "fe/term.h"
17
18namespace fe {
19
20/// Facility to log what you are doing.
21class Log {
22public:
23 enum class Level {
25 Warn,
26 Info,
27 Verbose,
28 Debug,
29 Trace,
30 E = Error,
31 W = Warn,
32 I = Info,
33 V = Verbose,
34 D = Debug,
35 T = Trace,
36 };
37
38 /// @name Getters
39 ///@{
40 Level level() const { return max_level_; }
41 std::ostream& ostream() const {
42 assert(ostream_);
43 return *ostream_;
44 }
45 explicit operator bool() const { return ostream_; } ///< Checks if Log::ostream_ is set.
46 ///@}
47
48 /// @name Setters
49 ///@{
50 Log& set(std::ostream* ostream) {
51 ostream_ = ostream;
52 return *this;
53 }
54 Log& set(Level max_level) {
55 max_level_ = max_level;
56 return *this;
57 }
58 ///@}
59
60 /// A cite_string that remembers where it was written.
61 template<class... Args>
62 struct FmtLoc {
63 template<class S>
64 requires std::convertible_to<const S&, std::string_view>
65 consteval FmtLoc(const S& fmt, std::source_location loc = std::source_location::current())
66 : fmt(fmt)
67 , loc(loc) {}
68
69 cite_string<Args...> fmt;
70 std::source_location loc;
71 };
72
73 /// Puts the `Args` of a Log::FmtLoc parameter into a non-deduced context, so that they are deduced from the
74 /// trailing arguments and the format string keeps capturing its call site.
75 template<class... Args>
77
78 /// @name Log
79 /// Output @p fmt to Log::ostream; does nothing if Log::ostream is `nullptr`.
80 ///@{
81 template<class... Args>
82 void log(Level level, Loc loc, cite_string<Args...> fmt, Args&&... args) const {
83 if (ostream_ && level <= max_level_) emit(level, loc, fmt, std::forward<Args>(args)...);
84 }
85
86 /// A std::source_location is no Loc: it points into *your* source, which has no fe::Src.
87 template<class... Args>
88 void log(Level level, std::source_location where, cite_string<Args...> fmt, Args&&... args) const {
89 if (ostream_ && level <= max_level_)
90 emit(level, std::format("{}:{}", where.file_name(), where.line()), fmt, std::forward<Args>(args)...);
91 }
92
93 /// Points at the call site.
94 template<class... Args>
95 void log(Level level, Fmt<Args...> fmt, Args&&... args) const {
96 log(level, fmt.loc, fmt.fmt, std::forward<Args>(args)...);
97 }
98 ///@}
99
100 /// @name Level Shorthands
101 /// Log at a fixed Level, pointing at the call site.
102 ///@{
103 // clang-format off
104 template<class... Args> void e(Fmt<Args...> fmt, Args&&... args) const { log(Level::E, fmt, std::forward<Args>(args)...); }
105 template<class... Args> void w(Fmt<Args...> fmt, Args&&... args) const { log(Level::W, fmt, std::forward<Args>(args)...); }
106 template<class... Args> void i(Fmt<Args...> fmt, Args&&... args) const { log(Level::I, fmt, std::forward<Args>(args)...); }
107 template<class... Args> void v(Fmt<Args...> fmt, Args&&... args) const { log(Level::V, fmt, std::forward<Args>(args)...); }
108 // clang-format on
109 ///@}
110
111 /// @name Debug Shorthands
112 /// Vaporize to nothingness in `Release` build; the arguments are still evaluated.
113 ///@{
114#ifndef NDEBUG
115 // clang-format off
116 template<class... Args> void d(Fmt<Args...> fmt, Args&&... args) const { log(Level::Debug, fmt, std::forward<Args>(args)...); }
117 template<class... Args> void t(Fmt<Args...> fmt, Args&&... args) const { log(Level::Trace, fmt, std::forward<Args>(args)...); }
118#else
119 template<class... Args> void d(Fmt<Args...>, Args&&...) const {}
120 template<class... Args> void t(Fmt<Args...>, Args&&...) const {}
121#endif
122 // clang-format on
123 ///@}
124
125 /// @name Breakpoints
126 ///@{
127 bool break_on_error = false;
128 bool break_on_warn = false;
129 ///@}
130
131 /// @name Conversions
132 ///@{
133 static char level2acro(Level level);
135 ///@}
136
137private:
138 /// Renders into a detached buffer, so a `` `citation` `` follows the same Mode::Auto decision the
139 /// term::FG values of the prefix do; see fe/term.h.
140 template<class W, class... Args>
141 void emit(Level level, const W& where, cite_string<Args...> fmt, Args&&... args) const {
142 auto oss = std::ostringstream();
143 term::render_cite(oss, term::detail::vformat_cite(fmt.get(), args...));
144 std::println(ostream(), "{}{}:{}{}:{} {}", level2color(level), level2acro(level), term::FG::Gray, where,
145 term::FG::Reset, oss.str());
147 }
148
149 std::ostream* ostream_ = nullptr;
150 Level max_level_ = Level::E;
151};
152
153} // namespace fe
Collects diagnostics and hands each to the Diag that lays it out.
Definition error.h:23
Facility to log what you are doing.
Definition log.h:21
Log & set(std::ostream *ostream)
Definition log.h:50
void e(Fmt< Args... > fmt, Args &&... args) const
Definition log.h:104
bool break_on_warn
Definition log.h:128
FmtLoc< std::type_identity_t< Args >... > Fmt
Puts the Args of a Log::FmtLoc parameter into a non-deduced context, so that they are deduced from th...
Definition log.h:76
static term::FG level2color(Level level)
void d(Fmt< Args... > fmt, Args &&... args) const
Definition log.h:116
static char level2acro(Level level)
void t(Fmt< Args... > fmt, Args &&... args) const
Definition log.h:117
Log & set(Level max_level)
Definition log.h:54
void log(Level level, Loc loc, cite_string< Args... > fmt, Args &&... args) const
Definition log.h:82
bool break_on_error
Definition log.h:127
void log(Level level, std::source_location where, cite_string< Args... > fmt, Args &&... args) const
A std::source_location is no Loc: it points into your source, which has no fe::Src.
Definition log.h:88
Level level() const
Definition log.h:40
void w(Fmt< Args... > fmt, Args &&... args) const
Definition log.h:105
void v(Fmt< Args... > fmt, Args &&... args) const
Definition log.h:107
void log(Level level, Fmt< Args... > fmt, Args &&... args) const
Points at the call site.
Definition log.h:95
std::ostream & ostream() const
Definition log.h:41
Level
Definition log.h:23
void i(Fmt< Args... > fmt, Args &&... args) const
Definition log.h:106
FG
Foreground colors that can be streamed into an std::ostream.
Definition term.h:50
std::format_string< detail::cite_arg_t< Args >... > cite_string
A std::format_string whose backticks delimit a `citation` while those of its arguments are data.
Definition term.h:242
FE_API void render_cite(std::ostream &os, std::string_view str, bool color)
Streams str into os, coloring each `citation` and dropping its backticks - or keeping them verbatim...
Definition algo.h:17
void breakpoint()
Raise a breakpoint in the debugger.
Definition assert.h:30
Location within a Src: the half-open byte range [Loc::begin, Loc::end).
Definition loc.h:42
A cite_string that remembers where it was written.
Definition log.h:62
consteval FmtLoc(const S &fmt, std::source_location loc=std::source_location::current())
Definition log.h:65