MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
yaml_value.hpp
1#ifndef MSTL_CORE_FILE_YAML_YAML_VALUE_HPP__
2#define MSTL_CORE_FILE_YAML_YAML_VALUE_HPP__
3#include "MSTL/core/container/unordered_map.hpp"
4#include "MSTL/core/container/vector.hpp"
6#include "MSTL/core/interface/istringify.hpp"
7#include "MSTL/core/time/datetime.hpp"
9
10MSTL_ERROR_BUILD_FINAL_CLASS(yaml_exception, value_exception, "YAML Operation Failed.")
11
12
13class yaml_value;
14class yaml_null;
15class yaml_boolean;
16class yaml_integer;
17class yaml_float;
18class yaml_string;
19class yaml_timestamp;
20class yaml_sequence;
21class yaml_mapping;
22
23
24class MSTL_API yaml_value : public istringify<yaml_value> {
25public:
26 string anchor;
27 string tag;
28
29 enum types {
30 Null,
31 Boolean,
32 Integer,
33 Float,
34 String,
35 Timestamp,
36 Sequence,
37 Mapping
38 };
39
40 virtual ~yaml_value() = default;
41 MSTL_NODISCARD virtual types type() const noexcept = 0;
42
43 MSTL_NODISCARD virtual const yaml_null* as_null() const noexcept { return nullptr; }
44 MSTL_NODISCARD virtual const yaml_boolean* as_boolean() const noexcept { return nullptr; }
45 MSTL_NODISCARD virtual const yaml_integer* as_integer() const noexcept { return nullptr; }
46 MSTL_NODISCARD virtual const yaml_float* as_float() const noexcept { return nullptr; }
47 MSTL_NODISCARD virtual const yaml_string* as_string() const noexcept { return nullptr; }
48 MSTL_NODISCARD virtual const yaml_timestamp* as_timestamp() const noexcept { return nullptr; }
49 MSTL_NODISCARD virtual const yaml_sequence* as_sequence() const noexcept { return nullptr; }
50 MSTL_NODISCARD virtual const yaml_mapping* as_mapping() const noexcept { return nullptr; }
51
52 MSTL_NODISCARD bool is_null() const noexcept { return type() == Null; }
53 MSTL_NODISCARD bool is_boolean() const noexcept { return type() == Boolean; }
54 MSTL_NODISCARD bool is_integer() const noexcept { return type() == Integer; }
55 MSTL_NODISCARD bool is_float() const noexcept { return type() == Float; }
56 MSTL_NODISCARD bool is_string() const noexcept { return type() == String; }
57 MSTL_NODISCARD bool is_timestamp() const noexcept { return type() == Timestamp; }
58 MSTL_NODISCARD bool is_sequence() const noexcept { return type() == Sequence; }
59 MSTL_NODISCARD bool is_mapping() const noexcept { return type() == Mapping; }
60
61 void set_anchor(const string& a) { this->anchor = a; }
62 void set_tag(const string& t) { this->tag = t; }
63
64 MSTL_NODISCARD string to_string() const;
65 MSTL_NODISCARD string to_document() const;
66};
67
68using yaml_ptr = shared_ptr<yaml_value>;
69
70
71class MSTL_API yaml_null final : public yaml_value {
72public:
73 yaml_null() = default;
74 MSTL_NODISCARD types type() const noexcept override { return Null; }
75 MSTL_NODISCARD const yaml_null* as_null() const noexcept override { return this; }
76};
77
78class MSTL_API yaml_boolean final : public yaml_value {
79private:
80 bool value;
81
82public:
83 explicit yaml_boolean(const bool v) noexcept : value(v) {}
84 MSTL_NODISCARD types type() const noexcept override { return Boolean; }
85 MSTL_NODISCARD const yaml_boolean* as_boolean() const noexcept override { return this; }
86 MSTL_NODISCARD bool get_value() const noexcept { return value; }
87};
88
89class MSTL_API yaml_integer final : public yaml_value {
90private:
91 int64_t value;
92
93public:
94 explicit yaml_integer(const int64_t v) noexcept : value(v) {}
95 MSTL_NODISCARD types type() const noexcept override { return Integer; }
96 MSTL_NODISCARD const yaml_integer* as_integer() const noexcept override { return this; }
97 MSTL_NODISCARD int64_t get_value() const noexcept { return value; }
98};
99
100class MSTL_API yaml_float final : public yaml_value {
101private:
102 double value;
103
104public:
105 explicit yaml_float(const double v) noexcept : value(v) {}
106 MSTL_NODISCARD types type() const noexcept override { return Float; }
107 MSTL_NODISCARD const yaml_float* as_float() const noexcept override { return this; }
108 MSTL_NODISCARD double get_value() const noexcept { return value; }
109};
110
111class MSTL_API yaml_string final : public yaml_value {
112public:
113 enum string_style {
114 Plain,
115 SingleQuoted,
116 DoubleQuoted,
117 Literal,
118 Folded
119 };
120
121private:
122 string value;
123 string_style style;
124
125public:
126 explicit yaml_string(string v, const string_style s = Plain) noexcept
127 : value(_MSTL move(v)), style(s) {}
128
129 MSTL_NODISCARD types type() const noexcept override { return String; }
130 MSTL_NODISCARD const yaml_string* as_string() const noexcept override { return this; }
131 MSTL_NODISCARD const string& get_value() const noexcept { return value; }
132 MSTL_NODISCARD string_style get_style() const noexcept { return style; }
133};
134
135class MSTL_API yaml_timestamp final : public yaml_value {
136private:
137 datetime value;
138
139public:
140 explicit yaml_timestamp(const string_view v) {
141 datetime dt;
142 if (dt.try_parse_ISO_UTC(v) || dt.try_parse_ISO(v)) {
143 value = dt;
144 } else {
145 throw_exception(yaml_exception(("Invalid timestamp format: " + string(v)).c_str()));
146 }
147 }
148
149 explicit yaml_timestamp(const datetime& dt) noexcept : value(dt) {}
150
151 MSTL_NODISCARD types type() const noexcept override { return Timestamp; }
152 MSTL_NODISCARD const yaml_timestamp* as_timestamp() const noexcept override { return this; }
153 MSTL_NODISCARD const datetime& get_value() const noexcept { return value; }
154
155 MSTL_NODISCARD string get_string_value() const noexcept {
156 return value.to_string_ISO_UTC();
157 }
158};
159
160class MSTL_API yaml_sequence final : public yaml_value {
161public:
162 enum sequence_style {
163 Block,
164 Flow
165 };
166
167private:
168 vector<yaml_ptr> elements;
169 sequence_style style;
170
171public:
172 explicit yaml_sequence(const sequence_style s = Block) : style(s) {}
173
174 yaml_sequence(const yaml_sequence&) = delete;
175 yaml_sequence& operator =(const yaml_sequence&) = delete;
176 yaml_sequence(yaml_sequence&&) = default;
177 yaml_sequence& operator =(yaml_sequence&&) = default;
178
179 MSTL_NODISCARD types type() const noexcept override { return Sequence; }
180 MSTL_NODISCARD const yaml_sequence* as_sequence() const noexcept override { return this; }
181
182 void add_element(yaml_ptr value) {
183 elements.emplace_back(_MSTL move(value));
184 }
185
186 MSTL_NODISCARD const yaml_value* get_element(const size_t index) const noexcept {
187 if (index < elements.size()) return elements[index].get();
188 return nullptr;
189 }
190
191 MSTL_NODISCARD yaml_value* get_element(const size_t index) noexcept {
192 if (index < elements.size()) return elements[index].get();
193 return nullptr;
194 }
195
196 MSTL_NODISCARD size_t size() const noexcept { return elements.size(); }
197 MSTL_NODISCARD const vector<yaml_ptr>& get_elements() const noexcept { return elements; }
198 MSTL_NODISCARD sequence_style get_style() const noexcept { return style; }
199 void set_style(const sequence_style s) noexcept { style = s; }
200};
201
202class MSTL_API yaml_mapping final : public yaml_value {
203public:
204 enum mapping_style {
205 Block,
206 Flow
207 };
208
209private:
210 unordered_map<string, yaml_ptr> members;
211 mapping_style style;
212
213public:
214 explicit yaml_mapping(const mapping_style s = Block) : style(s) {}
215
216 yaml_mapping(const yaml_mapping&) = delete;
217 yaml_mapping& operator =(const yaml_mapping&) = delete;
218 yaml_mapping(yaml_mapping&&) = default;
219 yaml_mapping& operator =(yaml_mapping&&) = default;
220
221 MSTL_NODISCARD types type() const noexcept override { return Mapping; }
222 MSTL_NODISCARD const yaml_mapping* as_mapping() const noexcept override { return this; }
223
224 void add_member(const string& key, yaml_ptr value) {
225 members[key] = _MSTL move(value);
226 }
227
228 MSTL_NODISCARD const yaml_value* get_member(const string& key) const {
229 const auto it = members.find(key);
230 if (it != members.end()) return it->second.get();
231 return nullptr;
232 }
233
234 MSTL_NODISCARD yaml_value* get_member(const string& key) {
235 const auto it = members.find(key);
236 if (it != members.end()) return it->second.get();
237 return nullptr;
238 }
239
240 MSTL_NODISCARD bool has_member(const string& key) const {
241 return members.find(key) != members.end();
242 }
243
244 MSTL_NODISCARD const unordered_map<string, yaml_ptr>& get_members() const noexcept {
245 return members;
246 }
247
248 MSTL_NODISCARD mapping_style get_style() const noexcept { return style; }
249 void set_style(const mapping_style s) noexcept { style = s; }
250
251 void merge_from(const yaml_mapping* other) {
252 if (!other) return;
253 for (const auto& pair : other->get_members()) {
254 if (members.find(pair.first) == members.end()) {
255 members[pair.first] = pair.second;
256 }
257 }
258 }
259};
260
262string MSTL_API yaml_value_to_string(const yaml_value* value);
263string MSTL_API yaml_value_document(const yaml_value* root);
265
266MSTL_ALWAYS_INLINE_INLINE string to_string(const yaml_value* value) {
267 return _INNER yaml_value_to_string(value);
268}
269MSTL_ALWAYS_INLINE_INLINE string to_string(const yaml_value& value) {
270 return _INNER yaml_value_to_string(&value);
271}
272MSTL_ALWAYS_INLINE_INLINE string to_string(const yaml_ptr& value) {
273 return _INNER yaml_value_to_string(value.get());
274}
275
276MSTL_NODISCARD MSTL_ALWAYS_INLINE_INLINE string yaml_value::to_string() const {
277 return _INNER yaml_value_to_string(this);
278}
279
280MSTL_ALWAYS_INLINE_INLINE string yaml_document(const yaml_value* value) {
281 return _INNER yaml_value_document(value);
282}
283MSTL_ALWAYS_INLINE_INLINE string yaml_document(const yaml_value& value) {
284 return _INNER yaml_value_document(&value);
285}
286MSTL_ALWAYS_INLINE_INLINE string yaml_document(const yaml_ptr& value) {
287 return _INNER yaml_value_document(value.get());
288}
289
290MSTL_NODISCARD MSTL_ALWAYS_INLINE_INLINE string yaml_value::to_document() const {
291 return _INNER yaml_value_document(this);
292}
293
295#endif // MSTL_CORE_FILE_YAML_YAML_VALUE_HPP__
共享智能指针类模板
MSTL_NODISCARD T * get() const noexcept
获取原始指针
long long int64_t
64位有符号整数类型
#define MSTL_ERROR_BUILD_FINAL_CLASS(THIS, BASE, INFO)
构建最终异常类宏
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
MSTL共享智能指针实现
判断类型是否为布尔类型
变量处理异常