MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
toml_builder.hpp
1#ifndef MSTL_CORE_FILE_TOML_BUILDER_HPP__
2#define MSTL_CORE_FILE_TOML_BUILDER_HPP__
3#include "MSTL/core/container/stack.hpp"
5#include "toml_value.hpp"
7
8class MSTL_API toml_builder {
9private:
10 enum RANGE_TYPE { TABLE, INLINE_TABLE, ARRAY };
11
12 struct frame {
13 RANGE_TYPE type = TABLE;
14 union {
15 toml_table* table_ptr = nullptr;
16 toml_array* array_ptr;
17 };
18
19 frame() = default;
20 frame(const RANGE_TYPE t, toml_table* tbl) : type(t), table_ptr(tbl) {}
21 frame(const RANGE_TYPE t, toml_array* arr) : type(t), array_ptr(arr) {}
22
23 frame(const frame&) = default;
24 frame& operator =(const frame&) = default;
25 frame(frame&&) = default;
26 frame& operator =(frame&&) = default;
27 ~frame() = default;
28 };
29
30 _MSTL stack<frame> contexts_;
31 unique_ptr<toml_table> root_;
32 string current_key_;
33
34private:
35 template <typename T>
36 toml_builder& value_impl(unique_ptr<T> v) {
37 if (contexts_.empty()) {
38 throw_exception(toml_exception("Cannot add value to root (root must be a table)"));
39 }
40
41 const auto& top = contexts_.top();
42 if (top.type == ARRAY) {
43 top.array_ptr->add_element(_MSTL move(v));
44 } else if (top.type == TABLE || top.type == INLINE_TABLE) {
45 if (current_key_.empty()) {
46 throw_exception(toml_exception("No key set for value in table"));
47 }
48 if (top.table_ptr->has_member(current_key_)) {
49 throw_exception(toml_exception(("Duplicate key: " + current_key_).data()));
50 }
51 top.table_ptr->add_member(current_key_, _MSTL move(v));
52 current_key_.clear();
53 }
54 return *this;
55 }
56
57 template <typename Iterable, enable_if_t<is_iterable_v<Iterable>, int> = 0>
58 toml_builder& value_iterable_dispatch(const Iterable& t) {
59 return this->value_iterable_impl(t);
60 }
61
62 template <typename Map, enable_if_t<is_maplike_v<Map>, int> = 0>
63 toml_builder& value_iterable_impl(const Map& map) {
64 begin_inline_table();
65 for (const auto& pair : map) {
66 this->key(pair.first).value(pair.second);
67 }
68 end_inline_table();
69 return *this;
70 }
71
72 template <typename Iterable, enable_if_t<!is_maplike_v<Iterable>, int> = 0>
73 toml_builder& value_iterable_impl(const Iterable& t) {
74 begin_array();
75 for (const auto& element : t) {
76 this->value(element);
77 }
78 end_array();
79 return *this;
80 }
81
82 toml_table* get_or_create_table_path(const vector<string>& path) const;
83 toml_array* get_or_create_array_for_array_table(const vector<string>& path) const;
84
85public:
86 toml_builder();
87 toml_builder(const toml_builder&) = delete;
88 toml_builder& operator =(const toml_builder&) = delete;
89 toml_builder(toml_builder&&) = default;
90 toml_builder& operator =(toml_builder&&) = default;
91
92 toml_builder& key(const string& k);
93
94 toml_builder& begin_table(const string& table_name);
95 toml_builder& begin_table(const vector<string>& table_path);
96 toml_builder& end_table();
97
98 toml_builder& begin_inline_table();
99 toml_builder& end_inline_table();
100
101 toml_builder& begin_array();
102 toml_builder& end_array();
103
104 toml_builder& begin_array_table(const string& array_table_name);
105 toml_builder& begin_array_table(const vector<string>& array_table_path);
106 toml_builder& end_array_table();
107
108 toml_builder& value(nullptr_t) { return value_impl(make_unique<toml_boolean>(false)); }
109 toml_builder& value(const bool v) { return value_impl(make_unique<toml_boolean>(v)); }
110 toml_builder& value(const int64_t v) { return value_impl(make_unique<toml_integer>(v)); }
111 toml_builder& value(const int v) { return value(static_cast<int64_t>(v)); }
112 toml_builder& value(const double v) { return value_impl(make_unique<toml_float>(v)); }
113 toml_builder& value(const string& v) {
114 return value_impl(make_unique<toml_string>(v, toml_string::Basic));
115 }
116 toml_builder& value(const char* v) { return value(string(v)); }
117 toml_builder& value(const string_view v) { return value(string(v)); }
118 toml_builder& value(unique_ptr<toml_value>&& v) { return value_impl(_MSTL move(v)); }
119
120 toml_builder& value_string(const string& v, toml_string::string_type type) {
121 return value_impl(make_unique<toml_string>(v, type));
122 }
123
124 toml_builder& value_datetime(const string_view v, toml_datetime::datetime_type type) {
125 return value_impl(make_unique<toml_datetime>(v, type));
126 }
127
128 template <typename Iterable>
129 toml_builder& value(const Iterable& t) {
130 return this->value_iterable_dispatch(t);
131 }
132
133 toml_builder& value_table(_MSTL function<void(toml_builder&)>&& build_func);
134 toml_builder& value_inline_table(_MSTL function<void(toml_builder&)>&& build_func);
135 toml_builder& value_array(_MSTL function<void(toml_builder&)>&& build_func);
136
137 unique_ptr<toml_table> build();
138};
139
141#endif // MSTL_CORE_FILE_TOML_BUILDER_HPP__
MSTL通用函数包装器
long long int64_t
64位有符号整数类型
decltype(nullptr) nullptr_t
空指针类型
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
MSTL_CONSTEXPR20 unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr