Util: Add map formatting to new struct Formatter
This commit is contained in:
@@ -13,7 +13,6 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
#include "util/format/formatter.h"
|
#include "util/format/formatter.h"
|
||||||
#include "util/format/toformat.h"
|
|
||||||
|
|
||||||
namespace Util::Format {
|
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);
|
Formatter<const void*>::format(builder, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Containers
|
|
||||||
|
|
||||||
} // namespace Util::Format
|
} // 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
|
} // 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