MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
json_builder.hpp
1#ifndef MSTL_CORE_FILE_JSON_JSON_BUILDER_HPP__
2#define MSTL_CORE_FILE_JSON_JSON_BUILDER_HPP__
3#include "MSTL/core/container/stack.hpp"
5#include "json_value.hpp"
7
8class MSTL_API json_builder {
9private:
10 enum RANGE_TYPE { OBJECT, ARRAY };
11
12 struct frame {
13 RANGE_TYPE type = OBJECT;
14 union {
15 json_object* object_ptr = nullptr;
16 json_array* array_ptr;
17 };
18
19 frame() = default;
20 frame(const RANGE_TYPE t, json_object* obj) : type(t), object_ptr(obj) {}
21 frame(const RANGE_TYPE t, json_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<json_value> root;
32 string current_key;
33
34private:
35 template <typename T>
36 json_builder& value_impl(unique_ptr<T> v) {
37 if (contexts.empty()) {
38 if (root) {
39 throw_exception(json_exception("Multiple root values not allowed"));
40 }
41 root = _MSTL move(v);
42 } else {
43 const auto& top = contexts.top();
44 if (top.type == ARRAY) {
45 top.array_ptr->add_element(_MSTL move(v));
46 } else if (top.type == OBJECT) {
47 if (current_key.empty()) {
48 throw_exception(json_exception("No key set for value in object"));
49 }
50 top.object_ptr->add_member(current_key, _MSTL move(v));
51 current_key.clear();
52 }
53 }
54 return *this;
55 }
56
57 template <typename Iterable, enable_if_t<is_iterable_v<Iterable>, int> = 0>
58 json_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 json_builder& value_iterable_impl(const Map& map) {
64 begin_object();
65 for (const auto& pair : map) {
66 this->key(pair.first).value(pair.second);
67 }
68 end_object();
69 return *this;
70 }
71
72 template <typename Iterable, enable_if_t<!is_maplike_v<Iterable>, int> = 0>
73 json_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
82public:
83 json_builder() = default;
84 json_builder(const json_builder&) = delete;
85 json_builder& operator =(const json_builder&) = delete;
86 json_builder(json_builder&&) = default;
87 json_builder& operator =(json_builder&&) = default;
88
89 json_builder& begin_object();
90 json_builder& begin_array();
91
92 json_builder& end_object();
93 json_builder& end_array();
94
95 json_builder& key(const string& k);
96
97 json_builder& value(nullptr_t) { return value_impl(make_unique<json_null>()); }
98 json_builder& value(const string& v) { return value_impl(make_unique<json_string>(v)); }
99 json_builder& value(const char* v) { return value(string(v)); }
100 json_builder& value(const string_view v) { return value(string(v)); }
101 json_builder& value(const double v) { return value_impl(make_unique<json_number>(v)); }
102 json_builder& value(const int v) { return value_impl(make_unique<json_number>(static_cast<double>(v))); }
103 json_builder& value(const bool v) { return value_impl(make_unique<json_bool>(v)); }
104 json_builder& value(unique_ptr<json_value>&& v) { return value_impl(_MSTL move(v)); }
105
106 template <typename Iterable>
107 json_builder& value(const Iterable& t) {
108 return this->value_iterable_dispatch(t);
109 }
110
111 json_builder& value_object(_MSTL function<void(json_builder&)>&& build_func);
112 json_builder& value_array(_MSTL function<void(json_builder&)>&& build_func);
113
114 unique_ptr<json_value> build();
115};
116
118#endif // MSTL_CORE_FILE_JSON_JSON_BUILDER_HPP__
MSTL通用函数包装器
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_CONSTEXPR20 unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr