Riyyi
2 years ago
4 changed files with 28 additions and 168 deletions
@ -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
|
Loading…
Reference in new issue