Zen C++ Libraries
Zero-dependency re-usable components for C++
Loading...
Searching...
No Matches
value.hpp
1#ifndef ZEN_VALUE_HPP
2#define ZEN_VALUE_HPP
3
4#include <vector>
5#include <memory>
6
7#include "zen/config.hpp"
8#include "zen/clone_ptr.hpp"
9#include "zen/config.hpp"
10#include "zen/string.hpp"
11#include "zen/seq_map.hpp"
12
13ZEN_NAMESPACE_START
14
15using bigint = long long;
16
17using fractional = double;
18
19enum class value_type {
20 array,
21 boolean,
22 string,
23 null,
24 integer,
25 fractional,
26 object,
27};
28
29class value;
30
31class null {};
32
33
34class value {
35public:
36
37 using array = std::vector<value>;
38 using object = seq_map<string, value>;
39
40private:
41
42 value_type type;
43
44 union {
45 bool b;
46 bigint i;
47 fractional f;
48 string s;
49 array a;
50 object o;
51 };
52
53public:
54
55 value():
56 type(value_type::null) {}
57
58 value(null):
59 type(value_type::null) {}
60
61 value(bool b):
62 type(value_type::boolean), b(b) {}
63
64 value(bigint i):
65 type(value_type::integer), i(i) {}
66
67 value(fractional f):
68 type(value_type::fractional), f(f) {}
69
70 value(object o):
71 type(value_type::object), o(o) {}
72
73 value(array value):
74 type(value_type::array) {
75 new (&a) array(value);
76 }
77
78 value(string s):
79 type(value_type::string), s(s) { }
80
81 value(const value& other): type(other.type) {
82 switch (other.type) {
83 case value_type::array:
84 new (&a) array(other.a);
85 break;
86 case value_type::object:
87 new (&o) object(other.o);
88 break;
89 case value_type::integer:
90 new (&i) bigint(other.i);
91 break;
92 case value_type::boolean:
93 b = other.b;
94 break;
95 case value_type::null:
96 break;
97 case value_type::string:
98 new (&s) string(other.s);
99 break;
100 case value_type::fractional:
101 new (&f) fractional(other.f);
102 break;
103 }
104 }
105
106 value(value&& other): type(std::move(other.type)) {
107 switch (other.type) {
108 case value_type::array:
109 new (&a) array(std::move(other.a));
110 break;
111 case value_type::object:
112 new (&o) object(std::move(other.o));
113 break;
114 case value_type::integer:
115 new (&i) bigint(std::move(other.i));
116 break;
117 case value_type::boolean:
118 b = other.b;
119 break;
120 case value_type::null:
121 break;
122 case value_type::string:
123 new (&s) string(std::move(other.s));
124 break;
125 case value_type::fractional:
126 new (&f) fractional(std::move(other.f));
127 break;
128 }
129 other.type = value_type::null;
130 }
131
132 value& operator=(const value& other) {
133 type = other.type;
134 switch (other.type) {
135 case value_type::array:
136 new (&a) array(other.a);
137 break;
138 case value_type::object:
139 new (&o) object(other.o);
140 break;
141 case value_type::integer:
142 new (&i) bigint(other.i);
143 break;
144 case value_type::boolean:
145 b = other.b;
146 break;
147 case value_type::null:
148 break;
149 case value_type::string:
150 new (&s) string(other.s);
151 break;
152 case value_type::fractional:
153 new (&f) fractional(other.f);
154 break;
155 }
156 return *this;
157 }
158
159 value& operator=(value&& other) {
160 type = std::move(other.type);
161 switch (other.type) {
162 case value_type::array:
163 new (&a) array(std::move(other.a));
164 break;
165 case value_type::object:
166 new (&o) object(std::move(other.o));
167 break;
168 case value_type::integer:
169 new (&i) bigint(std::move(other.i));
170 break;
171 case value_type::boolean:
172 b = other.b;
173 break;
174 case value_type::null:
175 break;
176 case value_type::string:
177 new (&s) string(std::move(other.s));
178 break;
179 case value_type::fractional:
180 new (&f) fractional(std::move(other.f));
181 break;
182 }
183 other.type = value_type::null;
184 return *this;
185 }
186
187 inline ~value() {
188 switch (type) {
189 case value_type::string:
190 s.~string();
191 break;
192 case value_type::fractional:
193 f.~fractional();
194 break;
195 case value_type::array:
196 a.~array();
197 break;
198 case value_type::object:
199 o.~object();
200 break;
201 case value_type::boolean:
202 break;
203 case value_type::integer:
204 i.~bigint();
205 break;
206 case value_type::null:
207 break;
208 }
209 }
210
211 inline value_type get_type() const noexcept {
212 return type;
213 }
214
215 inline bool& as_boolean() {
216 ZEN_ASSERT(type == value_type::boolean);
217 return b;
218 }
219
220 inline const bool& as_boolean() const {
221 ZEN_ASSERT(type == value_type::boolean);
222 return b;
223 }
224
225 inline string& as_string() {
226 ZEN_ASSERT(type == value_type::string);
227 return s;
228 }
229
230 inline const string& as_string() const {
231 ZEN_ASSERT(type == value_type::string);
232 return s;
233 }
234
235 inline bigint& as_integer() {
236 ZEN_ASSERT(type == value_type::integer);
237 return i;
238 }
239
240 inline const bigint& as_integer() const {
241 ZEN_ASSERT(type == value_type::integer);
242 return i;
243 }
244
245 inline fractional& as_fractional() {
246 ZEN_ASSERT(type == value_type::fractional);
247 return f;
248 }
249
250 inline const fractional& as_fractional() const {
251 ZEN_ASSERT(type == value_type::fractional);
252 return f;
253 }
254
255 inline array& as_array() {
256 ZEN_ASSERT(type == value_type::array);
257 return a;
258 }
259
260 inline const array& as_array() const {
261 ZEN_ASSERT(type == value_type::array);
262 return a;
263 }
264
265 inline object& as_object() {
266 ZEN_ASSERT(type == value_type::object);
267 return o;
268 }
269
270 inline const object& as_object() const {
271 ZEN_ASSERT(type == value_type::object);
272 return o;
273 }
274
275 inline bool is_true() const noexcept {
276 return type == value_type::boolean && b;
277 }
278
279 inline bool is_false() const noexcept {
280 return type == value_type::boolean && !b;
281 }
282
283 inline bool is_boolean() const noexcept {
284 return type == value_type::boolean;
285 }
286
287 inline bool is_integer() const noexcept {
288 return type == value_type::integer;
289 }
290
291 inline bool is_fractional() const noexcept {
292 return type == value_type::fractional;
293 }
294
295 inline bool is_null() const noexcept {
296 return type == value_type::null;
297 }
298
299 inline bool is_string() const noexcept {
300 return type == value_type::string;
301 }
302
303 inline bool is_object() const noexcept {
304 return type == value_type::object;
305 }
306
307 inline bool is_array() const noexcept {
308 return type == value_type::array;
309 }
310
311};
312
313using array = value::array;
314using object = value::object;
315
316ZEN_NAMESPACE_END
317
318#endif // of #ifndef ZEN_VALUE_HPP
Definition value.hpp:31
Definition seq_map.hpp:13
Definition value.hpp:34
A Unicode-aware string type.