1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_LOGGER_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_LOGGER_H
17#include <molpro/iostream.h>
53 { T::name } -> std::convertible_to<const char *>;
60template<
typename CRTP,
bool fixed_args,
typename ...Args >
65 static constexpr const char *
name = []() {
69 return typeid(CRTP).
name();
83 static constexpr std::size_t
num_args =
sizeof...(Args);
91 static constexpr decltype(
auto)
to_arg(T &&arg) {
92 if constexpr (std::ranges::view<T>) {
93 return std::forward<T>(arg);
94 }
else if constexpr (std::ranges::range<std::remove_cvref_t<T>>) {
95 return std::ranges::views::all(arg);
97 return std::as_const(arg);
105 template<std::
size_t Idx>
107 using arg_t =
decltype(
to_arg(std::declval<std::tuple_element_t<Idx, arg_types_tuple>>()));
112 template<std::size_t Idx,
typename ...Ts>
114 return to_arg(std::get<Idx>(std::forward_as_tuple(std::forward<Ts>(args)...)));
122template<
typename T >
125 []<
bool b,
typename...Ts>(
const ContextBase<T, b, Ts...> &){}(t);
131template<
typename Ctx,
typename ...Args >
138concept pair_like =
requires(
const std::remove_cvref_t<T> &t) {
147concept streamable =
requires (std::ostream &stream,
const std::remove_cvref_t<T> &t) {
155concept formattable =
requires (
const std::remove_cvref_t<T> &t, std::format_context ctx) {
156 std::formatter<std::remove_cvref_t<T>>().format(t, ctx);
171template<std::
size_t MaxSize>
178 template<std::
size_t N>
179 requires(N - 1 <= MaxSize)
182 for (std::size_t i = 0; i < N - 1; ++i) {
183 push_back(literal[i]);
189 if (m_size == MaxSize) {
190 throw std::out_of_range(
"Maximum capacity has been reached - can't append further chars");
193 m_data.at(m_size) = c;
197 constexpr std::size_t
size()
const {
return m_size; }
201 throw std::out_of_range(
"Requested index is out of range");
204 return m_data.at(idx);
208 return {m_data.data(), m_size};
211 constexpr operator std::string_view()
const {
216 std::array<char, MaxSize> m_data;
217 std::size_t m_size = 0;
244template<std::
size_t precision>
252 if (precision == 0) {
255 std::size_t begin = str.
size();
258 std::size_t prec_val = precision;
259 while (prec_val > 0) {
260 std::size_t tmp = prec_val / 10;
261 std::size_t digit = prec_val - tmp * 10;
264 str.
push_back(
'0' +
static_cast<char>(digit));
270 for (std::size_t i = 0; i <
num_digits / 2; ++i) {
271 std::swap(str[i + begin], str[str.
size() - i - 1]);
294template<context Context,
typename T, std::
size_t precision = default_precision>
301 return create_fmt_string_for_precision<precision>();
323 stream << std::setprecision(precision);
331template <context Context, std::
size_t precision = default_precision,
typename T>
332 requires(formattable<T> || streamable<T> || string_convertible_range<T> || pair_like<T>)
333static std::string stringify(T &&t) {
334 using FOpts = FormatOption<Context, std::remove_cvref_t<T>, precision>;
336 if constexpr (formattable<T>) {
337 static constexpr auto fmt = FOpts::format_string();
338 return std::format(fmt.as_view(), t);
339 }
else if constexpr (streamable<T>) {
340 std::stringstream sstream;
341 FOpts::prepare_stream(sstream);
343 return sstream.str();
344 }
else if constexpr (pair_like<T>) {
345 std::stringstream sstream;
347 sstream <<
"{ " << stringify<Context, precision>(t.first) <<
": " << stringify<Context, precision>(t.second)
350 return sstream.str();
352 std::stringstream sstream;
354 using std::ranges::begin;
355 using std::ranges::end;
357 sstream << FOpts::range_begin_mark();
359 for (
auto it = begin(t); it != end(t); ++it) {
360 sstream << stringify<Context, precision>(*it);
362 if (it + 1 != end(t)) {
363 sstream << FOpts::range_separator();
367 sstream << FOpts::range_end_mark();
369 return sstream.str();
378template<
typename Context, std::
size_t precision,
typename T>
380 { stringify<Context, precision>(t) } -> std::same_as<std::string>;
406template< context Context >
408 template<
typename ...Ts>
411 template<
typename ...Ts>
415template<
typename Context,
typename ...Args >
418 std::declval<std::string_view>(), args...);
420template<
typename Context,
typename ...Args >
422 handler.handle(std::declval<Severity>(), std::declval<Verbosity>(),
423 std::declval<std::string_view>(), args...);
429template<
typename Context,
typename ...Args >
452 log_ctx(Context::name,
sizeof...(args));
454 if (
verbosity < m_verbosity || severity < m_min_severity) {
459 if constexpr (Context::uses_fixed_arguments) {
467 const Handler *handler =
dynamic_cast<const Handler *
>(
this);
469 handler->
handle(severity,
verbosity, message, std::forward<Ts>(args)...);
471 Handler::handle(*
this, severity,
verbosity, message, std::forward<Ts>(args)...);
474 dynamic_cast<const Handler &
>(*this).handle(severity,
verbosity, message, std::forward<Ts>(args)...);
477 Handler::handle(*
this, severity,
verbosity, message, std::forward<Ts>(args)...);
479 }
else if constexpr (
sizeof...(args) > 0) {
480 std::string arg_str = ((log::stringify<Context, precision>(std::forward<Ts>(args)) +
", ") + ...);
482 if (!message.empty() && message.back() !=
' ') {
485 arg_str =
" -> " + arg_str;
495 void trace(std::string_view message, Ts && ...args)
const {
500 void debug(std::string_view message, Ts && ...args)
const {
505 void info(std::string_view message, Ts && ...args)
const {
510 void warn(std::string_view message, Ts && ...args)
const {
515 void error(std::string_view message, Ts && ...args)
const {
520 void fatal(std::string_view message, Ts && ...args)
const {
526 void data_dump(std::string_view what, Ts...data)
const {
551 bool add_colon =
false;
556 molpro::cout <<
"[WARNING]";
560 molpro::cout <<
"[ERROR]:";
564 molpro::cout <<
"[FATAL]:";
572 molpro::cout <<
"[INFO]";
576 molpro::cout <<
"[DEBUG]";
580 molpro::cout <<
"[TRACE]";
586 molpro::cout <<
"[" << ctx <<
"]";
590 molpro::cout << (add_colon ?
": " :
"") <<
msg;
592 molpro::cout << std::endl;
594 molpro::cout <<
"\n";
598 virtual void log_ctx(std::string_view ctx, std::size_t num_args)
const {
608 bool m_dump_data =
false;
void set_min_severity(log::Severity severity)
Definition: Logger.h:537
void info(std::string_view message, Ts &&...args) const
Definition: Logger.h:505
Logger(log::Severity min_severity=log::Severity::Normal, log::Verbosity verbosity=log::Verbosity::Info, bool enable_data_dumps=false)
Definition: Logger.h:444
void warn(std::string_view message, Ts &&...args) const
Definition: Logger.h:510
void debug(std::string_view message, Ts &&...args) const
Definition: Logger.h:500
log::Verbosity verbosity() const
Definition: Logger.h:539
void msg(log::Severity severity, log::Verbosity verbosity, std::string_view message, Ts &&...args) const
Definition: Logger.h:451
void error(std::string_view message, Ts &&...args) const
Definition: Logger.h:515
void data_dump(std::string_view what, Ts...data) const
Definition: Logger.h:526
virtual void default_message_handler(std::string_view ctx, log::Severity severity, log::Verbosity verbosity, std::string_view msg) const
Definition: Logger.h:550
void fatal(std::string_view message, Ts &&...args) const
Definition: Logger.h:520
bool data_dumps_enabled() const
Definition: Logger.h:543
log::Severity min_severity() const
Definition: Logger.h:535
void trace(std::string_view message, Ts &&...args) const
Definition: Logger.h:495
void enable_data_dumps(bool enable)
Definition: Logger.h:545
virtual void log_ctx(std::string_view ctx, std::size_t num_args) const
Definition: Logger.h:598
void set_verbosity(log::Verbosity verbosity)
Definition: Logger.h:541
constexpr ~ConstexprString()
Definition: Logger.h:186
constexpr ConstexprString()
Definition: Logger.h:175
constexpr ConstexprString(const char(&literal)[N])
Definition: Logger.h:180
constexpr void push_back(char c)
Definition: Logger.h:188
constexpr char & operator[](std::size_t idx)
Definition: Logger.h:199
constexpr std::size_t size() const
Definition: Logger.h:197
constexpr std::string_view as_view() const
Definition: Logger.h:207
Definition: IterativeSolverTemplate.h:127
constexpr const std::size_t default_precision
Definition: Logger.h:284
constexpr std::size_t num_digits(std::size_t val)
Definition: Logger.h:224
Verbosity
Different levels of logging.
Definition: Logger.h:29
constexpr ConstexprString< num_digits(precision)+4 > create_fmt_string_for_precision()
Definition: Logger.h:245
Severity
Severity of a given message.
Definition: Logger.h:40
4-parameter interpolation of a 1-dimensional function given two points for which function values and ...
Definition: helper.h:14
static constexpr const char * name
Definition: Logger.h:65
static arg_t< Idx > get_arg(Ts &&...args)
Definition: Logger.h:113
std::tuple< std::remove_cvref_t< Args >... > arg_types_tuple
Definition: Logger.h:78
decltype(to_arg(std::declval< std::tuple_element_t< Idx, arg_types_tuple > >())) arg_t
Definition: Logger.h:107
static constexpr bool uses_fixed_arguments
Definition: Logger.h:75
static constexpr decltype(auto) to_arg(T &&arg)
Definition: Logger.h:91
static constexpr std::size_t num_args
Definition: Logger.h:83
static constexpr const char * name
Definition: Logger.h:395
static constexpr const char * name
Definition: Logger.h:390
void handle(Severity severity, Verbosity verbosity, std::string_view message, Ts...args)=delete
static void handle(const Logger &logger, Severity severity, Verbosity verbosity, std::string_view message, Ts...args)=delete