Simplify util/macros.hpp and rewrite util/toml from scratch
This commit is contained in:
parent
edcba981dd
commit
5a6bc79308
@ -1,53 +0,0 @@
|
||||
/* tomlize.hpp
|
||||
* Copyright © 2024 Saul D. Beniquez
|
||||
* License: Mozilla Public License v2.0 (MPL2)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public License,
|
||||
* v.2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
* obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <toml++/toml.hpp>
|
||||
|
||||
namespace TOML {
|
||||
|
||||
using ErrorFlag = bool;
|
||||
static constexpr ErrorFlag error_t = true;
|
||||
static constexpr ErrorFlag success_t = false;
|
||||
|
||||
template<typename T>
|
||||
auto to_toml(const T&) -> toml::table;
|
||||
|
||||
template<typename T>
|
||||
auto from_toml(const toml::table&, T&) -> ErrorFlag;
|
||||
|
||||
template<typename TField>
|
||||
void add_toml_field(const TField&, toml::table&);
|
||||
|
||||
template<typename TField>
|
||||
auto extract_toml_field(const toml::table&, TField&) -> ErrorFlag;
|
||||
|
||||
#define TOMILIZE_FIELD(FIELD) add_toml_field(FIELD, table);
|
||||
#define DETOMLIZE_FIELD(FIELD) result |= extract_toml_field(table, FIELD);
|
||||
|
||||
#define TOMLIZE_STRUCT(STRUCT, ...) \
|
||||
template<> \
|
||||
auto to_toml(const STRUCT& s)->toml::table \
|
||||
{ \
|
||||
toml::table table; \
|
||||
FOREACH_PARAM(TOMLIZE_FIELD, __VA_ARGS__); \
|
||||
return table; \
|
||||
} \
|
||||
template<> \
|
||||
auto from_toml(const toml::table& table, STRUCT& s)->ErrorFlag \
|
||||
{ \
|
||||
auto result = success_t; \
|
||||
FOREACH_PARAM(DETOMLIZE_FIELD, __VA_ARGS__); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
} // namespace TOML
|
||||
// clang-format off
|
||||
// vim: set foldmethod=syntax foldminlines=10 textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :
|
@ -10,58 +10,34 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#define TOML_EXPAND(x) x
|
||||
#define TOML_ENUM_FIELD(field) { field, #field }
|
||||
#define MACRO_EXPAND(x) x
|
||||
#define NAMED_PAIR(field) { #field, field }
|
||||
|
||||
#define FOREACH_PARAM_1(func, param) func(param)
|
||||
#define FOREACH_PARAM_2(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_1(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_3(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_2(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_4(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_3(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_5(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_4(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_6(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_5(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_7(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_6(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_8(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_7(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_9(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_8(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_10(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_9(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_11(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_10(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_12(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_11(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_13(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_12(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_14(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_13(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_15(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_14(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_16(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_15(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_17(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_16(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_18(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_17(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_19(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_18(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_20(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_19(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_21(func, param, ...) func(param); TOML_EXPAND(FOREACH_PARAM_20(func, __VA_ARGS__))
|
||||
|
||||
|
||||
#define FOREACH_ENUM_PARAM_1(func, param) func(param)
|
||||
#define FOREACH_ENUM_PARAM_2(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_1(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_3(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_2(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_4(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_3(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_5(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_4(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_6(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_5(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_7(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_6(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_8(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_7(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_9(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_8(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_10(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_9(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_11(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_10(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_12(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_11(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_13(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_12(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_14(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_13(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_15(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_14(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_16(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_15(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_17(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_16(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_18(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_17(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_19(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_18(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_20(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_19(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM_21(func, param, ...) func(param), TOML_EXPAND(FOREACH_ENUM_PARAM_20(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_2(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_1(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_3(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_2(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_4(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_3(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_5(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_4(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_6(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_5(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_7(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_6(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_8(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_7(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_9(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_8(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_10(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_9(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_11(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_10(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_12(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_11(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_13(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_12(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_14(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_13(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_15(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_14(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_16(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_15(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_17(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_16(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_18(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_17(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_19(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_18(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_20(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_19(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM_21(func, param, ...) func(param) MACRO_EXPAND(FOREACH_PARAM_20(func, __VA_ARGS__))
|
||||
|
||||
|
||||
#define GET_FOREACH_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,NAME,...) NAME
|
||||
#define FOREACH_PARAM(func, ...) TOML_EXPAND(GET_FOREACH_MACRO(__VA_ARGS__, FOREACH_PARAM_21, FOREACH_PARAM_20, FOREACH_PARAM_19, FOREACH_PARAM_18, FOREACH_PARAM_17, FOREACH_PARAM_16, FOREACH_PARAM_15, FOREACH_PARAM_14, FOREACH_PARAM_13, FOREACH_PARAM_12, FOREACH_PARAM_11, FOREACH_PARAM_10, FOREACH_PARAM_9, FOREACH_PARAM_8, FOREACH_PARAM_7, FOREACH_PARAM_6, FOREACH_PARAM_5, FOREACH_PARAM_4, FOREACH_PARAM_3, FOREACH_PARAM_2, FOREACH_PARAM_1)(func, __VA_ARGS__))
|
||||
#define FOREACH_ENUM_PARAM(func, ...) TOML_EXPAND(GET_FOREACH_MACRO(__VA_ARGS__, FOREACH_ENUM_PARAM_21, FOREACH_ENUM_PARAM_20, FOREACH_ENUM_PARAM_19, FOREACH_ENUM_PARAM_18, FOREACH_ENUM_PARAM_17, FOREACH_ENUM_PARAM_16, FOREACH_ENUM_PARAM_15, FOREACH_ENUM_PARAM_14, FOREACH_ENUM_PARAM_13, FOREACH_ENUM_PARAM_12, FOREACH_ENUM_PARAM_11, FOREACH_ENUM_PARAM_10, FOREACH_ENUM_PARAM_9, FOREACH_ENUM_PARAM_8, FOREACH_ENUM_PARAM_7, FOREACH_ENUM_PARAM_6, FOREACH_ENUM_PARAM_5, FOREACH_ENUM_PARAM_4, FOREACH_ENUM_PARAM_3, FOREACH_ENUM_PARAM_2, FOREACH_ENUM_PARAM_1)(func, __VA_ARGS__))
|
||||
#define FOREACH_PARAM(func, ...) MACRO_EXPAND(GET_FOREACH_MACRO(__VA_ARGS__, FOREACH_PARAM_21, FOREACH_PARAM_20, FOREACH_PARAM_19, FOREACH_PARAM_18, FOREACH_PARAM_17, FOREACH_PARAM_16, FOREACH_PARAM_15, FOREACH_PARAM_14, FOREACH_PARAM_13, FOREACH_PARAM_12, FOREACH_PARAM_11, FOREACH_PARAM_10, FOREACH_PARAM_9, FOREACH_PARAM_8, FOREACH_PARAM_7, FOREACH_PARAM_6, FOREACH_PARAM_5, FOREACH_PARAM_4, FOREACH_PARAM_3, FOREACH_PARAM_2, FOREACH_PARAM_1)(func, __VA_ARGS__))
|
||||
|
||||
// clang-format off
|
||||
// vim: set foldmethod=syntax foldminlines=10 textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :
|
||||
|
157
include/util/toml.hpp
Normal file
157
include/util/toml.hpp
Normal file
@ -0,0 +1,157 @@
|
||||
/* util/toml.hpp
|
||||
* Copyright © 2024 Saul D. Beniquez
|
||||
* License: Mozilla Public License v2.0 (MPL2)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public License,
|
||||
* v.2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
* obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <toml++/toml.hpp>
|
||||
|
||||
#include "../Exception.hpp"
|
||||
#include "./macros.hpp"
|
||||
|
||||
|
||||
inline namespace TOML {
|
||||
|
||||
struct TomlException : public IOCore::Exception {
|
||||
|
||||
TomlException()
|
||||
: IOCore::Exception("TOML Serialization/Deseralization Exception")
|
||||
{
|
||||
}
|
||||
explicit TomlException(const std::string& message)
|
||||
: IOCore::Exception(message)
|
||||
{
|
||||
}
|
||||
~TomlException() override = default;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr bool is_toml_type_t = toml::impl::can_partially_represent_native<T>;
|
||||
|
||||
template<typename T>
|
||||
void to_toml(toml::table&, const T&);
|
||||
|
||||
template<typename T>
|
||||
void from_toml(const toml::table&, T&);
|
||||
|
||||
template<typename TField>
|
||||
inline void
|
||||
add_toml_field(const TField& obj, const char* fieldName, toml::table& tbl)
|
||||
{
|
||||
using value_type = std::decay_t<TField>;
|
||||
|
||||
if constexpr (std::is_enum_v<value_type>) {
|
||||
add_toml_enum_field(obj, fieldName, tbl);
|
||||
} else if constexpr (std::is_same_v<char, value_type>) {
|
||||
tbl.insert_or_assign(fieldName, std::string(1, obj));
|
||||
return;
|
||||
} else {
|
||||
if constexpr (is_toml_type_t<value_type>) {
|
||||
tbl.insert_or_assign(fieldName, obj);
|
||||
} else {
|
||||
toml::table subtable;
|
||||
to_toml(subtable, obj);
|
||||
tbl.insert_or_assign(fieldName, subtable);
|
||||
}
|
||||
}
|
||||
}
|
||||
template<typename TField>
|
||||
inline void
|
||||
extract_toml_field(const toml::table& tbl, const char* fieldName, TField& output)
|
||||
{
|
||||
using value_type = std::decay_t<TField>;
|
||||
|
||||
if (!tbl.contains(fieldName)) {
|
||||
throw TomlException("Missing field " + std::string(fieldName));
|
||||
}
|
||||
|
||||
if constexpr (std::is_enum_v<value_type>) {
|
||||
extract_toml_enum_field(tbl, fieldName, output);
|
||||
} else if constexpr (std::is_same_v<char, value_type>) {
|
||||
output = tbl[fieldName].value<std::string>()->at(0);
|
||||
} else if constexpr (is_toml_type_t<value_type>) {
|
||||
output = tbl[fieldName].value<value_type>().value();
|
||||
} else {
|
||||
auto subtable = *(tbl[fieldName].as_table());
|
||||
from_toml(subtable, output);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TOML
|
||||
|
||||
#define INSERT_FIELD(FIELD) add_toml_field(obj.FIELD, #FIELD, table);
|
||||
#define EXTRACT_FIELD(FIELD) extract_toml_field(table, #FIELD, obj.FIELD);
|
||||
|
||||
#define ENUM_FIELD_ENTRY(field) NAMED_PAIR(field),
|
||||
|
||||
#define TOML_STRUCT(STRUCT_TYPE, ...) \
|
||||
inline void to_toml(toml::table& table, const STRUCT_TYPE& obj) \
|
||||
{ \
|
||||
FOREACH_PARAM(INSERT_FIELD, __VA_ARGS__); \
|
||||
} \
|
||||
\
|
||||
inline void from_toml(const toml::table& table, STRUCT_TYPE& obj) \
|
||||
{ \
|
||||
FOREACH_PARAM(EXTRACT_FIELD, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define TOML_CLASS(CLASS_TYPE, ...) \
|
||||
inline friend void to_toml(toml::table& table, const CLASS_TYPE& obj) \
|
||||
{ \
|
||||
FOREACH_PARAM(INSERT_FIELD, __VA_ARGS__); \
|
||||
} \
|
||||
\
|
||||
inline friend void from_toml(const toml::table& table, CLASS_TYPE& obj) \
|
||||
{ \
|
||||
FOREACH_PARAM(EXTRACT_FIELD, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define TOML_ENUM(ENUM_TYPE, ...) \
|
||||
inline void add_toml_enum_field( \
|
||||
const ENUM_TYPE& obj, const char* fieldName, toml::table& tbl \
|
||||
) \
|
||||
{ \
|
||||
static_assert( \
|
||||
std::is_enum<ENUM_TYPE>::value, \
|
||||
#ENUM_TYPE "must be an enum!" \
|
||||
); \
|
||||
using pair_t = std::pair<const char*, ENUM_TYPE>; \
|
||||
static const pair_t _enum_to_string[] = { \
|
||||
FOREACH_PARAM(ENUM_FIELD_ENTRY, __VA_ARGS__) \
|
||||
}; \
|
||||
auto it = std::find_if( \
|
||||
std::begin(_enum_to_string), \
|
||||
std::end(_enum_to_string), \
|
||||
[obj](const auto& pair) -> bool { \
|
||||
return pair.second == obj; \
|
||||
} \
|
||||
); \
|
||||
tbl.insert_or_assign(fieldName, it->first); \
|
||||
} \
|
||||
inline void extract_toml_enum_field( \
|
||||
const toml::table& tbl, const char* fieldName, ENUM_TYPE& obj \
|
||||
) \
|
||||
{ \
|
||||
static_assert( \
|
||||
std::is_enum<ENUM_TYPE>::value, \
|
||||
#ENUM_TYPE " must be an enum!" \
|
||||
); \
|
||||
using pair_t = std::pair<const char*, ENUM_TYPE>; \
|
||||
static const pair_t _enum_to_string[] = { \
|
||||
FOREACH_PARAM(ENUM_FIELD_ENTRY, __VA_ARGS__) \
|
||||
}; \
|
||||
auto val = tbl[fieldName].value<std::string>().value(); \
|
||||
for (const auto& [str, enum_val] : _enum_to_string) { \
|
||||
if (str == val) { \
|
||||
obj = enum_val; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
// clang-format off
|
||||
// vim: set foldmethod=syntax foldminlines=10 textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :
|
Loading…
Reference in New Issue
Block a user