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"
24class MSTL_API yaml_value : public istringify<yaml_value> {
40 virtual ~yaml_value() =
default;
41 MSTL_NODISCARD
virtual types type() const noexcept = 0;
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; }
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; }
61 void set_anchor(
const string& a) { this->anchor = a; }
62 void set_tag(
const string& t) { this->tag = t; }
64 MSTL_NODISCARD
string to_string()
const;
65 MSTL_NODISCARD
string to_document()
const;
71class MSTL_API yaml_null final :
public yaml_value {
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; }
78class MSTL_API yaml_boolean final :
public yaml_value {
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; }
89class MSTL_API yaml_integer final :
public yaml_value {
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; }
100class MSTL_API yaml_float final :
public yaml_value {
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; }
111class MSTL_API yaml_string final :
public yaml_value {
126 explicit yaml_string(
string v,
const string_style s = Plain) noexcept
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; }
135class MSTL_API yaml_timestamp final :
public yaml_value {
140 explicit yaml_timestamp(
const string_view v) {
142 if (dt.try_parse_ISO_UTC(v) || dt.try_parse_ISO(v)) {
145 throw_exception(yaml_exception((
"Invalid timestamp format: " +
string(v)).c_str()));
149 explicit yaml_timestamp(
const datetime& dt) noexcept : value(dt) {}
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; }
155 MSTL_NODISCARD
string get_string_value() const noexcept {
156 return value.to_string_ISO_UTC();
160class MSTL_API yaml_sequence final :
public yaml_value {
162 enum sequence_style {
168 vector<yaml_ptr> elements;
169 sequence_style style;
172 explicit yaml_sequence(
const sequence_style s = Block) : style(s) {}
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;
179 MSTL_NODISCARD types type() const noexcept
override {
return Sequence; }
180 MSTL_NODISCARD
const yaml_sequence* as_sequence() const noexcept
override {
return this; }
182 void add_element(yaml_ptr value) {
183 elements.emplace_back(
_MSTL move(value));
186 MSTL_NODISCARD
const yaml_value* get_element(
const size_t index)
const noexcept {
187 if (index < elements.size())
return elements[index].get();
191 MSTL_NODISCARD yaml_value* get_element(
const size_t index)
noexcept {
192 if (index < elements.size())
return elements[index].get();
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; }
202class MSTL_API yaml_mapping final :
public yaml_value {
210 unordered_map<string, yaml_ptr> members;
214 explicit yaml_mapping(
const mapping_style s = Block) : style(s) {}
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;
221 MSTL_NODISCARD types type() const noexcept
override {
return Mapping; }
222 MSTL_NODISCARD
const yaml_mapping* as_mapping() const noexcept
override {
return this; }
224 void add_member(
const string& key, yaml_ptr value) {
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();
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();
240 MSTL_NODISCARD
bool has_member(
const string& key)
const {
241 return members.find(key) != members.end();
244 MSTL_NODISCARD
const unordered_map<string, yaml_ptr>& get_members() const noexcept {
248 MSTL_NODISCARD mapping_style get_style() const noexcept {
return style; }
249 void set_style(
const mapping_style s)
noexcept { style = s; }
251 void merge_from(
const yaml_mapping* other) {
253 for (
const auto& pair : other->get_members()) {
254 if (members.find(pair.first) == members.end()) {
255 members[pair.first] = pair.second;
262string MSTL_API yaml_value_to_string(
const yaml_value* value);
263string MSTL_API yaml_value_document(
const yaml_value* root);
266MSTL_ALWAYS_INLINE_INLINE
string to_string(
const yaml_value* value) {
267 return _INNER yaml_value_to_string(value);
269MSTL_ALWAYS_INLINE_INLINE
string to_string(
const yaml_value& value) {
270 return _INNER yaml_value_to_string(&value);
272MSTL_ALWAYS_INLINE_INLINE
string to_string(
const yaml_ptr& value) {
273 return _INNER yaml_value_to_string(value.
get());
276MSTL_NODISCARD MSTL_ALWAYS_INLINE_INLINE
string yaml_value::to_string()
const {
277 return _INNER yaml_value_to_string(
this);
280MSTL_ALWAYS_INLINE_INLINE
string yaml_document(
const yaml_value* value) {
281 return _INNER yaml_value_document(value);
283MSTL_ALWAYS_INLINE_INLINE
string yaml_document(
const yaml_value& value) {
284 return _INNER yaml_value_document(&value);
286MSTL_ALWAYS_INLINE_INLINE
string yaml_document(
const yaml_ptr& value) {
287 return _INNER yaml_value_document(value.
get());
290MSTL_NODISCARD MSTL_ALWAYS_INLINE_INLINE
string yaml_value::to_document()
const {
291 return _INNER yaml_value_document(
this);
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()))
获取容器的大小