Util: Add map formatting to new struct Formatter
This commit is contained in:
@@ -13,7 +13,6 @@
|
||||
#include <string_view>
|
||||
|
||||
#include "util/format/formatter.h"
|
||||
#include "util/format/toformat.h"
|
||||
|
||||
namespace Util::Format {
|
||||
|
||||
|
||||
@@ -90,6 +90,4 @@ void Formatter<std::nullptr_t>::format(Builder& builder, std::nullptr_t) const
|
||||
Formatter<const void*>::format(builder, 0);
|
||||
}
|
||||
|
||||
// Containers
|
||||
|
||||
} // namespace Util::Format
|
||||
|
||||
@@ -114,4 +114,32 @@ struct Formatter<std::vector<T>> : Formatter<T> {
|
||||
}
|
||||
};
|
||||
|
||||
#define UTIL_FORMAT_FORMAT_AS_MAP(type) \
|
||||
template<typename K, typename V> \
|
||||
struct Formatter<type<K, V>> \
|
||||
: Formatter<K> \
|
||||
, Formatter<V> { \
|
||||
void format(Builder& builder, const type<K, V>& value) const \
|
||||
{ \
|
||||
builder.putString("{\n"); \
|
||||
auto last = value.end(); \
|
||||
for (auto it = value.begin(); it != last; ++it) { \
|
||||
builder.putString(R"( ")"); \
|
||||
Formatter<K>::format(builder, it->first); \
|
||||
builder.putString(R"(": )"); \
|
||||
Formatter<V>::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
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Riyyi
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef> // nullptr_t, size_t
|
||||
#include <cstdint> // int32_t, uint32_t, int64_t
|
||||
#include <cstring> // strlen
|
||||
#include <iterator> // next
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <utility> // forward
|
||||
#include <vector>
|
||||
|
||||
#include "util/meta/odr.h"
|
||||
|
||||
namespace Util::Format {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
template<typename FormatBuilder>
|
||||
void format(FormatBuilder& builder, std::nullptr_t)
|
||||
{
|
||||
builder.putString("(nil)");
|
||||
}
|
||||
|
||||
template<typename FormatBuilder, typename T>
|
||||
void format(FormatBuilder& builder, T* pointer)
|
||||
{
|
||||
builder.putPointer(static_cast<const void*>(pointer));
|
||||
}
|
||||
|
||||
template<typename FormatBuilder>
|
||||
void format(FormatBuilder& builder, bool boolean)
|
||||
{
|
||||
builder.putString(boolean ? "true" : "false");
|
||||
}
|
||||
|
||||
template<typename FormatBuilder>
|
||||
void format(FormatBuilder& builder, int32_t number) // int
|
||||
{
|
||||
builder.putI32(number);
|
||||
}
|
||||
|
||||
template<typename FormatBuilder>
|
||||
void format(FormatBuilder& builder, uint32_t number) // unsigned int
|
||||
{
|
||||
builder.putU32(number);
|
||||
}
|
||||
|
||||
template<typename FormatBuilder>
|
||||
void format(FormatBuilder& builder, int64_t number) // long int
|
||||
{
|
||||
builder.putI64(number);
|
||||
}
|
||||
|
||||
template<typename FormatBuilder> // uint64_t
|
||||
void format(FormatBuilder& builder, size_t number) // long unsigned int
|
||||
{
|
||||
builder.putU64(number);
|
||||
}
|
||||
|
||||
template<typename FormatBuilder>
|
||||
void format(FormatBuilder& builder, float number)
|
||||
{
|
||||
builder.putF32(number);
|
||||
}
|
||||
|
||||
template<typename FormatBuilder>
|
||||
void format(FormatBuilder& builder, double number)
|
||||
{
|
||||
builder.putF64(number);
|
||||
}
|
||||
|
||||
template<typename FormatBuilder>
|
||||
void format(FormatBuilder& builder, char character)
|
||||
{
|
||||
builder.putCharacter(character);
|
||||
}
|
||||
|
||||
template<typename FormatBuilder>
|
||||
void format(FormatBuilder& builder, const char* string)
|
||||
{
|
||||
builder.putString({ string, strlen(string) });
|
||||
}
|
||||
|
||||
template<typename FormatBuilder>
|
||||
void format(FormatBuilder& builder, const std::string& string)
|
||||
{
|
||||
builder.putString(string);
|
||||
}
|
||||
|
||||
template<typename FormatBuilder>
|
||||
void format(FormatBuilder& builder, std::string_view string)
|
||||
{
|
||||
builder.putString(string);
|
||||
}
|
||||
|
||||
template<typename FormatBuilder, typename T>
|
||||
void format(FormatBuilder& builder, const std::vector<T>& array)
|
||||
{
|
||||
builder.putString("{\n");
|
||||
for (auto it = array.cbegin(); it != array.cend(); ++it) {
|
||||
builder.putString(" ");
|
||||
format(builder, *it);
|
||||
|
||||
// Add comma, except after the last element
|
||||
if (it != std::prev(array.end(), 1)) {
|
||||
builder.putCharacter(',');
|
||||
}
|
||||
builder.putCharacter('\n');
|
||||
}
|
||||
builder.putCharacter('}');
|
||||
}
|
||||
|
||||
#define FORMAT_MAP \
|
||||
builder.putString("{\n"); \
|
||||
auto last = map.end(); \
|
||||
for (auto it = map.begin(); it != last; ++it) { \
|
||||
builder.putString(R"( ")"); \
|
||||
format(builder, it->first); \
|
||||
builder.putString(R"(": )"); \
|
||||
format(builder, it->second); \
|
||||
\
|
||||
/* Add comma, except after the last element */ \
|
||||
if (std::next(it) != last) { \
|
||||
builder.putCharacter(','); \
|
||||
} \
|
||||
\
|
||||
builder.putCharacter('\n'); \
|
||||
} \
|
||||
builder.putCharacter('}');
|
||||
|
||||
template<typename FormatBuilder, typename K, typename V>
|
||||
void format(FormatBuilder& builder, const std::map<K, V>& map)
|
||||
{
|
||||
FORMAT_MAP;
|
||||
}
|
||||
|
||||
template<typename FormatBuilder, typename K, typename V>
|
||||
void format(FormatBuilder& builder, const std::unordered_map<K, V>& map)
|
||||
{
|
||||
FORMAT_MAP;
|
||||
}
|
||||
|
||||
struct formatFunction {
|
||||
template<typename FormatBuilder, typename T>
|
||||
auto operator()(FormatBuilder& builder, T&& value) const
|
||||
{
|
||||
return format(builder, std::forward<T>(value));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Detail
|
||||
|
||||
namespace {
|
||||
constexpr const auto& _format = Util::Detail::staticConst<Detail::formatFunction>; // NOLINT(misc-definitions-in-headers,clang-diagnostic-unused-variable)
|
||||
} // namespace
|
||||
|
||||
} // namespace Util::Format
|
||||
Reference in New Issue
Block a user