// License: Modified MIT (NON-AI) // See the LICENSE file in the root directory for license information. // Copyright 2025 Timothy Prepscius #pragma once #include "../type_traits/is_iterable.hpp" #include #include #include "demangle.h" #include "../types/Types+IO.h" namespace tjp::core { template struct LogOf { const T &t; explicit LogOf(const T &t_) : t(t_) {} std::ostream &operator()(std::ostream &o) const { return o << t; } } ; template struct LogOfV { T t; explicit LogOfV(T t_) : t(t_) {} std::ostream &operator()(std::ostream &o) const { return o << t; } } ; template auto logOfV(T t) { return LogOfV(t); } template std::ostream &operator <<(std::ostream &o, const LogOf &v) { return v(o); } template std::ostream &operator <<(std::ostream &o, const LogOfV &v) { return v(o); } template::value, T>::type* = nullptr> auto logOf(const T &t); template::value, T>::type* = nullptr> auto logOf(const T &t); inline auto logOf(const std::string &t) { return t; } inline auto logOf(bool v) { return v ? "true" : "false"; } template auto logOf(const std::pair &t) { std::ostringstream o; o << "(" << logOf(t.first) << "," << logOf(t.second) << ")"; return o.str(); } template::value, T>::type*> auto logOf(const T &t) { return LogOf(t); } template::value, T>::type*> auto logOf(const T &t) { std::ostringstream o; o << "["; auto first = true; for (auto v : t) { if (!first) { o << ","; } o << logOf(v); first = false; } o << "]"; return o.str(); } inline auto logOf(const std::string_view &v) { return v; } template struct NullOrValue { const T *t; explicit NullOrValue(const T *t_) : t(t_) {} } ; template std::ostream &operator <<(std::ostream &o, const NullOrValue &v) { if (v.t) return o << logOf(*v.t); return o << "null"; } template auto logOfRef(T *t) { return NullOrValue(t); } template struct NullOrPtrValue { const T *t; explicit NullOrPtrValue(const T *t_) : t(t_) {} } ; template std::ostream &operator <<(std::ostream &o, const NullOrPtrValue &v) { if (v.t) return o << "[" << v.t << "] " << logOf(*v.t); return o << "null"; } template auto logPtrValue(T *t) { return NullOrPtrValue(t); } template auto logPtr(T *t) { return t; } template struct SpaceBefore { const T &t; } ; template std::ostream &operator <<(std::ostream &o, const SpaceBefore &v) { return o << " " << logOf(v.t); } template SpaceBefore _logOf(const T &t) { return SpaceBefore { t }; } template auto logOfDispatch(T &&t) { return logOf(std::forward(t)); } template auto logOfDispatchV(T t) { return logOfV(t); } #define logOfThis(x) "[" << tjp::core::logPtr(x) << "] " #define logVar(x) #x << " " << tjp::core::logOfDispatch(x) << " " #define logVarV(x) #x << " " << tjp::core::logOfDispatchV(x) << " " #define logType(x) #x << " " << tjp::core::type_id().name() << " " #define logLabel(l) l << " " #define logLabelVar(l, x) l << " " << tjp::core::logOfDispatch(x) << " " #define logLabelVarV(l, x) l << " " << tjp::core::logOfDispatchV(x) << " " } // namespace