/* * Copyright (C) 2022 Riyyi * * SPDX-License-Identifier: MIT */ #pragma once #include // size_t #include // int32_t, uint8_t, uint32_t, int64_t, #include #include #include #include "util/format/builder.h" #include "util/format/parser.h" namespace Util::Format { template struct Formatter { void format(Builder& builder, T value) const { (void)builder, (void)value; } }; // Integral template<> void Formatter::format(Builder& builder, int32_t value) const; template<> void Formatter::format(Builder& builder, uint32_t value) const; template<> void Formatter::format(Builder& builder, int64_t value) const; template<> void Formatter::format(Builder& builder, size_t value) const; // uint64_t // Floating point template<> void Formatter::format(Builder& builder, float value) const; template<> void Formatter::format(Builder& builder, double value) const; // Char template<> void Formatter::format(Builder& builder, char value) const; template<> void Formatter::format(Builder& builder, bool value) const; // String template<> void Formatter::format(Builder& builder, std::string_view value) const; template<> struct Formatter : Formatter { }; template<> struct Formatter : Formatter { void format(Builder& builder, const char* value) const; }; template<> struct Formatter : Formatter { }; template struct Formatter : Formatter { }; // Pointer template struct Formatter { void format(Builder& builder, T* value) const { value == nullptr ? builder.putString("0x0") : builder.putPointer(static_cast(value)); } }; template<> struct Formatter : Formatter { void format(Builder& builder, std::nullptr_t) const; }; // Container template struct Formatter> : Formatter { void format(Builder& builder, const std::vector& value) const { builder.putString("{\n"); for (auto it = value.cbegin(); it != value.cend(); ++it) { builder.putString(" "); Formatter::format(builder, *it); // Add comma, except after the last element if (it != std::prev(value.end(), 1)) { builder.putCharacter(','); } builder.putCharacter('\n'); } builder.putCharacter('}'); } }; #define UTIL_FORMAT_FORMAT_AS_MAP(type) \ template \ struct Formatter> \ : Formatter \ , Formatter { \ void format(Builder& builder, const type& value) const \ { \ builder.putString("{\n"); \ auto last = value.end(); \ for (auto it = value.begin(); it != last; ++it) { \ builder.putString(R"( ")"); \ Formatter::format(builder, it->first); \ builder.putString(R"(": )"); \ Formatter::format(builder, it->second); \ \ /* Add comma, except after the last element */ \ if (std::next(it) != last) { \ builder.putCharacter(','); \ } \ \ builder.putCharacter('\n'); \ } \ builder.putCharacter('}'); \ } \ } UTIL_FORMAT_FORMAT_AS_MAP(std::map); UTIL_FORMAT_FORMAT_AS_MAP(std::unordered_map); } // namespace Util::Format