steam-min-cpp
Loading...
Searching...
No Matches
ctljson.hpp
1
3/*****************************************************************************
4**
5** ctl::json version 2.115
6**
7** Copyright (c) 2019-2025, Nozomu Katoo. All rights reserved.
8**
9** Redistribution and use in source and binary forms, with or without
10** modification, are permitted provided that the following conditions are
11** met:
12**
13** 1. Redistributions of source code must retain the above copyright notice,
14** this list of conditions and the following disclaimer.
15**
16** 2. Redistributions in binary form must reproduce the above copyright
17** notice, this list of conditions and the following disclaimer in the
18** documentation and/or other materials provided with the distribution.
19**
20** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
21** IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31**
32******************************************************************************
33**/
34
35#ifndef CTL_JSON_TEMPLATE_LIBRARY
36#define CTL_JSON_TEMPLATE_LIBRARY
37
38#include <algorithm>
39#include <cstdlib>
40#include <cstring>
41#include <iterator>
42#include <limits>
43#include <map>
44#include <memory>
45#include <new>
46#include <string>
47#include <utility>
48#include <vector>
49
50
51#if !defined(NAMESPACE_CTLJSON)
52#define NAMESPACE_CTLJSON ctl
53#endif
54
55namespace NAMESPACE_CTLJSON {
56namespace string_internal_ {
57
58template <typename T>
59struct casetables {
60 static const T lc[];
61 static const T uc[];
62};
63template <typename T>
64const T casetables<T>::lc[] = {
65 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
66 0x38, 0x39, // "0123456789";
67 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
68 0x69, 0x6a, // "abcdefghij"
69 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
70 0x73, 0x74, // "klmnopqrst"
71 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x2e, 0x2b, // "uvwxyz.+"
72 0x2d, 0x69, 0x6e, 0x66, // "-inf"
73 0x2d, 0x71, 0x6e, 0x61, 0x6e, // "-qnan"
74 0x2d, 0x73, 0x6e, 0x61, 0x6e // "-snan"
75};
76template <typename T>
77const T casetables<T>::uc[] = {
78 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
79 0x38, 0x39, // "0123456789";
80 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
81 0x49, 0x4a, // "ABCDEFGHIJ"
82 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
83 0x53, 0x54, // "KLMNOPQRST"
84 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x2e, 0x2b, // "UVWXYZ.+"
85 0x2d, 0x49, 0x4e, 0x46, // "-INF"
86 0x2d, 0x51, 0x4e, 0x41, 0x4e, // "-QNAN"
87 0x2d, 0x53, 0x4e, 0x41, 0x4e // "-SNAN"
88};
89
90template <typename stringT>
91stringT reverse_(stringT& s) {
92 typedef typename stringT::size_type size_type;
93 const size_type mid = s.size() / 2;
94
95 for (size_type i = 0; i < mid; ++i) std::swap(s[i], s[s.size() - i - 1]);
96
97 return s;
98}
99
100template <typename stringT>
101int mul2_(stringT& s, const int radix) {
102 typedef typename stringT::value_type char_type;
103 typedef typename stringT::size_type size_type;
104 char_type carried = 0;
105
106 for (size_type i = 0; i < s.size(); ++i) {
107 char_type& ch = s[i] *= 2;
108
109 carried = ((ch = static_cast<char_type>(ch + carried)) >=
110 static_cast<char_type>(radix))
111 ? (ch = static_cast<char_type>(ch - radix), 1)
112 : 0;
113 }
114 return carried ? (s.push_back(carried), 1) : 0;
115}
116
117template <typename stringT>
118int div2_(stringT& s, const int radix) {
119 typedef typename stringT::value_type char_type;
120 typedef typename stringT::size_type size_type;
121 int borrowed = 0;
122
123 for (size_type i = s.size(); i;) {
124 char_type& ch = s[--i];
125
126 ch = static_cast<char_type>(ch + (borrowed ? radix : 0));
127
128 borrowed = ch & 1;
129 ch /= 2;
130 }
131 if (borrowed) s.insert(0, 1, static_cast<char_type>(radix / 2));
132
133 if (s.size() && s[s.size() - 1] == 0) {
134 s.resize(s.size() - 1);
135 borrowed |= 2;
136 }
137 return borrowed;
138}
139
140template <typename stringT>
141int plus_(stringT& s1, const stringT& s2, const int radix) {
142 typedef typename stringT::value_type char_type;
143 typedef typename stringT::size_type size_type;
144 char_type carried = 0;
145
146 if (s1.size() < s2.size()) s1.resize(s2.size(), 0);
147
148 for (size_type i = 0; i < s1.size(); ++i) {
149 char_type& ch = s1[i] += (i < s2.size() ? s2[i] : 0) + carried;
150 carried = (ch >= static_cast<char_type>(radix))
151 ? (ch = static_cast<char_type>(ch - radix), 1)
152 : 0;
153 }
154 return carried ? (s1.push_back(carried), 1) : 0;
155}
156
157template <typename stringT>
158int round_(stringT& s, typename stringT::size_type pos, const int radix) {
159 typedef typename stringT::value_type char_type;
160
161 if (pos <= s.size()) {
162 char_type carried =
163 (s[(pos = s.size() - pos)] >= static_cast<char_type>(radix / 2)) ? 1
164 : 0;
165
166 for (s.erase(0, pos + 1), pos = 0; carried && pos < s.size(); ++pos) {
167 char_type& ch = s[pos];
168
169 ch = static_cast<char_type>(ch + carried);
170 carried = (ch >= static_cast<char_type>(radix))
171 ? (ch = static_cast<char_type>(ch - radix), 1)
172 : 0;
173 }
174 if (carried) return s.push_back(carried), 1;
175 }
176 return 0;
177}
178
179template <typename T>
180static bool is_same_(const T l, const T r) {
181 return std::memcmp(&l, &r, sizeof(T)) == 0;
182}
183
184} // namespace string_internal_
185
186template <typename stringT, typename T>
187inline stringT to_string(T value, int base = 10, const int precision = 1) {
188 typedef typename stringT::value_type char_type;
189 typedef typename stringT::size_type size_type;
190 const char_type* const table =
191 (base >= 0
192 ? string_internal_::casetables<char_type>::lc
193 : (base = 0 - base, string_internal_::casetables<char_type>::uc));
194 stringT num;
195
196 if (base >= 2 && base <= 36) {
197 const bool minus = value < 0 ? (value = 0 - value, true) : false;
198
199 for (; value; value /= base) {
200 num.push_back(table[value % base]);
201 }
202
203 if (precision > 0 && num.size() < static_cast<size_type>(precision))
204 num.append(static_cast<size_type>(precision) - num.size(), table[0]);
205
206 if (minus) num.push_back(table[38]);
207 }
208 return string_internal_::reverse_(num);
209}
210
211template <typename stringT, typename T>
212stringT to_string_fp(T value, int fmt, int precision) {
213 typedef stringT string_type;
214 typedef typename stringT::value_type char_type;
215 typedef typename stringT::size_type size_type;
216
217 const bool uc = fmt >= 'A' && fmt <= 'Z';
218
219 const char_type* const table =
220 uc ? (fmt += 'a' - 'A', string_internal_::casetables<char_type>::uc)
221 : string_internal_::casetables<char_type>::lc;
222
223 int dppos;
224
225 if ((dppos = 38 + 1,
226 string_internal_::is_same_(value, std::numeric_limits<T>::infinity())) ||
227 (--dppos,
228 string_internal_::is_same_(value, -std::numeric_limits<T>::infinity())))
229 // return &(uc ? "-INF" : "-inf")[dppos];
230 return stringT(&table[dppos], ((dppos & 1) ? 3 : 4));
231
232 if ((dppos = 42 + 1, string_internal_::is_same_(
233 value, std::numeric_limits<T>::quiet_NaN())) ||
234 (--dppos,
235 string_internal_::is_same_(value, -std::numeric_limits<T>::quiet_NaN())))
236 // return &(uc ? "-QNAN" : "-qnan")[dppos];
237 return stringT(&table[dppos], ((dppos & 1) ? 4 : 5));
238
239 if ((dppos = 47 + 1, string_internal_::is_same_(
240 value, std::numeric_limits<T>::signaling_NaN())) ||
241 (--dppos, string_internal_::is_same_(
242 value, -std::numeric_limits<T>::signaling_NaN())))
243 // return &(uc ? "-SNAN" : "-snan")[dppos];
244 return stringT(&table[dppos], ((dppos & 1) ? 5 : 4));
245
246 const int base = fmt == 'a' ? (fmt = 'e', 16) : 10;
247 const bool remove0s =
248 (precision < 0) ? (precision = 0 - precision, true) : (fmt == 'g');
249 const bool minus =
250 (value < 0 || string_internal_::is_same_(value, static_cast<T>(-0.0)))
251 ? (value = 0 - value, true)
252 : false;
253 string_type resstr;
254
255 dppos = 0;
256 if (value != 0.0) {
257 int borrowed = 0;
258 T mask = 1.0;
259 string_type mstr;
260
261 mstr.push_back(1);
262
263 if (value >= mask)
264 for (; (value - mask) >= mask; mask *= 2.0)
265 dppos += string_internal_::mul2_(mstr, base);
266 else
267 for (; value <
268 ((dppos -= (string_internal_::div2_(mstr, base) & 2) ? 1 : 0),
269 mask /= 2.0););
270
271 for (int count = 11; value > 0.0 && mask > 0.0 && count < 64; mask /= 2.0) {
272 if (borrowed) resstr.insert(0, 1, 0);
273
274 if (value >= mask) {
275 value -= mask;
276 dppos += string_internal_::plus_(resstr, mstr, base);
277 }
278 borrowed = string_internal_::div2_(mstr, base) & 1;
279 }
280
281 if (base == 16 && resstr.size()) {
282 const char_type& lb = resstr[resstr.size() - 1];
283 const int shift = (lb & 8) ? 3 : ((lb & 4) ? 2 : ((lb & 2) ? 1 : 0));
284
285 dppos = dppos * 4 + shift;
286 if (shift) {
287 char_type borrowed2 = 0;
288 for (size_type i = resstr.size(); i;) {
289 char_type& ch = resstr[--i] |= borrowed2;
290 borrowed2 = ch << 4;
291 ch = static_cast<char_type>((ch >> shift) & 15);
292 }
293 if (borrowed2)
294 resstr.insert(0, 1,
295 static_cast<char_type>((borrowed2 >> shift) & 15));
296 }
297 }
298 // dppos += round_(resstr, 18, base);
299 }
300
301 if (fmt == 'g') {
302 dppos += string_internal_::round_(resstr, precision + 1, base);
303
304 if (dppos >= -4 && dppos < precision) {
305 precision = precision - 1 - dppos;
306 dppos < 0 ? (resstr.append(static_cast<size_type>(-dppos),
307 static_cast<char_type>(0)),
308 dppos = 1)
309 : ++dppos;
310 goto STYLE_F;
311 }
312 goto STYLE_E;
313 }
314
315 if (fmt == 'e') {
316 ++precision;
317 dppos += string_internal_::round_(resstr, precision + 1, base);
318
319 STYLE_E:
320
321 if (remove0s)
322 for (size_type i = 0;
323 precision > 1 && i < resstr.size() && resstr[i] == 0;
324 --precision, ++i);
325
326 if (resstr.size() > static_cast<size_type>(precision))
327 resstr.erase(0, resstr.size() - precision);
328 else
329 resstr.insert(0, static_cast<size_type>(precision) - resstr.size(), 0);
330
331 for (size_type i = 0; i < resstr.size(); ++i)
332 resstr[i] = table[static_cast<unsigned int>(resstr[i])];
333
334 if (resstr.size() > 1) resstr.insert(resstr.size() - 1, 1, table[36]);
335
336 resstr.insert(0, 1, table[base == 10 ? 14 : 25]); // 'E''e' 'P''p'
337 resstr.insert(0, 1, ((dppos >= 0) ? table[37] : table[38]));
338
339 if (dppos < 0) dppos = 0 - dppos;
340
341 const size_type minwidth = base == 10 ? 2 : 1;
342 for (size_type inspos = 0; dppos || inspos < minwidth;
343 ++inspos, dppos /= 10)
344 resstr.insert(inspos, 1, table[dppos % 10]);
345
346 if (base == 16) {
347 resstr.push_back(table[33]); // 'X' 'x'
348 resstr.push_back(table[0]);
349 }
350 } else {
351 dppos < 0 ? (resstr.append(static_cast<size_type>(-dppos),
352 static_cast<char_type>(0)),
353 dppos = 1)
354 : ++dppos;
355
356 dppos += string_internal_::round_(resstr, precision + dppos + 1, base);
357
358 STYLE_F:
359
360 if (remove0s)
361 for (size_type i = 0;
362 precision > 1 && i < resstr.size() && resstr[i] == 0;
363 --precision, ++i);
364
365 precision += dppos;
366
367 if (resstr.size() > static_cast<size_type>(precision))
368 resstr.erase(0, resstr.size() - precision);
369 else {
370 const size_type wantedsize =
371 static_cast<size_type>(remove0s ? dppos : precision);
372 if (resstr.size() < wantedsize)
373 resstr.insert(0, wantedsize - resstr.size(), 0);
374 }
375
376 for (size_type i = 0; i < resstr.size(); ++i)
377 resstr[i] = table[static_cast<unsigned int>(resstr[i])];
378
379 if (resstr.size() > static_cast<size_type>(dppos))
380 resstr.insert(resstr.size() - dppos, 1, table[36]);
381 }
382
383 if (minus) resstr.push_back(table[38]);
384
385 return string_internal_::reverse_(resstr);
386}
387
388template <typename stringT>
389inline stringT to_string(double val, const int fmt = 'f',
390 const int precision = 6) {
391 return to_string_fp<stringT>(val, fmt, precision);
392}
393template <typename stringT>
394inline stringT to_string(float val, const int fmt = 'f',
395 const int precision = 6) {
396 return to_string_fp<stringT>(val, fmt, precision);
397}
398template <typename stringT>
399inline stringT to_string(long double val, const int fmt = 'f',
400 const int precision = 6) {
401 return to_string_fp<stringT>(val, fmt, precision);
402}
403
404struct json_error {
405 enum code_type {
406 ec_no_error = 0,
407 ec_ok = 0,
408 ec_array = 2,
409 ec_object = 3,
410 ec_object_name = 4,
411 ec_no_colon = 5,
412 ec_object_value = 6,
413 ec_string = 7,
414 ec_literal = 8,
415 ec_number = 9,
416 };
417
418 int code() const { return code_; }
419
420 std::size_t position() const { return pos_; }
421
422 // private:
423
424 bool clear_() {
425 pos_ = 0;
426 code_ = 0;
427 return false;
428 }
429
430 std::size_t pos_;
431 int code_;
432};
433
434namespace json_internal_ {
435
436template <typename T>
437struct view {
438 typedef T char_type;
439 typedef std::size_t size_type;
440 typedef const char_type* const_iterator;
441
442 view(const char_type* const p)
443 : data_(p), size_(std::char_traits<T>::length(p)) {}
444
445 view(const char_type* const p, const size_type l) : data_(p), size_(l) {}
446
447 template <typename StringLike>
448 view(const StringLike& s) : data_(s.data()), size_(s.size()) {}
449
450 char_type* data() { return data_; }
451 const char_type* data() const { return data_; }
452
453 size_type size() const { return size_; }
454
455 template <typename StringLike>
456 StringLike str() const {
457 return StringLike(data_, size_);
458 }
459
460 template <typename StringLike>
461 int compare(const StringLike& right) const {
462 if (data_ == right.data()) return 0;
463
464 const size_type count = size_ <= right.size() ? size_ : right.size();
465 const int cmp = std::memcmp(data_, right.data(), count * sizeof(T));
466
467 if (cmp != 0) return cmp;
468
469 return size_ == right.size() ? 0 : (size_ < right.size() ? -1 : 1);
470 }
471
472 template <typename StringLike>
473 bool operator==(const StringLike& right) const {
474 return compare(right) == 0;
475 }
476
477 template <typename StringLike>
478 bool operator!=(const StringLike& right) const {
479 return !operator==(right);
480 }
481
482 const T operator[](const size_type n) const { return data_[n]; }
483
484 const_iterator begin() const { return data_; }
485 const_iterator end() const { return data_ + size_; }
486
487 private:
488 const T* data_;
489 size_type size_;
490};
491
492template <typename ElemT>
493class nestring {
494 public:
495 typedef ElemT value_type;
496 typedef std::size_t size_type;
497 typedef ElemT& reference;
498 typedef const ElemT& const_reference;
499 typedef ElemT* pointer;
500 typedef const ElemT* const_pointer;
501 typedef const_pointer const_iterator;
502 typedef view<ElemT> view_type;
503
504 static const size_type npos = static_cast<size_type>(-1);
505
506 public:
507 nestring() : size_(0), capacity_p1_(lbsize_p1_) {}
508
509 nestring(const const_pointer p, const size_type len)
510 : size_(0), capacity_p1_(lbsize_p1_) {
511 resize(len);
512 if (len) std::memcpy(buf_(), p, len * sizeof(ElemT));
513 }
514
515 nestring(const nestring& right, const size_type pos, size_type len = npos)
516 : size_(0), capacity_p1_(lbsize_p1_) {
517 {
518 const size_type len2 = right.size_ - pos;
519 if (len > len2) len = len2;
520 }
521
522 resize(len);
523 if (len) std::memcpy(buf_(), right.buf_() + pos, len * sizeof(ElemT));
524 }
525
526 nestring(const const_pointer p) : size_(0), capacity_p1_(lbsize_p1_) {
527 operator=(p);
528 }
529
530 nestring(const nestring& right) : size_(0), capacity_p1_(lbsize_p1_) {
531 operator=(right);
532 }
533
534 nestring(const view_type v) : size_(0), capacity_p1_(lbsize_p1_) {
535 assign(v.data(), v.size());
536 }
537
538 nestring& operator=(const nestring& right) {
539 if (this != &right) {
540 resize(right.size_);
541 std::memcpy(buf_(), right.buf_(), right.size_ * sizeof(ElemT));
542 }
543 return *this;
544 }
545
546 nestring& operator=(const const_pointer p) {
547 if (buf_() != p) {
548 const std::size_t size = std::char_traits<ElemT>::length(p);
549
550 resize(size);
551 std::memcpy(buf_(), p, size * sizeof(ElemT));
552 }
553 return *this;
554 }
555
556#if defined(__cpp_rvalue_references)
557 nestring(nestring&& right)
558 : size_(right.size_), capacity_p1_(right.capacity_p1_) {
559 if (!right.is_localbuf_()) {
560 buffer_ = right.buffer_;
561 right.buffer_ = NULL;
562 } else
563 std::memcpy(localbuf_, right.localbuf_, size_ * sizeof(ElemT));
564
565 right.size_ = 0;
566 right.capacity_p1_ = lbsize_p1_;
567 }
568
569 nestring& operator=(nestring&& right) {
570 if (this != &right) {
571 size_ = right.size_;
572 capacity_p1_ = right.capacity_p1_;
573
574 if (!is_localbuf_() && buffer_ != NULL) std::free(buffer_);
575
576 if (!right.is_localbuf_()) {
577 buffer_ = right.buffer_;
578 right.buffer_ = NULL;
579 } else
580 std::memcpy(localbuf_, right.localbuf_, size_ * sizeof(ElemT));
581
582 right.size_ = 0;
583 right.capacity_p1_ = lbsize_p1_;
584 }
585 return *this;
586 }
587#endif
588
589 ~nestring() {
590 if (!is_localbuf_() && buffer_ != NULL) std::free(buffer_);
591 }
592
593 size_type size() const { return size_; }
594
595 template <typename Traits, typename Alloc>
596 operator std::basic_string<ElemT, Traits, Alloc>() const {
597 return std::basic_string<ElemT, Traits, Alloc>(buf_(), buf_() + size_);
598 }
599
600 nestring substr(size_type pos, size_type len) const {
601 return nestring(buf_() + pos, len);
602 }
603
604 view_type make_view(size_type pos, size_type len) const {
605 return view_type(buf_() + pos, len);
606 }
607
608 bool operator==(const nestring& right) const {
609 if (size_ != right.size_) return false;
610
611 if (this == &right) return true;
612
613 return std::memcmp(buf_(), right.buf_(), size_ * sizeof(ElemT)) == 0;
614 }
615
616 bool operator!=(const nestring& right) const { return !operator==(right); }
617 bool operator<(const nestring& right) const { return compare(right) < 0; }
618
619 void clear() { size_ = 0; }
620
621 void resize(const size_type newsize) {
622 if (newsize >= capacity_p1_)
623 reserve(newsize);
624 else if (!is_localbuf_() && newsize <= localbuf_size_)
625 heap_to_local_(newsize);
626
627 size_ = newsize;
628 }
629
630 void resize(const size_type newsize, const ElemT type) {
631 size_type oldsize = size_;
632
633 resize(newsize);
634
635 const pointer base = buf_();
636 for (; oldsize < size_; ++oldsize) base[oldsize] = type;
637 }
638
639 reference operator[](const size_type pos) { return buf_()[pos]; }
640
641 const_reference operator[](const size_type pos) const { return buf_()[pos]; }
642
643 void push_back(const ElemT n) {
644 const size_type oldsize = size_;
645
646 if (++size_ >= capacity_p1_) reserve(size_);
647
648 buf_()[oldsize] = n;
649 }
650
651 void assign(const nestring& right) { operator=(right); }
652
653 void assign(const const_pointer p, const size_type len) {
654 if (p != buf_()) {
655 resize(len);
656 std::memcpy(buf_(), p, len * sizeof(ElemT));
657 }
658 }
659
660 template <typename Iterator>
661 void assign(Iterator begin, const Iterator end) {
662 resize(end - begin);
663
664 for (size_type i = 0; begin != end; ++i, ++begin)
665 buf_()[i] = static_cast<value_type>(*begin);
666 }
667
668 nestring& append(const size_type len, const ElemT type) {
669 resize(size_ + len, type);
670 return *this;
671 }
672
673 nestring& append(const const_pointer p, const size_type len) {
674 const size_type oldsize = size_;
675
676 resize(size_ + len);
677 std::memcpy(buf_() + oldsize, p, len * sizeof(ElemT));
678 return *this;
679 }
680
681 nestring& append(const const_pointer p) {
682 return append(p, std::char_traits<ElemT>::length(p));
683 }
684
685 template <typename Iterator>
686 nestring& append(Iterator begin, const Iterator end) {
687 const size_type len = end - begin;
688 size_type oldsize = size_;
689
690 resize(size_ + len);
691 pointer base = buf_() + oldsize;
692 for (size_type i = 0; begin != end; ++i, ++begin)
693 base[i] = static_cast<value_type>(*begin);
694 return *this;
695 }
696
697 nestring& append(const view_type right) {
698 const size_type oldsize = size_;
699 const size_type rightsize = right.size();
700
701 resize(size_ + right.size());
702 std::memcpy(buf_() + oldsize, right.data(), rightsize * sizeof(ElemT));
703 return *this;
704 }
705
706 void erase(const size_type pos, const size_type len) {
707 if (pos < size_) {
708 size_type rmndr = size_ - pos;
709
710 if (rmndr > len) {
711 rmndr -= len;
712 std::memmove(buf_() + pos, buf_() + pos + len, rmndr * sizeof(ElemT));
713 size_ -= len;
714 } else
715 size_ = pos;
716
717 if (!is_localbuf_() && size_ <= localbuf_size_) heap_to_local_(size_);
718 }
719 }
720
721 void insert(const size_type pos, const view_type right) {
722 const size_type rightsize = right.size();
723
724 move_forwards_(pos, rightsize);
725 std::memcpy(buf_() + pos, right.data(), rightsize * sizeof(ElemT));
726 }
727
728 void insert(const size_type pos, const size_type count, const ElemT ch) {
729 move_forwards_(pos, count);
730 pointer base = buf_() + pos;
731
732 for (size_type i = 0; i < count; ++i) base[i] = ch;
733 }
734
735 const_pointer data() const { return buf_(); }
736
737 const_iterator begin() const { return buf_(); }
738 const_iterator end() const { return buf_() + size_; }
739
740 int compare(size_type pos1, const size_type count1, const view_type right,
741 const size_type pos2, const size_type count2) const {
742 const size_type count = count1 <= count2 ? count1 : count2;
743 const_pointer lbase = buf_() + pos1;
744 const_pointer rbase = right.data() + pos2;
745 const int cmp = std::memcmp(lbase, rbase, count * sizeof(ElemT));
746
747 if (cmp != 0) return cmp;
748
749 return count1 == count2 ? 0 : (count1 < count2 ? -1 : 1);
750 }
751
752 bool no_alloc_failure() const { return capacity_p1_ > 0; }
753
754 void reserve(size_type newsize) {
755 if (newsize <= maxsize_) {
756 const size_type capa2 = capacity_p1_ * 2;
757
758 if (newsize < capa2) {
759 newsize = capa2;
760 if (newsize > maxsize_) newsize = maxsize_;
761 }
762
763 if (is_localbuf_()) {
764 const pointer newbuf =
765 static_cast<pointer>(std::malloc(newsize * sizeof(ElemT)));
766
767 if (newbuf != NULL) {
768 std::memcpy(newbuf, localbuf_, size_ * sizeof(ElemT));
769 buffer_ = newbuf;
770 capacity_p1_ = newsize + 1;
771 return;
772 }
773 } else {
774 const pointer oldbuffer = buffer_;
775
776 buffer_ = static_cast<pointer>(
777 std::realloc(static_cast<void*>(buffer_), newsize * sizeof(ElemT)));
778 if (buffer_ != NULL) {
779 capacity_p1_ = newsize + 1;
780 return;
781 }
782 std::free(oldbuffer);
783 }
784
785 // buffer_ = NULL;
786 size_ = 0;
787 capacity_p1_ = 1;
788 }
789 throw std::bad_alloc();
790 }
791
792 private:
793 void move_forwards_(const size_type pos, const size_type count) {
794 const size_type oldsize = size_;
795
796 resize(size_ + count);
797
798 if (pos < oldsize) {
799 const pointer base = buf_() + pos;
800
801 std::memmove(base + count, base, (oldsize - pos) * sizeof(ElemT));
802 }
803 }
804
805 void heap_to_local_(const size_type newsize) {
806 const pointer buf = buffer_;
807
808 std::memcpy(localbuf_, buf, newsize * sizeof(ElemT));
809 std::free(buf);
810 capacity_p1_ = lbsize_p1_;
811 }
812
813 enum { localbuf_size_ = 16, lbsize_p1_ = localbuf_size_ + 1 };
814
815 bool is_localbuf_() const { return capacity_p1_ <= lbsize_p1_; }
816
817 pointer buf_() { return !is_localbuf_() ? buffer_ : localbuf_; }
818 const_pointer buf_() const { return !is_localbuf_() ? buffer_ : localbuf_; }
819
820 union {
821 pointer buffer_;
822 ElemT localbuf_[localbuf_size_];
823 };
824 size_type size_;
825 size_type capacity_p1_;
826
827 static const size_type maxsize_ = npos / sizeof(ElemT) / 2;
828};
829template <typename ElemT>
830const typename nestring<ElemT>::size_type nestring<ElemT>::npos;
831// nestring
832
833template <typename ElemT>
834class nevector {
835 public:
836 typedef ElemT value_type;
837 typedef std::size_t size_type;
838 typedef ElemT& reference;
839 typedef const ElemT& const_reference;
840 typedef ElemT* pointer;
841 typedef const ElemT* const_pointer;
842
843 public:
844 nevector() : buffer_(NULL), size_(0), capacity_p1_(1) {}
845
846 nevector(const size_type initsize)
847 : buffer_(NULL), size_(0), capacity_p1_(1) {
848 reserve(initsize);
849
850 for (size_type i = 0; i < initsize; ++i) new (&buffer_[i]) ElemT();
851
852 size_ = initsize;
853 }
854
855 nevector(const nevector& right) : buffer_(NULL), size_(0), capacity_p1_(1) {
856 reserve(right.size_);
857
858 for (size_type i = 0; i < right.size_; ++i)
859 new (&buffer_[i]) ElemT(right.buffer_[i]);
860
861 size_ = right.size_;
862 }
863
864#if defined(__cpp_rvalue_references)
865 nevector(nevector&& right)
866 : buffer_(right.buffer_),
867 size_(right.size_),
868 capacity_p1_(right.capacity_p1_) {
869 right.size_ = 0;
870 right.capacity_p1_ = 1;
871 right.buffer_ = NULL;
872 }
873
874 nevector& operator=(nevector&& right) {
875 if (this != &right) {
876 if (this->buffer_ != NULL) destroy_all_(this->buffer_);
877
878 this->size_ = right.size_;
879 this->capacity_p1_ = right.capacity_p1_;
880 this->buffer_ = right.buffer_;
881
882 right.size_ = 0;
883 right.capacity_p1_ = 1;
884 right.buffer_ = NULL;
885 }
886 return *this;
887 }
888#endif
889
890 nevector& operator=(const nevector& right) {
891 if (this != &right) {
892 resize(right.size_);
893 for (size_type i = 0; i < right.size_; ++i) buffer_[i] = right.buffer_[i];
894 }
895 return *this;
896 }
897
898 ~nevector() {
899 if (buffer_ != NULL) destroy_all_(buffer_);
900 }
901
902 size_type size() const { return size_; }
903
904 void clear() {
905 for (size_type i = 0; i < size_; ++i) buffer_[i].~ElemT();
906 size_ = 0;
907 }
908
909 void resize(const size_type newsize) {
910 if (newsize > size_) {
911 if (newsize >= capacity_p1_) reserve(newsize);
912
913 for (size_type i = size_; i < newsize; ++i) new (&buffer_[i]) ElemT();
914 } else {
915 for (size_type i = newsize; i < size_; ++i) buffer_[i].~ElemT();
916 }
917 size_ = newsize;
918 }
919
920 void resize(const size_type newsize, const ElemT& type) {
921 if (newsize > size_) {
922 if (newsize >= capacity_p1_) reserve(newsize);
923
924 for (size_type i = size_; i < newsize; ++i) new (&buffer_[i]) ElemT(type);
925 } else {
926 for (size_type i = newsize; i < size_; ++i) buffer_[i].~ElemT();
927 }
928 size_ = newsize;
929 }
930
931 reference operator[](const size_type pos) { return buffer_[pos]; }
932
933 const_reference operator[](const size_type pos) const { return buffer_[pos]; }
934
935 void push_back(const_reference n) {
936 const size_type oldsize = size_;
937
938 if (++size_ >= capacity_p1_) reserve(size_);
939
940 new (&buffer_[oldsize]) ElemT(n);
941 }
942 reference push_back() {
943 const size_type oldsize = size_;
944
945 if (++size_ >= capacity_p1_) reserve(size_);
946
947 new (&buffer_[oldsize]) ElemT;
948 return buffer_[oldsize];
949 }
950
951 const_reference back() const { return buffer_[size_ - 1]; }
952
953 reference back() { return buffer_[size_ - 1]; }
954
955 void erase(const size_type pos) {
956 if (pos < size_) {
957 buffer_[pos].~ElemT();
958 std::memmove(static_cast<void*>(buffer_ + pos), buffer_ + pos + 1,
959 (size_ - pos - 1) * sizeof(ElemT));
960 --size_;
961 }
962 }
963
964 void insert(const size_type pos, const ElemT& type) {
965 move_forwards_(pos, 1);
966
967 new (&buffer_[pos]) ElemT(type);
968 }
969 reference insert(const size_type pos) {
970 move_forwards_(pos, 1);
971
972 new (&buffer_[pos]) ElemT;
973 return buffer_[pos];
974 }
975
976 bool no_alloc_failure() const { return capacity_p1_ > 0; }
977
978 void reserve(const size_type newsize) { reserve_<16>(newsize); }
979
980 private:
981 void move_forwards_(const size_type pos, const size_type count) {
982 const size_type oldsize = size_;
983
984 resize(size_ + count);
985
986 if (pos < oldsize) {
987 const pointer base = buffer_ + pos;
988
989 std::memmove(static_cast<void*>(base + count), base,
990 (oldsize - pos) * sizeof(ElemT));
991 }
992 }
993
994 template <const size_type minsize>
995 void reserve_(size_type newsize) {
996 if (newsize <= maxsize_) {
997 const pointer oldbuffer = buffer_;
998 const size_type capa2 = newsize >= minsize ? capacity_p1_ << 1 : minsize;
999
1000 if (newsize < capa2) {
1001 newsize = capa2;
1002 if (newsize > maxsize_) newsize = maxsize_;
1003 }
1004
1005 buffer_ = static_cast<pointer>(
1006 std::realloc(static_cast<void*>(buffer_), newsize * sizeof(ElemT)));
1007 capacity_p1_ = newsize + 1;
1008
1009 if (buffer_ != NULL) return;
1010
1011 destroy_all_(oldbuffer);
1012 // buffer_ = NULL;
1013 size_ = 0;
1014 capacity_p1_ = 1;
1015 }
1016 throw std::bad_alloc();
1017 }
1018
1019 void destroy_all_(const pointer p) {
1020 for (size_type i = 0; i < size_; ++i) p[i].~ElemT();
1021 std::free(p);
1022 }
1023
1024 pointer buffer_;
1025 size_type size_;
1026 size_type capacity_p1_;
1027
1028 static const size_type maxsize_ =
1029 static_cast<size_type>(-1) / sizeof(ElemT) / 2;
1030};
1031// nevector
1032
1033enum rbtree_colour { rb_red, rb_black };
1034
1035struct rbtree_node_base {
1036 typedef rbtree_node_base* pointer;
1037 typedef const rbtree_node_base* const_pointer;
1038
1039 pointer parent;
1040 pointer left;
1041 pointer right;
1042 rbtree_colour colour;
1043
1044 rbtree_node_base() : parent(NULL), left(NULL), right(NULL), colour(rb_red) {}
1045};
1046
1047struct rbtree_header : public rbtree_node_base {
1048 std::size_t node_count;
1049
1050 rbtree_header() { reset(); }
1051
1052 void reset() {
1053 this->parent = NULL; // Root.
1054 this->left = NULL; // Leftmost.
1055 this->right = NULL; // Rightmost.
1056 node_count = 0;
1057 }
1058};
1059
1060template <typename T>
1061struct rbtree_node : public rbtree_node_base {
1062 typedef rbtree_node<T>* pointer;
1063 typedef const rbtree_node<T>* const_pointer;
1064
1065 T value;
1066
1067 rbtree_node& operator=(const rbtree_node&) { return *this; }
1068};
1069
1070template <typename T>
1071struct const_iterator_base {
1072 typedef typename rbtree_node<T>::pointer pointer;
1073 typedef T value_type;
1074 typedef std::ptrdiff_t difference_type;
1075
1076 const_iterator_base() : it_(NULL) {}
1077
1078 const_iterator_base(const pointer p) : it_(p) {}
1079
1080 bool operator==(const const_iterator_base& right) const {
1081 return it_ == right.it_;
1082 }
1083
1084 bool operator!=(const const_iterator_base& right) const {
1085 return it_ != right.it_;
1086 }
1087
1088 const_iterator_base& operator++() {
1089 if (it_) {
1090 if (it_->right != NULL) {
1091 for (it_ = static_cast<pointer>(it_->right); it_->left != NULL;
1092 it_ = static_cast<pointer>(it_->left));
1093 } else if (it_->parent != NULL) {
1094 pointer p = static_cast<pointer>(it_->parent);
1095
1096 for (; p && p->right == it_;) {
1097 it_ = p;
1098 p = static_cast<pointer>(p->parent);
1099 }
1100 it_ = p;
1101 } else
1102 it_ = NULL;
1103 }
1104 return *this;
1105 }
1106
1107 const_iterator_base operator++(int) {
1108 const const_iterator_base r(*this);
1109 operator++();
1110 return r;
1111 }
1112
1113 const T& operator*() const { return it_->value; }
1114
1115 const T* operator->() const { return &it_->value; }
1116
1117 operator pointer() const { return it_; }
1118
1119 protected:
1120 pointer it_;
1121};
1122
1123template <typename T>
1124struct iterator_base : public const_iterator_base<T> {
1125 typedef const_iterator_base<T> base_type;
1126 typedef typename base_type::pointer pointer;
1127 typedef typename base_type::value_type value_type;
1128 typedef typename base_type::difference_type difference_type;
1129
1130 iterator_base() : base_type(NULL) {}
1131
1132 iterator_base(const pointer p) : base_type(p) {}
1133
1134 T& operator*() const { return this->it_->value; }
1135
1136 T* operator->() const { return &this->it_->value; }
1137};
1138
1139template <typename Key, typename T>
1140class nemap {
1141 public:
1142 typedef Key key_type;
1143 typedef T mapped_type;
1144 typedef std::pair<const Key, T> value_type;
1145 typedef std::size_t size_type;
1146 typedef value_type& reference;
1147 typedef const value_type& const_reference;
1148 typedef value_type* pointer;
1149 typedef const value_type* const_pointer;
1150
1151 typedef iterator_base<value_type> iterator;
1152 typedef const_iterator_base<value_type> const_iterator;
1153
1154 nemap() { entire_.reset(); }
1155
1156 nemap(const nemap& right) { operator=(right); }
1157
1158 ~nemap() { erase_all_(entire_.parent); }
1159
1160 std::size_t size() const { return entire_.node_count; }
1161
1162 void clear() {
1163 erase_all_(entire_.parent);
1164 entire_.reset();
1165 }
1166
1167 nemap& operator=(const nemap& right) {
1168 clear();
1169
1170 if (this != &right && right.entire_.parent != NULL)
1171 entire_.parent = copy_nodes_(entire_.parent, right.entire_.parent, right);
1172
1173 return *this;
1174 }
1175
1176 mapped_type& operator[](const typename key_type::view_type key) {
1177 node_pointer p = find_(key);
1178
1179 return p->value.second;
1180 }
1181
1182 iterator begin() const {
1183 return iterator(static_cast<node_pointer>(entire_.left));
1184 }
1185
1186 iterator end() const { return iterator(NULL); }
1187
1188 void erase(const typename key_type::view_type key) {
1189 rbtree_node_base* node = entire_.parent;
1190
1191 for (; node;) {
1192 const int comp =
1193 key.compare(static_cast<node_pointer>(node)->value.first);
1194
1195 if (comp < 0)
1196 node = node->left;
1197 else if (comp > 0)
1198 node = node->right;
1199 else
1200 break;
1201 }
1202 erase_(node);
1203 }
1204
1205 void erase(iterator it) { erase_(it); }
1206
1207 iterator find(const typename key_type::view_type key) {
1208 rbtree_node_base* node = entire_.parent;
1209
1210 for (; node;) {
1211 const int comp =
1212 key.compare(static_cast<node_pointer>(node)->value.first);
1213
1214 if (comp < 0)
1215 node = node->left;
1216 else if (comp > 0)
1217 node = node->right;
1218 else
1219 break;
1220 }
1221 return iterator(static_cast<node_pointer>(node));
1222 }
1223
1224 private:
1225 typedef typename key_type::value_type char_type;
1226 typedef rbtree_node<value_type> node_type;
1227 typedef typename node_type::pointer node_pointer;
1228 typedef typename node_type::const_pointer const_node_pointer;
1229
1230 node_pointer find_(const json_internal_::view<char_type> key) {
1231 rbtree_node_base* node = entire_.parent;
1232 rbtree_node_base* parentnode = entire_.parent;
1233 int comp = 0;
1234
1235 for (; node;) {
1236 comp = key.compare(static_cast<node_pointer>(node)->value.first);
1237
1238 parentnode = node;
1239 if (comp < 0)
1240 node = node->left;
1241 else if (comp > 0)
1242 node = node->right;
1243 else
1244 return static_cast<node_pointer>(node);
1245 }
1246
1247 const node_pointer nn =
1248 static_cast<node_pointer>(std::malloc(sizeof(node_type)));
1249
1250 if (nn == NULL) throw std::bad_alloc();
1251
1252 ++entire_.node_count;
1253 nn->left = NULL;
1254 nn->right = NULL;
1255 new (&nn->value) value_type(key, mapped_type());
1256
1257 if (entire_.parent == NULL) {
1258 nn->parent = NULL;
1259 nn->colour = rb_black;
1260
1261 entire_.parent = nn;
1262 entire_.left = nn;
1263 entire_.right = nn;
1264 return nn;
1265 }
1266
1267 nn->parent = parentnode;
1268 nn->colour = rb_red;
1269
1270 if (comp < 0) {
1271 parentnode->left = nn;
1272 if (entire_.left == parentnode) entire_.left = nn;
1273 } else {
1274 parentnode->right = nn;
1275 if (entire_.right == parentnode) entire_.right = nn;
1276 }
1277
1278 rbtree_node_base* nn2 = nn;
1279
1280 while (nn2 != entire_.parent && nn2->parent->colour == rb_red) {
1281 rbtree_node_base* const pp = nn2->parent->parent;
1282
1283 if (nn2->parent == pp->left) {
1284 rbtree_node_base* const oo = pp->right;
1285
1286 if (oo && oo->colour == rb_red) {
1287 nn2->parent->colour = rb_black;
1288 oo->colour = rb_black;
1289 pp->colour = rb_red;
1290 nn2 = pp;
1291 } else {
1292 if (nn2 == nn2->parent->right) {
1293 nn2 = nn2->parent;
1294 rotate_left_(nn2);
1295 }
1296 nn2->parent->colour = rb_black;
1297 pp->colour = rb_red;
1298 rotate_right_(pp);
1299 }
1300 } else {
1301 rbtree_node_base* const oo = pp->left;
1302
1303 if (oo && oo->colour == rb_red) {
1304 nn2->parent->colour = rb_black;
1305 oo->colour = rb_black;
1306 pp->colour = rb_red;
1307 nn2 = pp;
1308 } else {
1309 if (nn2 == nn2->parent->left) {
1310 nn2 = nn2->parent;
1311 rotate_right_(nn2);
1312 }
1313 nn2->parent->colour = rb_black;
1314 pp->colour = rb_red;
1315 rotate_left_(pp);
1316 }
1317 }
1318 }
1319 entire_.parent->colour = rb_black;
1320
1321 return nn;
1322 }
1323
1324 void rotate_left_(rbtree_node_base* nc) {
1325 rbtree_node_base* const np = nc->right;
1326
1327 nc->right = np->left;
1328
1329 if (np->left != NULL) np->left->parent = nc;
1330
1331 np->parent = nc->parent;
1332
1333 if (nc == entire_.parent)
1334 entire_.parent = np;
1335 else if (nc == nc->parent->left)
1336 nc->parent->left = np;
1337 else
1338 nc->parent->right = np;
1339
1340 np->left = nc;
1341 nc->parent = np;
1342 }
1343
1344 void rotate_right_(rbtree_node_base* nc) {
1345 rbtree_node_base* const np = nc->left;
1346
1347 nc->left = np->right;
1348
1349 if (np->right != NULL) np->right->parent = nc;
1350
1351 np->parent = nc->parent;
1352
1353 if (nc == entire_.parent)
1354 entire_.parent = np;
1355 else if (nc == nc->parent->right)
1356 nc->parent->right = np;
1357 else
1358 nc->parent->left = np;
1359
1360 np->right = nc;
1361 nc->parent = np;
1362 }
1363
1364 rbtree_node_base* copy_nodes_(rbtree_node_base* pnode,
1365 const rbtree_node_base* const srcnode,
1366 const nemap& srctree) {
1367 const node_pointer nn =
1368 static_cast<node_pointer>(std::malloc(sizeof(node_type)));
1369
1370 if (nn == NULL) throw std::bad_alloc();
1371
1372 new (&nn->value)
1373 value_type(static_cast<const_node_pointer>(srcnode)->value);
1374
1375 nn->parent = pnode;
1376 nn->colour = srcnode->colour;
1377
1378 ++entire_.node_count;
1379
1380 if (srcnode->left)
1381 nn->left = copy_nodes_(nn, srcnode->left, srctree);
1382 else
1383 nn->left = NULL;
1384
1385 if (srcnode->right)
1386 nn->right = copy_nodes_(nn, srcnode->right, srctree);
1387 else
1388 nn->right = NULL;
1389
1390 if (srcnode == srctree.entire_.left) entire_.left = nn;
1391
1392 if (srcnode == srctree.entire_.right) entire_.right = nn;
1393
1394 return nn;
1395 }
1396
1397 void erase_all_(rbtree_node_base* const node) {
1398 if (node) {
1399 node_pointer enode = static_cast<node_pointer>(node);
1400
1401 erase_all_(enode->left);
1402 erase_all_(enode->right);
1403
1404 (&enode->value)->~value_type();
1405 std::free(enode);
1406 }
1407 }
1408
1409 void erase_(rbtree_node_base* const enode) {
1410 if (enode) {
1411 rbtree_node_base*& root = entire_.parent;
1412 rbtree_node_base*& leftmost = entire_.left;
1413 rbtree_node_base*& rightmost = entire_.right;
1414 rbtree_node_base* s = enode;
1415 rbtree_node_base* sc = NULL;
1416 rbtree_node_base* scp = NULL;
1417 rbtree_colour s_orgclr = s->colour;
1418
1419 if (enode->left == NULL)
1420 sc = enode->right;
1421 else if (enode->right == NULL)
1422 sc = enode->left;
1423 else {
1424 s = enode->right;
1425
1426 while (s->left) s = s->left;
1427
1428 s_orgclr = s->colour;
1429 sc = s->right;
1430 }
1431
1432 if (s == enode) {
1433 scp = s->parent;
1434
1435 if (sc) sc->parent = scp;
1436
1437 if (enode == root)
1438 root = sc;
1439 else if (enode == enode->parent->left)
1440 enode->parent->left = sc;
1441 else
1442 enode->parent->right = sc;
1443
1444 if (enode == leftmost) {
1445 if (enode->right == NULL)
1446 leftmost = enode->parent;
1447 else
1448 for (leftmost = sc; leftmost->left != NULL;
1449 leftmost = leftmost->left);
1450 }
1451
1452 if (enode == rightmost) {
1453 if (enode->left == NULL)
1454 rightmost = enode->parent;
1455 else
1456 for (rightmost = sc; rightmost->right != NULL;
1457 rightmost = rightmost->right);
1458 }
1459 } else {
1460 enode->left->parent = s;
1461 s->left = enode->left;
1462
1463 if (enode->right == s)
1464 scp = s;
1465 else {
1466 scp = s->parent;
1467
1468 if (sc) sc->parent = scp;
1469
1470 s->parent->left = sc;
1471 s->right = enode->right;
1472 enode->right->parent = s;
1473 }
1474
1475 if (enode == root)
1476 root = s;
1477 else if (enode == enode->parent->left)
1478 enode->parent->left = s;
1479 else
1480 enode->parent->right = s;
1481
1482 s->parent = enode->parent;
1483 s->colour = enode->colour;
1484 }
1485
1486 if (s_orgclr == rb_black) {
1487 while (sc != root && (sc == NULL || sc->colour == rb_black)) {
1488 if (sc == scp->left) {
1489 rbtree_node_base* sib = scp->right;
1490
1491 if (sib->colour == rb_red) {
1492 sib->colour = rb_black;
1493 scp->colour = rb_red;
1494 rotate_left_(scp);
1495 sib = scp->right;
1496 }
1497
1498 if ((sib->left == NULL || sib->left->colour == rb_black) &&
1499 (sib->right == NULL || sib->right->colour == rb_black)) {
1500 sib->colour = rb_red;
1501 sc = scp;
1502 scp = scp->parent;
1503 } else {
1504 if (sib->right == NULL || sib->right->colour == rb_black) {
1505 sib->left->colour = rb_black;
1506 sib->colour = rb_red;
1507 rotate_right_(sib);
1508 sib = scp->right;
1509 }
1510
1511 sib->colour = scp->colour;
1512 scp->colour = rb_black;
1513
1514 if (sib->right) sib->right->colour = rb_black;
1515
1516 rotate_left_(scp);
1517 break;
1518 }
1519 } else {
1520 rbtree_node_base* sib = scp->left;
1521
1522 if (sib->colour == rb_red) {
1523 sib->colour = rb_black;
1524 scp->colour = rb_red;
1525 rotate_right_(scp);
1526 sib = scp->left;
1527 }
1528
1529 if ((sib->right == NULL || sib->right->colour == rb_black) &&
1530 (sib->left == NULL || sib->left->colour == rb_black)) {
1531 sib->colour = rb_red;
1532 sc = scp;
1533 scp = scp->parent;
1534 } else {
1535 if (sib->left == NULL || sib->left->colour == rb_black) {
1536 sib->right->colour = rb_black;
1537 sib->colour = rb_red;
1538 rotate_left_(sib);
1539 sib = scp->left;
1540 }
1541
1542 sib->colour = scp->colour;
1543 scp->colour = rb_black;
1544
1545 if (sib->left) sib->left->colour = rb_black;
1546
1547 rotate_right_(scp);
1548 break;
1549 }
1550 }
1551 }
1552 if (sc) sc->colour = rb_black;
1553 }
1554
1555 node_pointer enode2 = static_cast<node_pointer>(enode);
1556
1557 (&enode2->value)->~value_type();
1558 std::free(enode2);
1559
1560 --entire_.node_count;
1561 }
1562 }
1563
1564 rbtree_header entire_;
1565};
1566// nemap
1567
1568struct utf8tag {};
1569struct utf16tag {};
1570
1571template <bool, typename T>
1572struct enable_if {};
1573template <typename T>
1574struct enable_if<true, T> {
1575 typedef T type;
1576};
1577template <typename IntType, typename RetType>
1578struct enable_if_integer
1579 : enable_if<std::numeric_limits<IntType>::is_integer, RetType> {};
1580
1581template <typename charT, typename utftype>
1582class jsonnode {
1583 public:
1584 enum value_type {
1585 array,
1586 object,
1587 number,
1588 string,
1589 boolean,
1590 null,
1591 unassigned,
1592 fallback
1593 };
1594
1595 typedef std::basic_string<charT>
1596 string_type; // For backwards-compatibility.
1597 typedef charT char_type;
1598
1599 typedef nestring<charT> nstring_type;
1600 typedef json_internal_::view<charT> sview_type;
1601
1602 struct psnum {
1603 double value;
1604 int precision;
1605
1606 psnum(const double n, const int p = -6) : value(n), precision(p) {}
1607 };
1608
1609 private:
1610 explicit jsonnode(const value_type v)
1611 : type_(v) // For the fallback node.
1612 {}
1613
1614 public:
1615 jsonnode() : type_(unassigned) {}
1616
1617 jsonnode(const jsonnode& right) : type_(right.type_) {
1618 if (this != &right && !is_fallback() && !right.is_fallback()) {
1619 if (type_ == array) {
1620 array_ = new array_type(*right.array_);
1621 } else if (type_ == object) {
1622 object_ = new object_type(*right.object_);
1623 } else if (type_ == number || type_ == string) {
1624 string_ = new strnum_type(*right.string_);
1625 } else if (type_ == boolean)
1626 boolvalue_ = right.boolvalue_;
1627 }
1628 }
1629
1630 template <typename StringT>
1631 explicit jsonnode(const StringT& s) : type_(unassigned) {
1632 if (!parse(s)) clear();
1633 }
1634
1635 template <typename StringT>
1636 jsonnode(const StringT& s, json_error& e) : type_(unassigned) {
1637 parse(s, e);
1638 }
1639
1640 template <typename Iterator>
1641 jsonnode(Iterator begin, const Iterator end) : type_(unassigned) {
1642 if (!parse(begin, end)) clear();
1643 }
1644
1645 template <typename Iterator>
1646 jsonnode(Iterator begin, const Iterator end, json_error& e)
1647 : type_(unassigned) {
1648 parse(begin, end, e);
1649 }
1650
1651 ~jsonnode() {
1652 if (type_ < boolean) destroy_node_();
1653 }
1654
1655 void clear() {
1656 if (!is_fallback()) {
1657 destroy_node_();
1658 type_ = unassigned;
1659 }
1660 }
1661
1662 // Types.
1663
1664 value_type type() const { return static_cast<value_type>(type_); }
1665
1666 bool is_num() const { return type_ == number; }
1667 bool is_str() const { return type_ == string; }
1668 bool is_bool() const { return type_ == boolean; }
1669 bool is_true() const { return type_ == boolean && boolvalue_; }
1670 bool is_false() const { return type_ == boolean && !boolvalue_; }
1671 bool is_null() const { return type_ == null; }
1672 bool is_array() const { return type_ == array; }
1673 bool is_object() const { return type_ == object; }
1674 bool is_unassigned() const { return type_ == unassigned; }
1675 bool is_fallback() const { return type_ == fallback; }
1676 bool is_assigned() const { return type_ < unassigned; }
1677 bool has_value() const { return type_ < unassigned; }
1678
1679 bool exists() const { return type_ != fallback; }
1680
1681 jsonnode& operator=(const jsonnode& right) {
1682 if (this != &right && !is_fallback() && !right.is_fallback()) {
1683 const int newtype = right.type_;
1684
1685 if (newtype == array) {
1686 array_type* const newarray = new array_type(*right.array_);
1687 destroy_node_();
1688 array_ = newarray;
1689 } else if (newtype == object) {
1690 object_type* const newobject = new object_type(*right.object_);
1691 destroy_node_();
1692 object_ = newobject;
1693 } else if (newtype == number || newtype == string) {
1694 strnum_type* const newstring = new strnum_type(*right.string_);
1695 destroy_node_();
1696 string_ = newstring;
1697 } else if (newtype == boolean) {
1698 const bool bv = right.boolvalue_;
1699 destroy_node_();
1700 boolvalue_ = bv;
1701 }
1702 type_ = newtype;
1703 }
1704 return *this;
1705 }
1706
1707 jsonnode& operator=(const double d) { return set_num(d, -6); }
1708
1709 jsonnode& operator=(const psnum& n) { return set_num(n.value, n.precision); }
1710
1711 template <typename IntType>
1712 typename enable_if_integer<IntType, jsonnode>::type& operator=(
1713 const IntType i) {
1714 return set_num(static_cast<double>(i), -6);
1715 }
1716
1717 jsonnode& operator=(const bool b) { return set_bool(b); }
1718
1719 jsonnode& operator=(const sview_type s) { return set_str(s); }
1720
1721 jsonnode& operator=(const char_type* const p) { return set_str(p); }
1722
1723 jsonnode& operator=(const value_type v) {
1724 switch (v) {
1725 case array:
1726 return empty_array();
1727 case object:
1728 return empty_object();
1729 case number:
1730 return set_num(0);
1731 case string:
1732 return set_str(emptystr_, emptystr_);
1733 case boolean:
1734 return set_bool(false);
1735 // case null, unassigned, fallback.
1736 default:;
1737 }
1738 return set_null();
1739 }
1740
1741 template <typename StringT>
1742 bool parse(const StringT& s) {
1743 json_error e;
1744 return parse(s, e);
1745 }
1746
1747 template <typename StringT>
1748 bool parse(const StringT& s, json_error& e) {
1749 if (!is_fallback()) {
1750 return parse(s.data(), s.data() + s.size(), e);
1751 }
1752 return e.clear_();
1753 }
1754
1755 template <typename charT2>
1756 bool parse(const charT2* const p) {
1757 json_error e;
1758 return parse(p, e);
1759 }
1760
1761 template <typename charT2>
1762 bool parse(const charT2* const p, json_error& e) {
1763 if (!is_fallback()) {
1764 const charT2* const end = p + std::char_traits<charT2>::length(p);
1765 return parse(p, end, e);
1766 }
1767 return e.clear_();
1768 }
1769
1770 template <typename Iterator>
1771 bool parse(Iterator begin, const Iterator end) {
1772 json_error e;
1773 return parse(begin, end, e);
1774 }
1775
1776 template <typename Iterator>
1777 bool parse(Iterator begin, const Iterator end, json_error& e) {
1778 if (is_fallback()) return e.clear_();
1779
1780 const Iterator orgbegin = begin;
1781
1782 destroy_node_();
1783 type_ = unassigned;
1784 begin = skip_spaces_(begin, end);
1785
1786 e.code_ = parse_value_(begin, end);
1787 e.pos_ = e.code_ ? std::distance(orgbegin, begin) : 0;
1788
1789 return e.code_ == 0;
1790 }
1791
1792 std::basic_string<char_type> to_string() const {
1793 std::basic_string<char_type> out;
1794 value_to_string_(out);
1795 return out;
1796 }
1797 std::basic_string<char_type> stringify() const {
1798 std::basic_string<char_type> out;
1799 value_to_string_(out);
1800 return out;
1801 }
1802
1803 template <typename StringT>
1804 StringT to_string() const {
1805 StringT out;
1806 value_to_string_(out);
1807 return out;
1808 }
1809 template <typename StringT>
1810 StringT stringify() const {
1811 StringT out;
1812 value_to_string_(out);
1813 return out;
1814 }
1815
1816 template <typename StringT>
1817 void to_string(StringT& out) const {
1818 out.clear();
1819 value_to_string_(out);
1820 }
1821 template <typename StringT>
1822 void stringify(StringT& out) const {
1823 out.clear();
1824 value_to_string_(out);
1825 }
1826
1827 // For number.
1828
1829 jsonnode& set_num(const double d, const int precision = -6) {
1830 if (is_fallback()) return fallback_node_;
1831
1832 if (type_ != number) {
1833 destroy_node_();
1834 type_ = number;
1835 string_ = new strnum_type();
1836 }
1837
1838 string_->num = d;
1839 string_->str.assign(ctl::to_string<nstring_type>(d, 'f', precision));
1840 return *this;
1841 }
1842
1843 // For string.
1844
1845 jsonnode& set_str(const sview_type s) {
1846 return set_str(s.data(), s.data() + s.size());
1847 }
1848
1849 template <typename Iterator>
1850 jsonnode& set_str(Iterator begin, const Iterator end) {
1851 if (is_fallback()) return fallback_node_;
1852
1853 if (type_ != string) {
1854 destroy_node_();
1855 type_ = string;
1856 string_ = new strnum_type();
1857 }
1858 string_->str.assign(begin, end);
1859
1860 return *this;
1861 }
1862
1863 // For array.
1864
1865 bool exists(const std::size_t no) const {
1866 return !is_fallback() && n(no) != &fallback_node_;
1867 }
1868
1869 const jsonnode& operator[](const std::size_t no) const {
1870 const jsonnode* const node = n(no);
1871 return *node;
1872 }
1873 jsonnode& operator[](const std::size_t no) {
1874 jsonnode* const node = n(no);
1875 return *node;
1876 }
1877
1878 const jsonnode* n(const std::size_t no) const {
1879 if (type_ == array) {
1880 if (no < array_->size()) return &(*array_)[no];
1881 }
1882 return &fallback_node_;
1883 }
1884 jsonnode* n(const std::size_t no) {
1885 if (type_ == array) {
1886 if (no < array_->size()) return &(*array_)[no];
1887 }
1888 return &fallback_node_;
1889 }
1890
1891 jsonnode& operator()(const std::size_t no) {
1892 if (is_fallback()) return fallback_node_;
1893
1894 if (type_ == array) {
1895 if (no >= array_->size()) array_->resize(no + 1);
1896 } else {
1897 destroy_node_();
1898 type_ = array;
1899 array_ = new array_type();
1900 array_->resize(no + 1);
1901 }
1902 return (*array_)[no];
1903 }
1904
1905 bool erase(const std::size_t no) {
1906 if (type_ == array && no < array_->size()) {
1907 array_->erase(no);
1908 return true;
1909 }
1910 return false;
1911 }
1912
1913 template <typename ValueType>
1914 bool insert(const std::size_t no, const ValueType& right) {
1915 if (type_ == array && no <= array_->size()) {
1916 jsonnode backup;
1917 backup = right;
1918 array_->insert(no).move_(backup);
1919 return true;
1920 }
1921 return false;
1922 }
1923
1924 template <typename ValueType>
1925 void push_back(const ValueType& right) {
1926 if (type_ == array) {
1927 jsonnode backup; // Consideration for right == *this.
1928 backup = right;
1929 array_->push_back().move_(backup);
1930 }
1931 }
1932
1933 jsonnode& empty_array() {
1934 if (is_fallback()) return fallback_node_;
1935
1936 if (type_ == array) {
1937 array_->clear();
1938 } else {
1939 destroy_node_();
1940 type_ = array;
1941 array_ = new array_type();
1942 }
1943 return *this;
1944 }
1945
1946 // For array and object.
1947
1948 std::size_t size() const {
1949 if (type_ == array)
1950 return array_->size();
1951 else if (type_ == object)
1952 return object_->objmap.size();
1953
1954 return 0;
1955 }
1956
1957 // For object.
1958
1959 bool exists(const sview_type key) const {
1960 return !is_fallback() && n(key) != &fallback_node_;
1961 }
1962
1963 const jsonnode& operator[](const sview_type key) const {
1964 const jsonnode* const node = n(key);
1965 return *node;
1966 }
1967 jsonnode& operator[](const sview_type key) {
1968 jsonnode* const node = n(key);
1969 return *node;
1970 }
1971
1972 const jsonnode* n(const sview_type key) const {
1973 if (type_ == object) {
1974 const typename object_core::const_iterator it = object_->objmap.find(key);
1975
1976 if (it != object_->objmap.end()) return &it->second;
1977 }
1978 return &fallback_node_;
1979 }
1980 jsonnode* n(const sview_type key) {
1981 if (type_ == object) {
1982 const typename object_core::iterator it = object_->objmap.find(key);
1983
1984 if (it != object_->objmap.end()) return &it->second;
1985 }
1986 return &fallback_node_;
1987 }
1988
1989 jsonnode& operator()(const sview_type key) {
1990 if (is_fallback()) return fallback_node_;
1991
1992 if (type_ == object) {
1993 const typename object_core::iterator it = object_->objmap.find(key);
1994
1995 if (it != object_->objmap.end()) return it->second;
1996
1997 append_keyinfo_(object_->order, key, utftype());
1998 return object_->objmap[key];
1999 }
2000
2001 destroy_node_();
2002 type_ = object;
2003 object_ = new object_type();
2004 append_keyinfo_(object_->order, key, utftype());
2005 return object_->objmap[key];
2006 }
2007
2008 bool erase(const sview_type key) {
2009 if (type_ == object) {
2010 const typename object_core::iterator it = object_->objmap.find(key);
2011
2012 if (it != object_->objmap.end()) {
2013 object_->objmap.erase(it);
2014 remove_orderkey_(key);
2015 return true;
2016 }
2017 }
2018 return false;
2019 }
2020
2021 template <typename ValueType>
2022 bool insert(const sview_type inspos, const sview_type newkey,
2023 const ValueType& newelem) {
2024 if (type_ == object && newkey != inspos) {
2025 strsize_type newkeyindex = object_->order.size();
2026 strsize_type insposindex = newkeyindex;
2027
2028 for (strsize_type i = 0; (i < object_->order.size()) &&
2029 (newkeyindex == object_->order.size() ||
2030 insposindex == object_->order.size());) {
2031 const strsize_type keylen = get_keylen_(&object_->order[i], utftype());
2032 strsize_type base = i + keylen_size;
2033
2034 if (keylen == newkey.size() &&
2035 object_->order.compare(base, keylen, newkey, 0, keylen) == 0)
2036 newkeyindex = i;
2037 else if (keylen == inspos.size() &&
2038 object_->order.compare(base, keylen, inspos, 0, keylen) == 0)
2039 insposindex = i;
2040
2041 i = base + keylen;
2042 }
2043
2044 if (insposindex < object_->order.size()) {
2045 const strsize_type newkeylen = newkey.size();
2046 jsonnode backup;
2047
2048 backup = newelem;
2049
2050 if (newkeyindex < object_->order.size()) {
2051 const strsize_type remlen = keylen_size + newkeylen;
2052
2053 if ((newkeyindex + remlen) == insposindex)
2054 goto UPDATE;
2055 else {
2056 object_->order.erase(newkeyindex, remlen);
2057 if (newkeyindex < insposindex) insposindex -= remlen;
2058 }
2059 }
2060 {
2061 nstring_type len_newkey;
2062
2063 append_keyinfo_(len_newkey, newkey, utftype());
2064 object_->order.insert(insposindex, len_newkey);
2065 }
2066
2067 UPDATE:
2068 object_->objmap[newkey].move_(backup);
2069 return true;
2070 }
2071 }
2072 return false;
2073 }
2074
2075 template <typename ValueType>
2076 bool push_back(const sview_type key, const ValueType& right) {
2077 if (type_ == object) {
2078 jsonnode backup; // Consideration for right == *this.
2079
2080 backup = right;
2081
2082 for (strsize_type pos = 0;
2083 (pos + sizeof(keylen_type)) < object_->order.size();) {
2084 const strsize_type keylen =
2085 get_keylen_(&object_->order[pos], utftype());
2086 const strsize_type keypos = pos + keylen_size;
2087
2088 if (keylen == key.size()) {
2089 for (strsize_type i = 0;; ++i) {
2090 if (i == keylen) {
2091 if (keypos + keylen == object_->order.size()) goto PUSH_VALUE;
2092
2093 object_->order.erase(keypos - keylen_size, keylen_size + keylen);
2094 goto PUSH_KEY;
2095 }
2096 if (object_->order[keypos + i] != key[i]) break;
2097 }
2098 }
2099 pos = keypos + keylen;
2100 }
2101
2102 PUSH_KEY:
2103 append_keyinfo_(object_->order, key, utftype());
2104
2105 PUSH_VALUE:
2106 object_->objmap[key].move_(backup);
2107
2108 return true;
2109 }
2110 return false;
2111 }
2112
2113 jsonnode& empty_object() {
2114 if (is_fallback()) return fallback_node_;
2115
2116 if (type_ == object) {
2117 object_->objmap.clear();
2118 object_->order.clear();
2119 } else {
2120 destroy_node_();
2121 type_ = object;
2122 object_ = new object_type();
2123 }
2124 return *this;
2125 }
2126
2127 double num() const {
2128 if (type_ == number) return string_->num;
2129 if (type_ == boolean) return static_cast<double>(boolvalue_);
2130 return 0.0;
2131 }
2132
2133 template <typename NumType>
2134 NumType num() const {
2135 return static_cast<NumType>(
2136 type_ == number ? string_->num : (type_ == boolean ? boolvalue_ : 0));
2137 }
2138
2139 sview_type numstr_view() const {
2140 static const char_type ltrue[] = {0x74, 0x72, 0x75, 0x65, 0}; // "true"
2141 static const char_type lfalse[] = {0x66, 0x61, 0x6C,
2142 0x73, 0x65, 0}; // "false"
2143 static const char_type lnull[] = {0x6E, 0x75, 0x6C, 0x6C, 0}; // "null"
2144
2145 if (type_ == number) return string_->str;
2146 if (type_ == boolean) return boolvalue_ ? ltrue : lfalse;
2147 if (type_ == null) return lnull;
2148 return sview_type(lnull, 0);
2149 }
2150
2151 std::basic_string<char_type> numstr() const {
2152 const sview_type sv = numstr_view();
2153 return std::basic_string<char_type>(sv.data(), sv.size());
2154 }
2155
2156 template <typename StringT>
2157 void numstr(StringT& out) const {
2158 typedef typename StringT::value_type dchar_type;
2159 static const dchar_type ltrue[] = {0x74, 0x72, 0x75, 0x65, 0}; // "true"
2160 static const dchar_type lfalse[] = {0x66, 0x61, 0x6C,
2161 0x73, 0x65, 0}; // "false"
2162 static const dchar_type lnull[] = {0x6E, 0x75, 0x6C, 0x6C, 0}; // "null"
2163
2164 out.clear();
2165 if (type_ == number) {
2166 out.append(string_->str.begin(), string_->str.end());
2167 } else if (type_ == boolean)
2168 out.append(boolvalue_ ? ltrue : lfalse);
2169 else if (type_ == null)
2170 out.append(lnull);
2171 }
2172
2173 sview_type str_view() const {
2174 if (type_ == string) return sview_type(string_->str);
2175
2176 return sview_type(emptystr_, 0);
2177 }
2178
2179 std::basic_string<char_type> str() const {
2180 if (type_ == string) return string_->str;
2181
2182 return std::basic_string<char_type>();
2183 }
2184
2185 template <typename StringT>
2186 void str(StringT& out) const {
2187 out.clear();
2188 if (type_ == string) {
2189 out.append(string_->str.begin(), string_->str.end());
2190 }
2191 }
2192
2193 // For boolean, null.
2194
2195 jsonnode& set_bool(const bool b) {
2196 if (is_fallback()) return fallback_node_;
2197
2198 if (type_ != boolean) {
2199 destroy_node_();
2200 type_ = boolean;
2201 }
2202 boolvalue_ = b;
2203 return *this;
2204 }
2205
2206 jsonnode& set_null() {
2207 if (is_fallback()) return fallback_node_;
2208
2209 if (type_ != null) {
2210 destroy_node_();
2211 type_ = null;
2212 }
2213 return *this;
2214 }
2215
2216 jsonnode allkeys() const {
2217 jsonnode out;
2218 allkeys(out);
2219 return out;
2220 }
2221
2222 void allkeys(jsonnode& out) const {
2223 if (is_fallback()) {
2224 } else if (type_ == object) {
2225 const std::size_t objsize = object_->objmap.size();
2226
2227 if (out.type_ != array) {
2228 out.destroy_node_();
2229 out.type_ = array;
2230 out.array_ = new array_type();
2231 }
2232 out.array_->resize(objsize);
2233
2234 strsize_type pos = 0;
2235
2236 for (std::size_t i = 0;
2237 i < objsize && (pos + keylen_size) < object_->order.size(); ++i) {
2238 jsonnode& elem = (*out.array_)[i];
2239 const strsize_type keylen =
2240 get_keylen_(&object_->order[pos], utftype());
2241
2242 if (elem.type_ != string) {
2243 elem.destroy_node_();
2244 elem.type_ = string;
2245 elem.string_ = new strnum_type();
2246 }
2247 pos += keylen_size;
2248 elem.string_->str.assign(object_->order.view(pos, keylen));
2249 pos += keylen;
2250 }
2251 return;
2252 }
2253 out.clear();
2254 }
2255
2256 private:
2257 typedef typename nstring_type::size_type strsize_type;
2258 typedef unsigned int keylen_type;
2259
2260 typedef nevector<jsonnode> array_type;
2261 typedef nemap<nstring_type, jsonnode> object_core;
2262
2263 struct object_type {
2264 object_core objmap;
2265 nstring_type order;
2266 };
2267
2268 struct strnum_type {
2269 double num;
2270 nstring_type str;
2271 };
2272
2273 static const std::size_t keylen_size_tmp =
2274 sizeof(keylen_type) / sizeof(char_type) +
2275 ((sizeof(keylen_type) % sizeof(char_type)) ? 1 : 0);
2276 static const std::size_t keylen_size =
2277 keylen_size_tmp >= 2 ? keylen_size_tmp : 2;
2278
2279 template <typename ForwardIterator>
2280 inline ForwardIterator skip_spaces_(ForwardIterator begin,
2281 const ForwardIterator end) {
2282 for (; begin != end && (*begin == 0x20 || *begin == 0x09 ||
2283 *begin == 0x0a || *begin == 0x0d);
2284 ++begin);
2285
2286 return begin;
2287 }
2288
2289 template <typename utftag>
2290 void append_keyinfo_(nstring_type& order, const sview_type add,
2291 const utftag) const {
2292 const keylen_type size = static_cast<keylen_type>(add.size());
2293 const strsize_type base = order.size();
2294
2295 order.resize(base + keylen_size);
2296 std::memcpy(&order[base], &size, sizeof(keylen_type));
2297 order.append(add);
2298 }
2299 void append_keyinfo_(nstring_type& order, const sview_type add,
2300 const utf16tag) const {
2301 const keylen_type size = static_cast<keylen_type>(add.size());
2302 strsize_type i = order.size();
2303
2304 order.resize(i + keylen_size);
2305 order[i++] = static_cast<charT>(size & 0xffff);
2306 order[i] = static_cast<charT>(((size >> 8) >> 8) & 0xffff);
2307 order.append(add);
2308 }
2309
2310 template <typename utftag>
2311 strsize_type get_keylen_(const charT* const p, const utftag) const {
2312 keylen_type size;
2313 std::memcpy(&size, p, sizeof(keylen_type));
2314 return size;
2315 }
2316 strsize_type get_keylen_(const charT* const p, const utf16tag) const {
2317 return static_cast<strsize_type>(((p[0] & 0xffff)) |
2318 (((p[1] & 0xffff) << 8) << 8));
2319 }
2320
2321 // UTF-8 -> UTF-8.
2322
2323 template <typename ForwardIterator, typename UTFtag>
2324 bool parse_string_(nstring_type* const str, ForwardIterator& begin,
2325 const ForwardIterator end, const UTFtag) {
2326 ForwardIterator prevbegin = begin;
2327 unsigned long prev = 0ul;
2328
2329 for (; begin != end;) {
2330 if (*begin == 0x22) // '"'
2331 {
2332 if (prevbegin != begin) str->append(prevbegin, begin);
2333
2334 begin = skip_spaces_(++begin, end);
2335 return true;
2336 }
2337
2338 if (*begin == 0x5C) // '\\'
2339 {
2340 if (++begin == end) break;
2341
2342 char_type nch = *begin;
2343
2344 switch (nch) {
2345 case 0x22: // " quotation mark U+0022
2346 case 0x5c: // \ reverse solidus U+005C
2347 case 0x2f: // / solidus U+002F
2348 break;
2349
2350 case 0x62: // b backspace U+0008
2351 nch = 0x08;
2352 break;
2353
2354 case 0x66: // f form feed U+000C
2355 nch = 0x0c;
2356 break;
2357
2358 case 0x6e: // n line feed U+000A
2359 nch = 0x0a;
2360 break;
2361
2362 case 0x72: // r carriage return U+000D
2363 nch = 0x0d;
2364 break;
2365
2366 case 0x74: // t tab U+0009
2367 nch = 0x09;
2368 break;
2369
2370 case 0x75: // uXXXX U+XXXX
2371 {
2372 ForwardIterator upos = begin;
2373 unsigned long ucp = parse_4hexdigits_(begin, end);
2374
2375 if (ucp < 0x10000ul) {
2376 ++begin;
2377
2378 if (prev && ucp >= 0xDC00ul && ucp <= 0xDFFFul) {
2379 ucp = ((ucp & 0x3FFul) | ((prev & 0x3FFul) << 10)) + 0x10000;
2380
2381 (*str)[str->size() - 3] =
2382 static_cast<char_type>(((ucp >> 18) & 7) | 0xf0);
2383 (*str)[str->size() - 2] =
2384 static_cast<char_type>(((ucp >> 12) & 0x3f) | 0x80);
2385 (*str)[str->size() - 1] =
2386 static_cast<char_type>(((ucp >> 6) & 0x3f) | 0x80);
2387 str->push_back(static_cast<char_type>((ucp & 0x3f) | 0x80));
2388 prev = 0ul;
2389 } else {
2390 prev = 0ul;
2391
2392 if (ucp < 0x80ul) {
2393 str->append(prevbegin, upos);
2394 (*str)[str->size() - 1] = static_cast<char_type>(ucp);
2395 } else if (ucp < 0x800ul) {
2396 ++upos;
2397 str->append(prevbegin, upos);
2398 (*str)[str->size() - 2] =
2399 static_cast<char_type>(((ucp >> 6) & 0x1f) | 0xc0);
2400 (*str)[str->size() - 1] =
2401 static_cast<char_type>((ucp & 0x3f) | 0x80);
2402 } else {
2403 ++upos;
2404 ++upos;
2405 str->append(prevbegin, upos);
2406 (*str)[str->size() - 3] =
2407 static_cast<char_type>(((ucp >> 12) & 0x0f) | 0xe0);
2408 (*str)[str->size() - 2] =
2409 static_cast<char_type>(((ucp >> 6) & 0x3f) | 0x80);
2410 (*str)[str->size() - 1] =
2411 static_cast<char_type>((ucp & 0x3f) | 0x80);
2412 if ((ucp & 0xFC00ul) == 0xD800ul) prev = ucp;
2413 }
2414 }
2415 prevbegin = begin;
2416 continue;
2417 }
2418 }
2419 // "\u" not followed by four hexdigits.
2420 prev = 0ul;
2421 continue;
2422
2423 default:
2424 prev = 0ul;
2425 ++begin;
2426 continue;
2427 }
2428
2429 str->append(prevbegin, begin);
2430 (*str)[str->size() - 1] = nch;
2431
2432 prev = 0ul;
2433 prevbegin = ++begin;
2434 continue;
2435 }
2436 ++begin;
2437 }
2438 str->clear();
2439 return false;
2440 }
2441
2442 // UTF-8 -> UTF-16.
2443
2444 template <typename ForwardIterator>
2445 bool parse_string_(nstring_type* const str, ForwardIterator& begin,
2446 const ForwardIterator end, const utf16tag) {
2447 ForwardIterator prevbegin = begin;
2448
2449 for (; begin != end;) {
2450 if (*begin == 0x22) // '"'
2451 {
2452 if (prevbegin != begin) str->append(prevbegin, begin);
2453
2454 begin = skip_spaces_(++begin, end);
2455 return true;
2456 }
2457
2458 if (*begin == 0x5C) // '\\'
2459 {
2460 if (++begin == end) break;
2461
2462 char_type nch = *begin;
2463
2464 switch (nch) {
2465 case 0x22: // " quotation mark U+0022
2466 case 0x5c: // \ reverse solidus U+005C
2467 case 0x2f: // / solidus U+002F
2468 break;
2469
2470 case 0x62: // b backspace U+0008
2471 nch = 0x08;
2472 break;
2473
2474 case 0x66: // f form feed U+000C
2475 nch = 0x0c;
2476 break;
2477
2478 case 0x6e: // n line feed U+000A
2479 nch = 0x0a;
2480 break;
2481
2482 case 0x72: // r carriage return U+000D
2483 nch = 0x0d;
2484 break;
2485
2486 case 0x74: // t tab U+0009
2487 nch = 0x09;
2488 break;
2489
2490 case 0x75: // uXXXX U+XXXX
2491 {
2492 ForwardIterator upos = begin;
2493 unsigned long ucp = parse_4hexdigits_(begin, end);
2494
2495 if (ucp < 0x10000ul) {
2496 ++begin;
2497
2498 str->append(prevbegin, upos);
2499 (*str)[str->size() - 1] = static_cast<char_type>(ucp);
2500 prevbegin = begin;
2501 }
2502 }
2503 // "\u" not followed by four hexdigits.
2504 continue;
2505
2506 default:
2507 ++begin;
2508 continue;
2509 }
2510
2511 str->append(prevbegin, begin);
2512 (*str)[str->size() - 1] = nch;
2513
2514 prevbegin = ++begin;
2515 continue;
2516 } else if (*begin & 0x80) {
2517 unsigned long ch = *begin & 0xff;
2518
2519 if (ch >= 0xc2) {
2520 if ((ch & 0x20) == 0) // 2 octets?
2521 {
2522 if (++begin != end && (*begin & 0xc0) == 0x80) // 2nd octet.
2523 {
2524 ch = ((ch << 6) & 0x7c0) | (*begin & 0x3f);
2525
2526 str->append(prevbegin, begin);
2527 (*str)[str->size() - 1] = static_cast<char_type>(ch);
2528 prevbegin = ++begin;
2529 continue;
2530 }
2531 } else if ((ch & 0x10) == 0) // 3 octets?
2532 {
2533 if (++begin != end && (*begin & 0xc0) == 0x80) // 2nd octet.
2534 {
2535 const ForwardIterator tmpend = begin;
2536
2537 ch = (ch << 8) | (*begin & 0xff);
2538
2539 if (ch >= 0xe0a0) // E0A080..
2540 {
2541 if (++begin != end && (*begin & 0xc0) == 0x80) // 3rd octet.
2542 {
2543 ch = ((ch << 4) & 0xf000) | ((ch << 6) & 0xfc0) |
2544 (*begin & 0x3f);
2545
2546 str->append(prevbegin, tmpend);
2547 (*str)[str->size() - 1] = static_cast<char_type>(ch);
2548 prevbegin = ++begin;
2549 continue;
2550 }
2551 }
2552 }
2553 } else if (ch >= 0xf0 && ch <= 0xf4) // 4 octets?
2554 {
2555 if (++begin != end && (*begin & 0xc0) == 0x80) // 2nd octet.
2556 {
2557 ch = (ch << 8) | (*begin & 0xff);
2558
2559 if (ch >= 0xf090 && ch <= 0xf48f) // F0908080..F48FBFBF.
2560 {
2561 if (++begin != end && (*begin & 0xc0) == 0x80) // 3rd octet.
2562 {
2563 const ForwardIterator tmpend = begin;
2564
2565 ch = ((ch << 4) & 0x7000) | ((ch << 6) & 0xfc0) |
2566 (*begin & 0x3f);
2567
2568 if (++begin != end && (*begin & 0xc0) == 0x80) // 4th octet.
2569 {
2570 ch = ((ch << 6) | (*begin & 0x3f)) - 0x10000;
2571
2572 str->append(prevbegin, tmpend);
2573 (*str)[str->size() - 2] =
2574 static_cast<char_type>(0xd800 | (ch >> 10));
2575 (*str)[str->size() - 1] =
2576 static_cast<char_type>(0xdc00 | (ch & 0x3ff));
2577 prevbegin = ++begin;
2578 continue;
2579 }
2580 }
2581 }
2582 }
2583 }
2584 // F5..FF
2585 }
2586 // 80..C1
2587 break;
2588 }
2589 ++begin;
2590 }
2591 str->clear();
2592 return false;
2593 }
2594
2595 template <typename ForwardIterator>
2596 int parse_value_(ForwardIterator& begin, const ForwardIterator end) {
2597 int ecode = json_error::ec_no_error;
2598
2599 if (begin != end) {
2600 if (*begin == 0x5B) // '['
2601 {
2602 array_ = new array_type();
2603 type_ = array;
2604 begin = skip_spaces_(++begin, end);
2605
2606 for (;;) {
2607 if (begin == end) {
2608 ecode = json_error::ec_array;
2609 break;
2610 }
2611
2612 if (*begin == 0x5D) // ']'
2613 {
2614 begin = skip_spaces_(++begin, end);
2615 return 0;
2616 }
2617
2618 array_->push_back(jsonnode());
2619 ecode = array_->back().parse_value_(begin, end);
2620 if (ecode) break;
2621
2622 if (begin != end && *begin == 0x2C) // ','
2623 begin = skip_spaces_(++begin, end);
2624 }
2625 return ecode;
2626 } else if (*begin == 0x7B) // '{'
2627 {
2628 nstring_type key;
2629
2630 object_ = new object_type();
2631 type_ = object;
2632 begin = skip_spaces_(++begin, end);
2633
2634 for (;;) {
2635 if (begin == end) {
2636 ecode = json_error::ec_object;
2637 break;
2638 }
2639
2640 if (*begin == 0x7D) // '}'
2641 {
2642 begin = skip_spaces_(++begin, end);
2643 return 0;
2644 }
2645
2646 if (*begin == 0x22) // '"', key.
2647 {
2648 key.clear();
2649 parse_string_(&key, ++begin, end, utftype());
2650
2651 if (key.size() == 0) {
2652 ecode = json_error::ec_object_name;
2653 break;
2654 }
2655
2656 const typename object_core::iterator it = object_->objmap.find(key);
2657 jsonnode* newnode;
2658
2659 if (it == object_->objmap.end()) {
2660 append_keyinfo_(object_->order, key, utftype());
2661 newnode = &object_->objmap[key];
2662 } else {
2663 it->second.destroy_node_();
2664 it->second.type_ = unassigned;
2665 newnode = &it->second;
2666 }
2667
2668 if (begin == end || *begin != 0x3A) // ':'
2669 {
2670 ecode = json_error::ec_no_colon;
2671 break;
2672 }
2673 begin = skip_spaces_(++begin, end);
2674
2675 ecode = newnode->parse_value_(begin, end);
2676 if (ecode) break;
2677
2678 if (begin != end && *begin == 0x2C) // ','
2679 begin = skip_spaces_(++begin, end);
2680 }
2681 // else if (*begin == ',')
2682 else {
2683 ecode = json_error::ec_object;
2684 break;
2685 }
2686 }
2687 return ecode;
2688 } else if (*begin == 0x22) // '"'
2689 {
2690 string_ = new strnum_type();
2691
2692 if (parse_string_(&string_->str, ++begin, end, utftype())) {
2693 type_ = string;
2694 return 0;
2695 }
2696 ecode = json_error::ec_string;
2697 delete string_;
2698 } else if (*begin == 0x74) // 't'
2699 {
2700 if (++begin != end && *begin == 0x72) // 'r'
2701 if (++begin != end && *begin == 0x75) // 'u'
2702 if (++begin != end && *begin == 0x65) // 'e'
2703 {
2704 ++begin;
2705 type_ = boolean;
2706 boolvalue_ = true;
2707 return 0;
2708 }
2709 ecode = json_error::ec_literal;
2710 } else if (*begin == 0x66) // 'f'
2711 {
2712 if (++begin != end && *begin == 0x61) // 'a'
2713 if (++begin != end && *begin == 0x6C) // 'l'
2714 if (++begin != end && *begin == 0x73) // 's'
2715 if (++begin != end && *begin == 0x65) // 'e'
2716 {
2717 ++begin;
2718 type_ = boolean;
2719 boolvalue_ = false;
2720 return 0;
2721 }
2722 ecode = json_error::ec_literal;
2723 } else if (*begin == 0x6E) // 'n'
2724 {
2725 if (++begin != end && *begin == 0x75) // 'u'
2726 if (++begin != end && *begin == 0x6C) // 'l'
2727 if (++begin != end && *begin == 0x6C) // 'l'
2728 {
2729 ++begin;
2730 type_ = null;
2731 return 0;
2732 }
2733 ecode = json_error::ec_literal;
2734 } else {
2735 ForwardIterator orgbegin = begin;
2736 nestring<char> cdigits;
2737
2738 if (*begin == 0x2D) // '-'
2739 {
2740 cdigits.push_back('-');
2741 ++begin;
2742 }
2743
2744 if (begin != end) {
2745 if (*begin == 0x30) // '0'
2746 {
2747 cdigits.push_back('0');
2748 ++begin;
2749 } else if (*begin >= 0x31 && *begin <= 0x39) // '1', '9'.
2750 {
2751 do {
2752 cdigits.push_back(static_cast<char>(*begin - 0x30 + '0'));
2753 } while (++begin != end && *begin >= 0x30 &&
2754 *begin <= 0x39); // '0', '9'.
2755 } else {
2756 ecode =
2757 cdigits.size() ? json_error::ec_number : json_error::ec_literal;
2758 goto FAILED;
2759 }
2760
2761 ecode = json_error::ec_number;
2762
2763 if (begin != end && *begin == 0x2E) // '.'
2764 {
2765 cdigits.push_back('.');
2766 if (++begin == end || *begin < 0x30 || *begin > 0x39) goto FAILED;
2767
2768 do {
2769 cdigits.push_back(static_cast<char>(*begin - 0x30 + '0'));
2770 } while (++begin != end && *begin >= 0x30 &&
2771 *begin <= 0x39); // '0', '9'.
2772 }
2773
2774 if (begin != end && (*begin | 0x20) == 0x65) // 'E' or 'e'.
2775 {
2776 cdigits.push_back('E');
2777 if (++begin == end) goto FAILED;
2778
2779 if (*begin == 0x2B || *begin == 0x2D) // '+', '-'.
2780 {
2781 cdigits.push_back(*begin == 0x2B ? '+' : '-');
2782 ++begin;
2783 }
2784
2785 if (begin == end || *begin < 0x30 || *begin > 0x39) goto FAILED;
2786
2787 do {
2788 cdigits.push_back(static_cast<char>(*begin - 0x30 + '0'));
2789 } while (++begin != end && *begin >= 0x30 &&
2790 *begin <= 0x39); // '0', '9'.
2791 }
2792
2793 cdigits.push_back(0);
2794 type_ = number;
2795 string_ = new strnum_type();
2796 string_->num = std::strtod(cdigits.data(), NULL);
2797 string_->str.assign(orgbegin, begin);
2798 begin = skip_spaces_(begin, end);
2799 return 0;
2800 }
2801 }
2802 }
2803 FAILED:
2804 return ecode;
2805 }
2806
2807 void destroy_node_() {
2808 if (type_ == array) {
2809 // for (typename array_type::size_type i = 0; i <
2810 //array_->size(); ++i)
2811 // (*array_)[i].destroy_node_();
2812 if (array_) delete array_;
2813 } else if (type_ == object) {
2814 // for (typename object_type::iterator it =
2815 //object_->begin(); it != object_->end(); ++it)
2816 // it->second.destroy_node_();
2817 if (object_) delete object_;
2818 } else if (type_ == string || type_ == number) {
2819 if (string_) delete string_;
2820 }
2821 // else // null, boolean.
2822
2823 // value_ = NULL;
2824 // type_ = unassigned;
2825 }
2826
2827 jsonnode& move_(jsonnode& right) {
2828 if (this != &right && !is_fallback() && !right.is_fallback()) {
2829 if (type_ < boolean) destroy_node_();
2830
2831 type_ = right.type_;
2832
2833 if (type_ == array) {
2834 array_ = right.array_;
2835 } else if (type_ == object) {
2836 object_ = right.object_;
2837 } else if (type_ == number || type_ == string) {
2838 string_ = right.string_;
2839 } else if (type_ == boolean) {
2840 boolvalue_ = right.boolvalue_;
2841 }
2842 right.type_ = unassigned;
2843 }
2844 return *this;
2845 }
2846
2847 template <typename StringT>
2848 void value_to_string_(StringT& out) const {
2849 typedef typename StringT::value_type dchar_type;
2850 static const dchar_type quot = 0x22; // '"'
2851 static const dchar_type quotcolon[] = {0x22, 0x3A, 0}; // "\":"
2852 static const dchar_type ltrue[] = {0x74, 0x72, 0x75, 0x65, 0}; // "true"
2853 static const dchar_type lfalse[] = {0x66, 0x61, 0x6C,
2854 0x73, 0x65, 0}; // "false"
2855 static const dchar_type lnull[] = {0x6E, 0x75, 0x6C, 0x6C, 0}; // "null"
2856
2857 if (type_ == number) {
2858 const strsize_type base = out.size();
2859
2860 out.resize(out.size() + string_->str.size());
2861
2862 for (strsize_type i = 0; i < string_->str.size(); ++i)
2863 out[base + i] = string_->str[i]; // ASCII only.
2864 } else if (type_ == string) {
2865 out.push_back(quot);
2866 escape_(out, string_->str, utftype());
2867 out.push_back(quot);
2868 } else if (type_ == boolean)
2869 out.append(boolvalue_ ? ltrue : lfalse);
2870 else if (type_ == array) {
2871 out.push_back(0x5B); // '['
2872
2873 const strsize_type base = out.size();
2874
2875 if (array_) {
2876 for (typename array_type::size_type i = 0; i < array_->size(); ++i) {
2877 (*array_)[i].value_to_string_(out);
2878 out.push_back(0x2C); // ','
2879 }
2880 }
2881
2882 if (out.size() != base)
2883 out[out.size() - 1] = 0x5D; // ']'
2884 else
2885 out.push_back(0x5D); // ']'
2886 } else if (type_ == object) {
2887 out.push_back(0x7B); // '{'
2888
2889 const strsize_type base = out.size();
2890
2891 if (object_) {
2892#if 0
2893 for (typename object_core::const_iterator it = object_->objmap.begin(); it != object_->objmap.end(); ++it)
2894 {
2895 out.push_back(quot);
2896 escape_(out, it->first, utftype());
2897 out.append(quotcolon);
2898 it->second.value_to_string_(out);
2899 out.push_back(0x2C); // ','
2900 }
2901#else
2902 for (strsize_type pos = 0;
2903 (pos + keylen_size) < object_->order.size();) {
2904 const strsize_type keylen =
2905 get_keylen_(&object_->order[pos], utftype());
2906 pos += keylen_size;
2907 const typename object_core::const_iterator it =
2908 object_->objmap.find(object_->order.view(pos, keylen));
2909 pos += keylen;
2910
2911 if (it != object_->objmap.end()) {
2912 out.push_back(quot);
2913 escape_(out, it->first, utftype());
2914 out.append(quotcolon);
2915 it->second.value_to_string_(out);
2916 out.push_back(0x2C); // ','
2917 }
2918 }
2919#endif
2920 }
2921
2922 if (out.size() != base)
2923 out[out.size() - 1] = 0x7D; // '}'
2924 else
2925 out.push_back(0x7D); // '}'
2926 } else
2927 out.append(lnull);
2928 }
2929
2930 void remove_orderkey_(const sview_type key) {
2931 for (strsize_type pos = 0; (pos + keylen_size) < object_->order.size();) {
2932 const strsize_type keylen = get_keylen_(&object_->order[pos], utftype());
2933 const strsize_type keypos = pos + keylen_size;
2934
2935 if (keylen == key.size()) {
2936 for (strsize_type i = 0;; ++i) {
2937 if (i == keylen) {
2938 object_->order.erase(pos, keylen_size + keylen);
2939 return;
2940 }
2941 if (object_->order[keypos + i] != key[i]) break;
2942 }
2943 }
2944 pos = keypos + keylen;
2945 }
2946 }
2947
2948 template <typename ForwardIterator>
2949 unsigned long parse_4hexdigits_(ForwardIterator& begin,
2950 const ForwardIterator end) const {
2951 unsigned long ucp = 0ul;
2952
2953 for (strsize_type i = 0; i < 4; ++i) {
2954 if (++begin != end) {
2955 int b = *begin;
2956
2957 if (b >= 0x30 && b <= 0x39)
2958 ucp = (ucp << 4) | (b - 0x30);
2959 else {
2960 b |= 0x20;
2961 if (b >= 0x61 && b <= 0x66)
2962 ucp = (ucp << 4) | (b - 0x61 + 10);
2963 else
2964 return 0x10000ul;
2965 }
2966 } else
2967 break;
2968 }
2969 return ucp;
2970 }
2971
2972 // UTF-8 -> UTF-8.
2973
2974 template <typename StringT, typename UTFtype>
2975 void escape_(StringT& d, const sview_type s, const UTFtype) const {
2976 typedef typename StringT::value_type dchar_type;
2977 typedef typename StringT::size_type dsize_type;
2978
2979 const dsize_type base = d.size();
2980
2981 d.append(s.begin(), s.end());
2982
2983 for (dsize_type i = base; i < d.size(); ++i) {
2984 unsigned long ch = d[i];
2985
2986 // unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
2987 if (ch < 0x20) {
2988 d.insert(i, 5, 0);
2989 d[i++] = static_cast<dchar_type>(0x5c);
2990 d[i++] = static_cast<dchar_type>(0x75);
2991 d[i++] = static_cast<dchar_type>(0x30);
2992 d[i++] = static_cast<dchar_type>(0x30);
2993 d[i++] = static_cast<dchar_type>((ch >> 4) + 0x30);
2994 ch &= 0xf;
2995 d[i] = static_cast<dchar_type>(ch + (ch < 10 ? 0x30 : 0x41 - 10));
2996 } else if (ch == 0x22 || ch == 0x5c) {
2997 d.insert(i++, 1, 0x5c);
2998 }
2999 }
3000 }
3001
3002 // UTF-16 -> UTF-8.
3003
3004 template <typename StringT>
3005 void escape_(StringT& d, const sview_type s, const utf16tag) const {
3006 typedef typename StringT::value_type dchar_type;
3007 typedef typename StringT::size_type dsize_type;
3008 unsigned long prev = 0ul;
3009
3010 d.reserve(d.size() + s.size());
3011
3012 for (strsize_type i = 0; i < s.size(); ++i) {
3013 unsigned long ch = s[i] & 0xffff;
3014
3015 // unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
3016 if (ch < 0x20) {
3017 dsize_type j = d.size();
3018
3019 d.resize(j + 6);
3020 d[j++] = static_cast<dchar_type>(0x5c);
3021 d[j++] = static_cast<dchar_type>(0x75);
3022 d[j++] = static_cast<dchar_type>(0x30);
3023 d[j++] = static_cast<dchar_type>(0x30);
3024 d[j++] = static_cast<dchar_type>((ch >> 4) + 0x30);
3025 ch &= 0xf;
3026 d[j] = static_cast<dchar_type>(ch + (ch < 10 ? 0x30 : 0x41 - 10));
3027 } else if (ch == 0x22 || ch == 0x5c) {
3028 d.resize(d.size() + 2, 0x5c);
3029 d[d.size() - 1] = static_cast<dchar_type>(ch);
3030 } else if (ch >= 0x80) {
3031 if (ch >= 0x800) {
3032 if (prev && ((ch - 0xdc00) < 0x400)) // DC00..DFFF.
3033 {
3034 dsize_type j = d.size();
3035
3036 ch = (((prev & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
3037
3038 d.resize(j + 1, static_cast<dchar_type>(0x80 | (ch & 0x3f)));
3039 d[j - 3] = static_cast<dchar_type>(0xf0 | (ch >> 18));
3040 d[j - 2] = static_cast<dchar_type>(0x80 | ((ch >> 12) & 0x3f));
3041 d[j - 1] = static_cast<dchar_type>(0x80 | ((ch >> 6) & 0x3f));
3042 } else {
3043 dsize_type j = d.size();
3044
3045 d.resize(j + 3, static_cast<dchar_type>(0x80 | (ch & 0x3f)));
3046 d[j++] = static_cast<dchar_type>(0xe0 | (ch >> 12));
3047 d[j++] = static_cast<dchar_type>(0x80 | ((ch >> 6) & 0x3f));
3048
3049 prev = ((ch - 0xd800) < 0x400) ? ch : 0ul; // D800..DBFF.
3050 continue;
3051 }
3052 } else // 80..7FF.
3053 {
3054 dsize_type j = d.size();
3055
3056 d.resize(j + 2, static_cast<dchar_type>(0x80 | (ch & 0x3f)));
3057 d[j] = static_cast<dchar_type>(0xc0 | (ch >> 6));
3058 }
3059 } else
3060 d.push_back(static_cast<dchar_type>(ch));
3061
3062 prev = 0ul;
3063 }
3064 }
3065
3066 private:
3067 union {
3068 void* value_;
3069 strnum_type* string_;
3070 array_type* array_;
3071 object_type* object_;
3072 bool boolvalue_;
3073 };
3074 union {
3075 // value_type type_;
3076 int type_;
3077 void* padding_;
3078 };
3079
3080 static jsonnode fallback_node_;
3081 static const char_type emptystr_[];
3082};
3083// Thanks to ODR, only one static object exists per type of charT,
3084// as fallback_node_.fallback_node_ is also jsonnode<charT>.
3085template <typename charT, typename utftype>
3086jsonnode<charT, utftype> jsonnode<charT, utftype>::fallback_node_(
3087 jsonnode<charT, utftype>::fallback);
3088
3089template <typename charT, typename utftype>
3090const typename jsonnode<charT, utftype>::char_type
3091 jsonnode<charT, utftype>::emptystr_[] = {0};
3092// jsonnode
3093
3094} // namespace json_internal_
3095
3096typedef json_internal_::jsonnode<char, json_internal_::utf8tag> json;
3097typedef json_internal_::jsonnode<char, json_internal_::utf8tag> u8cjson;
3098
3099#if defined(WCHAR_MAX) && (WCHAR_MAX >= 0xffff)
3100#if (WCHAR_MAX >= 0x10ffff)
3101#else
3102typedef json_internal_::jsonnode<wchar_t, json_internal_::utf16tag> wjson;
3103typedef json_internal_::jsonnode<wchar_t, json_internal_::utf16tag> u16wjson;
3104#endif
3105#endif
3106
3107#if defined(__cpp_unicode_characters)
3108typedef json_internal_::jsonnode<char16_t, json_internal_::utf16tag> u16json;
3109#endif
3110
3111#if defined(__cpp_char8_t)
3112typedef json_internal_::jsonnode<char8_t, json_internal_::utf8tag> u8json;
3113#endif
3114
3115} // namespace NAMESPACE_CTLJSON
3116#endif // CTL_JSON_TEMPLATE_LIBRARY
std::string stringify(const Object &obj)
Convert a VDF object into a human-readable string.
Definition vdf.hpp:199