diff --git a/src/log.hpp b/src/log.hpp index 58bc7ce..0922d0b 100755 --- a/src/log.hpp +++ b/src/log.hpp @@ -1,13 +1,12 @@ #pragma once +#include #define LOG_MULTITHREAD +#include "util/string_conversion.hpp" + #include #include -#include -#include -#include -#include #ifdef LOG_MULTITHREAD #include @@ -22,70 +21,6 @@ namespace gz { constexpr unsigned int LOG_POSTPREFIX_CHAR_COUNT = 2; - inline const char* boolToString(bool b) { - return b ? "true" : "false"; - } - - // - // CONCEPTS - // - /// is (similar or convertible to) std::string - template - concept Stringy = std::same_as || std::convertible_to; - /// is appendable to std::string - /* concept Stringy = requires(T t, std::string s) { s += t; }; */ - - /// has .to_string() member - template - concept HasToString = !Stringy && requires(T t) { { t.to_string() }-> Stringy; }; - - /// an overload of Stringy to_string(const T&) exists in global or gz namespace - template - concept ExistsToString = !Stringy && !HasToString && requires(const T& t) { { to_string(t) } -> Stringy; }; - - /// works with std::to_string(), except bool - template - concept WorksWithStdToString = !std::same_as && !Stringy && !HasToString && !ExistsToString && requires(T t) { { std::to_string(t) } -> Stringy; }; - - /// string-like, has .to_string() member, to_string(const T&) exits, works with std::to_string() or bool - template - concept PrintableNoPtr = Stringy || HasToString || ExistsToString || WorksWithStdToString || std::same_as; - - /// Everything from PrintableNoPtr but "behind" a pointer - template - concept Printable = PrintableNoPtr || requires(T t) { { *(t.get()) } -> PrintableNoPtr; }; - - /// Type having printable .x and .y members - template - concept Vector2Printable = !Printable && - requires(T t) { - { t.x } -> Printable; - { t.y } -> Printable; - requires sizeof(t.x) * 2 == sizeof(T); - }; - - /// Pair having printable elements - template - concept PairPrintable = !Vector2Printable && !Printable && - requires(T p) { { p.first } -> Printable; } && (requires(T p){ { p.second } -> Printable; } || requires(T p){ { p.second } -> Vector2Printable; }); - - /// Container having printable elements - template - concept ContainerPrintable = !Printable && !Vector2Printable && !PairPrintable && - std::ranges::forward_range && (Printable> || Vector2Printable>); - - /// Container having printable pairs - template - concept MapPrintable = !Printable && !Vector2Printable && !ContainerPrintable && - std::ranges::forward_range && PairPrintable>; - - template - concept LogableNotPointer = Printable || Vector2Printable || PairPrintable || ContainerPrintable || MapPrintable; - - template - concept LogableSmartPointer = requires(T t) { { *(t.get()) } -> LogableNotPointer; }; - - // // COLORS // @@ -103,23 +38,26 @@ namespace gz { * @brief Define types that can be logged with Log * @details * As of now you can log type T with instance t: - * -# Any @ref Stringy "string-like type": eg. std::string, std::string_view - * -# Any @ref WorksWithStdToString "type that works with std::to_string()" - * -# Any @ref ExistsToString "type for which an overload of" Stringy to_string(const T&) exists in global or gz namespace - * -# Any @ref HasToString "type that has a to_string() const member that returns a string" - * -# Any @ref Vector2Printable "type with t.x and t.y", provided t.x and t.y satisfy one of 1-3 - * -# Any @ref PairPrintable "type with t.first, t.second" provided t.first satisfies one of 1-3 and t.second satisfies 1-4 - * -# Any @ref ContainerPrintable "type that has a forward_iterator" which references any one of 1-5 + * -# Any @ref util::Stringy "string-like type": eg. std::string, std::string_view + * -# Any @ref util::WorksWithStdToString "type that works with std::to_string()" + * -# Any @ref util::HasToStringMember "type that has a to_string() const member that returns a string" + * -# Any @ref util::ContainerConvertibleToString "type that has a forward_iterator" which references any one of 1-3 + * -# Any @ref util::PairConvertibleToString "type with t.first, t.second" provided t.first satisfies one of 1-4 and t.second satisfies 1-4 + * -# Any @ref util::MapConvertibleToString "type that has a forward_iterator" which references 5 + * -# Any @ref util::Vector2ConvertibleToString "type with t.x and t.y", provided t.x and t.y satisfy one of 1-6 + * -# Any @ref util::Vector3ConvertibleToString "type with t.x, t.y, t.z", provided t.x, t.y, t.z satisfy one of 1-6 + * -# Any @ref util::Vector4ConvertibleToString "type with t.x, t.y, t.z and t.w", provided t.x, t.y, t.z, t.w satisfy one of 1-6 + * -# Any @ref ConvertibleToString "type for which an overload of" util::Stringy to_string(const T&) exists in global or gz namespace * * The higher number takes precedence in overload resolution for the log function. * - * 1-7 include for example: + * 1-6 include for example: * - int, float, bool... * - std::vector, std::list - * - std::map> if A.to_string() returns a string - ... + * - std::map> if A.to_string() returns a string - ... */ template - concept Logable = LogableNotPointer || LogableSmartPointer; + concept Logable = ConvertibleToString; /** * @brief Manages printing messages to stdout and to logfiles. @@ -270,105 +208,23 @@ class Log { private: // vlog for variadic log /// Log anything that can be appendend to std::string - template + template void vlog(const char* appendChars, T&& t, Args&&... args) { logLines[iter] += t; logLines[iter] += appendChars; vlog(" ", std::forward< Args>(args)...); } - - /// Log anything that has a to_string() member - template - void vlog(const char* appendChars, T&& t, Args&&... args) { - logLines[iter] += t.to_string(); - logLines[iter] += appendChars; - vlog(" ", std::forward< Args>(args)...); - } - - /// Log anything where to_string(const T&) -> Stringy - template - void vlog(const char* appendChars, T&& t, Args&&... args) { + /// Log anything where to_string exists + template + void vlog(const char* appendChars, T&& t, Args&&... args) requires (!util::Stringy) { logLines[iter] += to_string(t); logLines[iter] += appendChars; vlog(" ", std::forward< Args>(args)...); } - /// Log anything that works with std::to_string() - template - void vlog(const char* appendChars, T&& t, Args&&... args) { - logLines[iter] += std::to_string(t); - logLines[iter] += appendChars; - vlog(" ", std::forward< Args>(args)...); - } - - /// Log bool - template - requires(std::same_as) - void vlog(const char* appendChars, T&& b, Args&&... args) { - logLines[iter] += boolToString(b); - logLines[iter] += appendChars; - vlog(" ", std::forward< Args>(args)...); - } - - /// Log vec2 - template - void vlog(const char* appendChars, V&& v, Args&&... args) { - logLines[iter] += "("; - vlog("", v.x); - logLines[iter] += ", "; - vlog("", v.y); - logLines[iter] += ")"; - logLines[iter] += appendChars; - vlog(" ", std::forward< Args>(args)...); - } - - /// Log a pair - template - void vlog(const char* appendChars, P&& p, Args&&... args) { - logLines[iter] += "("; - vlog("", p.first); - logLines[iter] += ", "; - vlog("" ,p.second); - logLines[iter] += ")"; - logLines[iter] += appendChars; - vlog(" ", std::forward< Args>(args)...); - } - - /// Log a container using iterators - template - void vlog(const char* appendChars, T&& t, Args&&... args) {; - logLines[iter] += "["; - for (auto it = t.begin(); it != t.end(); it++) { - vlog(", ", *it); - } - logLines[iter].erase(logLines[iter].size() - 2); - logLines[iter] += "]"; - logLines[iter] += appendChars; - vlog(" ", std::forward< Args>(args)...); - } - - /// Log a container containing a pair - template - void vlog(const char* appendChars, T&& t, Args&&... args) { - logLines[iter] += "{"; - for (const auto& [k, v] : t) { - vlog(": ", k); - vlog(", ", v); - } - logLines[iter] += "}"; - logLines[iter] += appendChars; - vlog(" ", std::forward(args)...); - } - - /// Log any logable element that is stored in a pointer - template - void vlog(const char* appendChars, T&& t, Args&&... args) { - vlog("", *t); - vlog(" ", std::forward(args)...); - } - void vlog(const char* appendChars) {}; + private: /// Where the lines are stored std::vector logLines;