jsoncons 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/ext/jsoncons/extconf.rb +43 -0
  3. data/ext/jsoncons/jsoncons.cpp +161 -0
  4. data/ext/jsoncons/jsoncons.h +10 -0
  5. data/jsoncons.gemspec +44 -0
  6. data/lib/jsoncons/jsoncons/examples/input/address-book.json +13 -0
  7. data/lib/jsoncons/jsoncons/examples/input/books.json +28 -0
  8. data/lib/jsoncons/jsoncons/examples/input/countries.json +7 -0
  9. data/lib/jsoncons/jsoncons/examples/input/employees.json +30 -0
  10. data/lib/jsoncons/jsoncons/examples/input/jsonschema/name.json +15 -0
  11. data/lib/jsoncons/jsoncons/examples/input/multiple-json-objects.json +3 -0
  12. data/lib/jsoncons/jsoncons/examples/input/sales.csv +6 -0
  13. data/lib/jsoncons/jsoncons/examples/input/store.json +28 -0
  14. data/lib/jsoncons/jsoncons/examples/input/tasks.csv +6 -0
  15. data/lib/jsoncons/jsoncons/include/jsoncons/allocator_holder.hpp +38 -0
  16. data/lib/jsoncons/jsoncons/include/jsoncons/basic_json.hpp +5905 -0
  17. data/lib/jsoncons/jsoncons/include/jsoncons/bigint.hpp +1611 -0
  18. data/lib/jsoncons/jsoncons/include/jsoncons/byte_string.hpp +820 -0
  19. data/lib/jsoncons/jsoncons/include/jsoncons/config/binary_config.hpp +226 -0
  20. data/lib/jsoncons/jsoncons/include/jsoncons/config/compiler_support.hpp +375 -0
  21. data/lib/jsoncons/jsoncons/include/jsoncons/config/jsoncons_config.hpp +309 -0
  22. data/lib/jsoncons/jsoncons/include/jsoncons/config/version.hpp +40 -0
  23. data/lib/jsoncons/jsoncons/include/jsoncons/conv_error.hpp +218 -0
  24. data/lib/jsoncons/jsoncons/include/jsoncons/decode_json.hpp +209 -0
  25. data/lib/jsoncons/jsoncons/include/jsoncons/decode_traits.hpp +651 -0
  26. data/lib/jsoncons/jsoncons/include/jsoncons/detail/endian.hpp +44 -0
  27. data/lib/jsoncons/jsoncons/include/jsoncons/detail/grisu3.hpp +312 -0
  28. data/lib/jsoncons/jsoncons/include/jsoncons/detail/optional.hpp +483 -0
  29. data/lib/jsoncons/jsoncons/include/jsoncons/detail/parse_number.hpp +1133 -0
  30. data/lib/jsoncons/jsoncons/include/jsoncons/detail/span.hpp +188 -0
  31. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_view.hpp +537 -0
  32. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_wrapper.hpp +370 -0
  33. data/lib/jsoncons/jsoncons/include/jsoncons/detail/write_number.hpp +567 -0
  34. data/lib/jsoncons/jsoncons/include/jsoncons/encode_json.hpp +315 -0
  35. data/lib/jsoncons/jsoncons/include/jsoncons/encode_traits.hpp +378 -0
  36. data/lib/jsoncons/jsoncons/include/jsoncons/json.hpp +18 -0
  37. data/lib/jsoncons/jsoncons/include/jsoncons/json_array.hpp +324 -0
  38. data/lib/jsoncons/jsoncons/include/jsoncons/json_content_handler.hpp +12 -0
  39. data/lib/jsoncons/jsoncons/include/jsoncons/json_cursor.hpp +448 -0
  40. data/lib/jsoncons/jsoncons/include/jsoncons/json_decoder.hpp +420 -0
  41. data/lib/jsoncons/jsoncons/include/jsoncons/json_encoder.hpp +1587 -0
  42. data/lib/jsoncons/jsoncons/include/jsoncons/json_error.hpp +156 -0
  43. data/lib/jsoncons/jsoncons/include/jsoncons/json_exception.hpp +241 -0
  44. data/lib/jsoncons/jsoncons/include/jsoncons/json_filter.hpp +653 -0
  45. data/lib/jsoncons/jsoncons/include/jsoncons/json_fwd.hpp +23 -0
  46. data/lib/jsoncons/jsoncons/include/jsoncons/json_object.hpp +1772 -0
  47. data/lib/jsoncons/jsoncons/include/jsoncons/json_options.hpp +862 -0
  48. data/lib/jsoncons/jsoncons/include/jsoncons/json_parser.hpp +2900 -0
  49. data/lib/jsoncons/jsoncons/include/jsoncons/json_reader.hpp +731 -0
  50. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros.hpp +1072 -0
  51. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros_deprecated.hpp +144 -0
  52. data/lib/jsoncons/jsoncons/include/jsoncons/json_type.hpp +206 -0
  53. data/lib/jsoncons/jsoncons/include/jsoncons/json_type_traits.hpp +1830 -0
  54. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor.hpp +1560 -0
  55. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor2.hpp +2079 -0
  56. data/lib/jsoncons/jsoncons/include/jsoncons/pretty_print.hpp +89 -0
  57. data/lib/jsoncons/jsoncons/include/jsoncons/ser_context.hpp +62 -0
  58. data/lib/jsoncons/jsoncons/include/jsoncons/sink.hpp +289 -0
  59. data/lib/jsoncons/jsoncons/include/jsoncons/source.hpp +777 -0
  60. data/lib/jsoncons/jsoncons/include/jsoncons/source_adaptor.hpp +148 -0
  61. data/lib/jsoncons/jsoncons/include/jsoncons/staj2_cursor.hpp +1189 -0
  62. data/lib/jsoncons/jsoncons/include/jsoncons/staj_cursor.hpp +1254 -0
  63. data/lib/jsoncons/jsoncons/include/jsoncons/staj_iterator.hpp +449 -0
  64. data/lib/jsoncons/jsoncons/include/jsoncons/tag_type.hpp +245 -0
  65. data/lib/jsoncons/jsoncons/include/jsoncons/text_source_adaptor.hpp +144 -0
  66. data/lib/jsoncons/jsoncons/include/jsoncons/traits_extension.hpp +884 -0
  67. data/lib/jsoncons/jsoncons/include/jsoncons/typed_array_view.hpp +250 -0
  68. data/lib/jsoncons/jsoncons/include/jsoncons/unicode_traits.hpp +1330 -0
  69. data/lib/jsoncons/jsoncons/include/jsoncons/uri.hpp +635 -0
  70. data/lib/jsoncons/jsoncons/include/jsoncons/value_converter.hpp +340 -0
  71. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson.hpp +23 -0
  72. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_cursor.hpp +320 -0
  73. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_decimal128.hpp +865 -0
  74. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_encoder.hpp +585 -0
  75. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_error.hpp +103 -0
  76. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp +245 -0
  77. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_options.hpp +75 -0
  78. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_parser.hpp +645 -0
  79. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_reader.hpp +92 -0
  80. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_type.hpp +44 -0
  81. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/decode_bson.hpp +201 -0
  82. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/encode_bson.hpp +144 -0
  83. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor.hpp +26 -0
  84. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor.hpp +351 -0
  85. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor2.hpp +265 -0
  86. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_detail.hpp +93 -0
  87. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_encoder.hpp +1766 -0
  88. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_error.hpp +105 -0
  89. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_options.hpp +113 -0
  90. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_parser.hpp +1942 -0
  91. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_reader.hpp +116 -0
  92. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/decode_cbor.hpp +203 -0
  93. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/encode_cbor.hpp +151 -0
  94. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv.hpp +17 -0
  95. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_cursor.hpp +358 -0
  96. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_encoder.hpp +954 -0
  97. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_error.hpp +85 -0
  98. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_options.hpp +973 -0
  99. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp +2099 -0
  100. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp +348 -0
  101. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_serializer.hpp +12 -0
  102. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/decode_csv.hpp +208 -0
  103. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/encode_csv.hpp +122 -0
  104. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath.hpp +5215 -0
  105. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath_error.hpp +215 -0
  106. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch.hpp +579 -0
  107. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp +121 -0
  108. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/expression.hpp +3329 -0
  109. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/flatten.hpp +432 -0
  110. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_location.hpp +445 -0
  111. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_query.hpp +115 -0
  112. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath.hpp +13 -0
  113. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_error.hpp +240 -0
  114. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp +2612 -0
  115. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +1322 -0
  116. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer.hpp +1577 -0
  117. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp +119 -0
  118. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/format_validator.hpp +968 -0
  119. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/json_validator.hpp +120 -0
  120. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema.hpp +13 -0
  121. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_error.hpp +105 -0
  122. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_version.hpp +18 -0
  123. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator.hpp +1745 -0
  124. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator_factory.hpp +556 -0
  125. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_draft7.hpp +198 -0
  126. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_location.hpp +200 -0
  127. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_version.hpp +35 -0
  128. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/subschema.hpp +144 -0
  129. data/lib/jsoncons/jsoncons/include/jsoncons_ext/mergepatch/mergepatch.hpp +103 -0
  130. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/decode_msgpack.hpp +202 -0
  131. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/encode_msgpack.hpp +142 -0
  132. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack.hpp +24 -0
  133. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +343 -0
  134. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor2.hpp +259 -0
  135. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_encoder.hpp +753 -0
  136. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_error.hpp +94 -0
  137. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_options.hpp +74 -0
  138. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp +748 -0
  139. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_reader.hpp +116 -0
  140. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_type.hpp +63 -0
  141. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/decode_ubjson.hpp +201 -0
  142. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/encode_ubjson.hpp +142 -0
  143. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson.hpp +23 -0
  144. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +307 -0
  145. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_encoder.hpp +502 -0
  146. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_error.hpp +100 -0
  147. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_options.hpp +87 -0
  148. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp +880 -0
  149. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_reader.hpp +92 -0
  150. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_type.hpp +43 -0
  151. data/lib/jsoncons/version.rb +5 -0
  152. data/lib/jsoncons.rb +33 -0
  153. data/test/jsoncons_test.rb +108 -0
  154. data/test/test_helper.rb +7 -0
  155. metadata +268 -0
@@ -0,0 +1,1772 @@
1
+ // Copyright 2013 Daniel Parker
2
+ // Distributed under the Boost license, Version 1.0.
3
+ // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ // See https://github.com/danielaparker/jsoncons for latest version
6
+
7
+ #ifndef JSONCONS_JSON_OBJECT_HPP
8
+ #define JSONCONS_JSON_OBJECT_HPP
9
+
10
+ #include <string>
11
+ #include <vector>
12
+ #include <tuple>
13
+ #include <exception>
14
+ #include <cstring>
15
+ #include <algorithm> // std::sort, std::stable_sort, std::lower_bound, std::unique
16
+ #include <utility>
17
+ #include <initializer_list>
18
+ #include <iterator> // std::iterator_traits
19
+ #include <memory> // std::allocator
20
+ #include <utility> // std::move
21
+ #include <cassert> // assert
22
+ #include <type_traits> // std::enable_if
23
+ #include <jsoncons/json_exception.hpp>
24
+ #include <jsoncons/allocator_holder.hpp>
25
+ #include <jsoncons/json_array.hpp>
26
+
27
+ namespace jsoncons {
28
+
29
+ struct sorted_unique_range_tag
30
+ {
31
+ explicit sorted_unique_range_tag() = default;
32
+ };
33
+
34
+ // key_value
35
+
36
+ template <class KeyT, class ValueT>
37
+ class key_value
38
+ {
39
+ public:
40
+ using key_type = KeyT;
41
+ using value_type = ValueT;
42
+ using allocator_type = typename ValueT::allocator_type;
43
+ using string_view_type = typename value_type::string_view_type;
44
+ private:
45
+
46
+ key_type key_;
47
+ value_type value_;
48
+ public:
49
+
50
+ key_value() noexcept
51
+ {
52
+ }
53
+
54
+ key_value(const key_type& name, const value_type& val)
55
+ : key_(name), value_(val)
56
+ {
57
+ }
58
+
59
+ key_value(const string_view_type& name)
60
+ : key_(name)
61
+ {
62
+ }
63
+
64
+ template <typename... Args>
65
+ key_value(const key_type& name, Args&& ... args)
66
+ : key_(name), value_(std::forward<Args>(args)...)
67
+ {
68
+ }
69
+
70
+ template <typename... Args>
71
+ key_value(key_type&& name, Args&& ... args) noexcept
72
+ : key_(std::forward<key_type>(name)), value_(std::forward<Args>(args)...)
73
+ {
74
+ }
75
+
76
+ key_value(const key_value& member)
77
+ : key_(member.key_), value_(member.value_)
78
+ {
79
+ }
80
+
81
+ key_value(key_value&& member) noexcept
82
+ : key_(std::move(member.key_)), value_(std::move(member.value_))
83
+ {
84
+ }
85
+ template <typename... U1, typename... U2>
86
+ JSONCONS_CONSTEXPR key_value(std::piecewise_construct_t /*unused*/, std::tuple<U1...> a,
87
+ std::tuple<U2...>
88
+ b) noexcept(noexcept(key_value(std::declval<std::tuple<U1...>&>(),
89
+ std::declval<std::tuple<U2...>&>(),
90
+ jsoncons::traits_extension::index_sequence_for<U1...>(),
91
+ jsoncons::traits_extension::index_sequence_for<U2...>())))
92
+ : key_value(a, b, jsoncons::traits_extension::index_sequence_for<U1...>(),
93
+ jsoncons::traits_extension::index_sequence_for<U2...>()) {
94
+ }
95
+
96
+ template <typename... U1, size_t... I1, typename... U2, size_t... I2>
97
+ key_value(std::tuple<U1...>& a, std::tuple<U2...>& b, jsoncons::traits_extension::index_sequence<I1...> /*unused*/, jsoncons::traits_extension::index_sequence<I2...> /*unused*/) noexcept(
98
+ noexcept(KeyT(std::forward<U1>(std::get<I1>(
99
+ std::declval<std::tuple<
100
+ U1...>&>()))...)) && noexcept(ValueT(std::
101
+ forward<U2>(std::get<I2>(
102
+ std::declval<std::tuple<U2...>&>()))...)))
103
+ : key_(std::forward<U1>(std::get<I1>(a))...)
104
+ , value_(std::forward<U2>(std::get<I2>(b))...) {
105
+ // make visual studio compiler happy about warning about unused a & b.
106
+ // Visual studio's key_value implementation disables warning 4100.
107
+ (void)a;
108
+ (void)b;
109
+ }
110
+
111
+ const key_type& key() const
112
+ {
113
+ return key_;
114
+ }
115
+
116
+ value_type& value()
117
+ {
118
+ return value_;
119
+ }
120
+
121
+ const value_type& value() const
122
+ {
123
+ return value_;
124
+ }
125
+
126
+ template <class T>
127
+ void value(T&& value)
128
+ {
129
+ value_ = std::forward<T>(value);
130
+ }
131
+
132
+ void swap(key_value& member) noexcept
133
+ {
134
+ key_.swap(member.key_);
135
+ value_.swap(member.value_);
136
+ }
137
+
138
+ key_value& operator=(const key_value& member)
139
+ {
140
+ if (this != & member)
141
+ {
142
+ key_ = member.key_;
143
+ value_ = member.value_;
144
+ }
145
+ return *this;
146
+ }
147
+
148
+ key_value& operator=(key_value&& member) noexcept
149
+ {
150
+ if (this != &member)
151
+ {
152
+ key_.swap(member.key_);
153
+ value_.swap(member.value_);
154
+ }
155
+ return *this;
156
+ }
157
+
158
+ void shrink_to_fit()
159
+ {
160
+ key_.shrink_to_fit();
161
+ value_.shrink_to_fit();
162
+ }
163
+ #if !defined(JSONCONS_NO_DEPRECATED)
164
+ JSONCONS_DEPRECATED_MSG("Instead, use key()")
165
+ const key_type& name() const
166
+ {
167
+ return key_;
168
+ }
169
+ #endif
170
+
171
+ friend bool operator==(const key_value& lhs, const key_value& rhs) noexcept
172
+ {
173
+ return lhs.key_ == rhs.key_ && lhs.value_ == rhs.value_;
174
+ }
175
+
176
+ friend bool operator!=(const key_value& lhs, const key_value& rhs) noexcept
177
+ {
178
+ return !(lhs == rhs);
179
+ }
180
+
181
+ friend bool operator<(const key_value& lhs, const key_value& rhs) noexcept
182
+ {
183
+ if (lhs.key_ < rhs.key_)
184
+ {
185
+ return true;
186
+ }
187
+ if (lhs.key_ == rhs.key_ && lhs.value_ < rhs.value_)
188
+ {
189
+ return true;
190
+ }
191
+ return false;
192
+ }
193
+
194
+ friend bool operator<=(const key_value& lhs, const key_value& rhs) noexcept
195
+ {
196
+ return !(rhs < lhs);
197
+ }
198
+
199
+ friend bool operator>(const key_value& lhs, const key_value& rhs) noexcept
200
+ {
201
+ return !(lhs <= rhs);
202
+ }
203
+
204
+ friend bool operator>=(const key_value& lhs, const key_value& rhs) noexcept
205
+ {
206
+ return !(lhs < rhs);
207
+ }
208
+
209
+ friend void swap(key_value& a, key_value& b) noexcept(
210
+ noexcept(std::declval<key_value&>().swap(std::declval<key_value&>())))
211
+ {
212
+ a.swap(b);
213
+ }
214
+ };
215
+
216
+ template <class KeyT, class ValueT>
217
+ struct get_key_value
218
+ {
219
+ using key_value_type = key_value<KeyT,ValueT>;
220
+
221
+ template <class T1,class T2>
222
+ key_value_type operator()(const std::pair<T1,T2>& p)
223
+ {
224
+ return key_value_type(p.first,p.second);
225
+ }
226
+ template <class T1,class T2>
227
+ key_value_type operator()(std::pair<T1,T2>&& p)
228
+ {
229
+ return key_value_type(std::forward<T1>(p.first),std::forward<T2>(p.second));
230
+ }
231
+ template <class T1,class T2>
232
+ const key_value_type& operator()(const key_value<T1,T2>& p)
233
+ {
234
+ return p;
235
+ }
236
+ template <class T1,class T2>
237
+ key_value_type operator()(key_value<T1,T2>&& p)
238
+ {
239
+ return std::move(p);
240
+ }
241
+ };
242
+
243
+ struct sort_key_order
244
+ {
245
+ explicit sort_key_order() = default;
246
+ };
247
+
248
+ struct preserve_key_order
249
+ {
250
+ explicit preserve_key_order() = default;
251
+ };
252
+
253
+
254
+ // Sort keys
255
+ template <class KeyT,class Json,template<typename,typename> class SequenceContainer = std::vector>
256
+ class sorted_json_object : public allocator_holder<typename Json::allocator_type>
257
+ {
258
+ public:
259
+ using allocator_type = typename Json::allocator_type;
260
+ using key_type = KeyT;
261
+ using key_value_type = key_value<KeyT,Json>;
262
+ using char_type = typename Json::char_type;
263
+ using string_view_type = typename Json::string_view_type;
264
+ private:
265
+ struct Comp
266
+ {
267
+ bool operator() (const key_value_type& kv, string_view_type k) const { return kv.key() < k; }
268
+ bool operator() (string_view_type k, const key_value_type& kv) const { return k < kv.key(); }
269
+ };
270
+
271
+ using key_value_allocator_type = typename std::allocator_traits<allocator_type>:: template rebind_alloc<key_value_type>;
272
+ using key_value_container_type = SequenceContainer<key_value_type,key_value_allocator_type>;
273
+
274
+ key_value_container_type members_;
275
+ public:
276
+ using iterator = typename key_value_container_type::iterator;
277
+ using const_iterator = typename key_value_container_type::const_iterator;
278
+
279
+ using allocator_holder<allocator_type>::get_allocator;
280
+
281
+ sorted_json_object()
282
+ {
283
+ }
284
+
285
+ explicit sorted_json_object(const allocator_type& alloc)
286
+ : allocator_holder<allocator_type>(alloc),
287
+ members_(key_value_allocator_type(alloc))
288
+ {
289
+ }
290
+
291
+ sorted_json_object(const sorted_json_object& val)
292
+ : allocator_holder<allocator_type>(val.get_allocator()),
293
+ members_(val.members_)
294
+ {
295
+ }
296
+
297
+ sorted_json_object(sorted_json_object&& val)
298
+ : allocator_holder<allocator_type>(val.get_allocator()),
299
+ members_(std::move(val.members_))
300
+ {
301
+ }
302
+
303
+ sorted_json_object& operator=(const sorted_json_object& val)
304
+ {
305
+ allocator_holder<allocator_type>::operator=(val.get_allocator());
306
+ members_ = val.members_;
307
+ return *this;
308
+ }
309
+
310
+ sorted_json_object& operator=(sorted_json_object&& val)
311
+ {
312
+ val.swap(*this);
313
+ return *this;
314
+ }
315
+
316
+ sorted_json_object(const sorted_json_object& val, const allocator_type& alloc)
317
+ : allocator_holder<allocator_type>(alloc),
318
+ members_(val.members_,key_value_allocator_type(alloc))
319
+ {
320
+ }
321
+
322
+ sorted_json_object(sorted_json_object&& val,const allocator_type& alloc)
323
+ : allocator_holder<allocator_type>(alloc), members_(std::move(val.members_),key_value_allocator_type(alloc))
324
+ {
325
+ }
326
+
327
+ template<class InputIt>
328
+ sorted_json_object(InputIt first, InputIt last)
329
+ {
330
+ std::size_t count = std::distance(first,last);
331
+ members_.reserve(count);
332
+ for (auto s = first; s != last; ++s)
333
+ {
334
+ members_.emplace_back(get_key_value<KeyT,Json>()(*s));
335
+ }
336
+ std::stable_sort(members_.begin(),members_.end(),
337
+ [](const key_value_type& a, const key_value_type& b) -> bool {return a.key().compare(b.key()) < 0;});
338
+ auto it = std::unique(members_.begin(), members_.end(),
339
+ [](const key_value_type& a, const key_value_type& b) -> bool { return !(a.key().compare(b.key()));});
340
+ members_.erase(it, members_.end());
341
+ }
342
+
343
+ template<class InputIt>
344
+ sorted_json_object(InputIt first, InputIt last,
345
+ const allocator_type& alloc)
346
+ : allocator_holder<allocator_type>(alloc),
347
+ members_(key_value_allocator_type(alloc))
348
+ {
349
+ std::size_t count = std::distance(first,last);
350
+ members_.reserve(count);
351
+ for (auto s = first; s != last; ++s)
352
+ {
353
+ members_.emplace_back(get_key_value<KeyT,Json>()(*s));
354
+ }
355
+ std::stable_sort(members_.begin(),members_.end(),
356
+ [](const key_value_type& a, const key_value_type& b) -> bool {return a.key().compare(b.key()) < 0;});
357
+ auto it = std::unique(members_.begin(), members_.end(),
358
+ [](const key_value_type& a, const key_value_type& b) -> bool { return !(a.key().compare(b.key()));});
359
+ members_.erase(it, members_.end());
360
+ }
361
+
362
+ sorted_json_object(const std::initializer_list<std::pair<std::basic_string<char_type>,Json>>& init,
363
+ const allocator_type& alloc = allocator_type())
364
+ : allocator_holder<allocator_type>(alloc),
365
+ members_(key_value_allocator_type(alloc))
366
+ {
367
+ members_.reserve(init.size());
368
+ for (auto& item : init)
369
+ {
370
+ insert_or_assign(item.first, item.second);
371
+ }
372
+ }
373
+
374
+ ~sorted_json_object() noexcept
375
+ {
376
+ flatten_and_destroy();
377
+ }
378
+
379
+ bool empty() const
380
+ {
381
+ return members_.empty();
382
+ }
383
+
384
+ void swap(sorted_json_object& val) noexcept
385
+ {
386
+ members_.swap(val.members_);
387
+ }
388
+
389
+ iterator begin()
390
+ {
391
+ return members_.begin();
392
+ }
393
+
394
+ iterator end()
395
+ {
396
+ return members_.end();
397
+ }
398
+
399
+ const_iterator begin() const
400
+ {
401
+ return members_.begin();
402
+ }
403
+
404
+ const_iterator end() const
405
+ {
406
+ return members_.end();
407
+ }
408
+
409
+ std::size_t size() const {return members_.size();}
410
+
411
+ std::size_t capacity() const {return members_.capacity();}
412
+
413
+ void clear() {members_.clear();}
414
+
415
+ void shrink_to_fit()
416
+ {
417
+ for (std::size_t i = 0; i < members_.size(); ++i)
418
+ {
419
+ members_[i].shrink_to_fit();
420
+ }
421
+ members_.shrink_to_fit();
422
+ }
423
+
424
+ void reserve(std::size_t n) {members_.reserve(n);}
425
+
426
+ Json& at(std::size_t i)
427
+ {
428
+ if (i >= members_.size())
429
+ {
430
+ JSONCONS_THROW(json_runtime_error<std::out_of_range>("Invalid array subscript"));
431
+ }
432
+ return members_[i].value();
433
+ }
434
+
435
+ const Json& at(std::size_t i) const
436
+ {
437
+ if (i >= members_.size())
438
+ {
439
+ JSONCONS_THROW(json_runtime_error<std::out_of_range>("Invalid array subscript"));
440
+ }
441
+ return members_[i].value();
442
+ }
443
+
444
+ iterator find(const string_view_type& name) noexcept
445
+ {
446
+ auto p = std::equal_range(members_.begin(),members_.end(), name,
447
+ Comp());
448
+ return p.first == p.second ? members_.end() : p.first;
449
+ }
450
+
451
+ const_iterator find(const string_view_type& name) const noexcept
452
+ {
453
+ auto p = std::equal_range(members_.begin(),members_.end(), name,
454
+ Comp());
455
+ return p.first == p.second ? members_.end() : p.first;
456
+ }
457
+
458
+ iterator erase(const_iterator pos)
459
+ {
460
+ #if defined(JSONCONS_NO_VECTOR_ERASE_TAKES_CONST_ITERATOR)
461
+ iterator it = members_.begin() + (pos - members_.begin());
462
+ return members_.erase(it);
463
+ #else
464
+ return members_.erase(pos);
465
+ #endif
466
+ }
467
+
468
+ iterator erase(const_iterator first, const_iterator last)
469
+ {
470
+ #if defined(JSONCONS_NO_VECTOR_ERASE_TAKES_CONST_ITERATOR)
471
+ iterator it1 = members_.begin() + (first - members_.begin());
472
+ iterator it2 = members_.begin() + (last - members_.begin());
473
+ return members_.erase(it1,it2);
474
+ #else
475
+ return members_.erase(first,last);
476
+ #endif
477
+ }
478
+
479
+ void erase(const string_view_type& name)
480
+ {
481
+ auto it = find(name);
482
+ if (it != members_.end())
483
+ {
484
+ members_.erase(it);
485
+ }
486
+ }
487
+
488
+ template<class InputIt, class Convert>
489
+ void insert(InputIt first, InputIt last, Convert convert)
490
+ {
491
+ std::size_t count = std::distance(first,last);
492
+ members_.reserve(members_.size() + count);
493
+ for (auto s = first; s != last; ++s)
494
+ {
495
+ members_.emplace_back(convert(*s));
496
+ }
497
+ std::stable_sort(members_.begin(),members_.end(),
498
+ [](const key_value_type& a, const key_value_type& b) -> bool {return a.key().compare(b.key()) < 0;});
499
+ auto it = std::unique(members_.begin(), members_.end(),
500
+ [](const key_value_type& a, const key_value_type& b) -> bool { return !(a.key().compare(b.key()));});
501
+ members_.erase(it, members_.end());
502
+ }
503
+
504
+ template<class InputIt, class Convert>
505
+ void insert(sorted_unique_range_tag, InputIt first, InputIt last, Convert convert)
506
+ {
507
+ if (first != last)
508
+ {
509
+ std::size_t count = std::distance(first,last);
510
+ members_.reserve(members_.size() + count);
511
+
512
+ auto it = find(convert(*first).key());
513
+ if (it != members_.end())
514
+ {
515
+ for (auto s = first; s != last; ++s)
516
+ {
517
+ it = members_.emplace(it, convert(*s));
518
+ }
519
+ }
520
+ else
521
+ {
522
+ for (auto s = first; s != last; ++s)
523
+ {
524
+ members_.emplace_back(convert(*s));
525
+ }
526
+ }
527
+ }
528
+ }
529
+
530
+ // insert_or_assign
531
+
532
+ template <class T, class A=allocator_type>
533
+ typename std::enable_if<traits_extension::is_stateless<A>::value,std::pair<iterator,bool>>::type
534
+ insert_or_assign(const string_view_type& name, T&& value)
535
+ {
536
+ bool inserted;
537
+ auto it = std::lower_bound(members_.begin(),members_.end(), name,
538
+ Comp());
539
+ if (it == members_.end())
540
+ {
541
+ members_.emplace_back(key_type(name.begin(),name.end()),
542
+ std::forward<T>(value));
543
+ inserted = true;
544
+ it = members_.begin() + members_.size() - 1;
545
+ }
546
+ else if (it->key() == name)
547
+ {
548
+ it->value(Json(std::forward<T>(value)));
549
+ inserted = false; // assigned
550
+ }
551
+ else
552
+ {
553
+ it = members_.emplace(it,
554
+ key_type(name.begin(),name.end()),
555
+ std::forward<T>(value));
556
+ inserted = true;
557
+ }
558
+ return std::make_pair(it,inserted);
559
+ }
560
+
561
+ template <class T, class A=allocator_type>
562
+ typename std::enable_if<!traits_extension::is_stateless<A>::value,std::pair<iterator,bool>>::type
563
+ insert_or_assign(const string_view_type& name, T&& value)
564
+ {
565
+ bool inserted;
566
+ auto it = std::lower_bound(members_.begin(),members_.end(), name,
567
+ Comp());
568
+ if (it == members_.end())
569
+ {
570
+ members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()),
571
+ std::forward<T>(value),get_allocator());
572
+ inserted = true;
573
+ it = members_.begin() + members_.size() - 1;
574
+ }
575
+ else if (it->key() == name)
576
+ {
577
+ it->value(Json(std::forward<T>(value), get_allocator()));
578
+ inserted = false; // assigned
579
+ }
580
+ else
581
+ {
582
+ it = members_.emplace(it,
583
+ key_type(name.begin(),name.end(), get_allocator()),
584
+ std::forward<T>(value),get_allocator());
585
+ inserted = true;
586
+ }
587
+ return std::make_pair(it,inserted);
588
+ }
589
+
590
+ // try_emplace
591
+
592
+ template <class A=allocator_type, class... Args>
593
+ typename std::enable_if<traits_extension::is_stateless<A>::value,std::pair<iterator,bool>>::type
594
+ try_emplace(const string_view_type& name, Args&&... args)
595
+ {
596
+ bool inserted;
597
+ auto it = std::lower_bound(members_.begin(),members_.end(), name,
598
+ Comp());
599
+ if (it == members_.end())
600
+ {
601
+ members_.emplace_back(key_type(name.begin(),name.end()),
602
+ std::forward<Args>(args)...);
603
+ it = members_.begin() + members_.size() - 1;
604
+ inserted = true;
605
+ }
606
+ else if (it->key() == name)
607
+ {
608
+ inserted = false;
609
+ }
610
+ else
611
+ {
612
+ it = members_.emplace(it,
613
+ key_type(name.begin(),name.end()),
614
+ std::forward<Args>(args)...);
615
+ inserted = true;
616
+ }
617
+ return std::make_pair(it,inserted);
618
+ }
619
+
620
+ template <class A=allocator_type, class... Args>
621
+ typename std::enable_if<!traits_extension::is_stateless<A>::value,std::pair<iterator,bool>>::type
622
+ try_emplace(const string_view_type& name, Args&&... args)
623
+ {
624
+ bool inserted;
625
+ auto it = std::lower_bound(members_.begin(),members_.end(), name,
626
+ Comp());
627
+ if (it == members_.end())
628
+ {
629
+ members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()),
630
+ std::forward<Args>(args)...);
631
+ it = members_.begin() + members_.size() - 1;
632
+ inserted = true;
633
+ }
634
+ else if (it->key() == name)
635
+ {
636
+ inserted = false;
637
+ }
638
+ else
639
+ {
640
+ it = members_.emplace(it,
641
+ key_type(name.begin(),name.end(), get_allocator()),
642
+ std::forward<Args>(args)...);
643
+ inserted = true;
644
+ }
645
+ return std::make_pair(it,inserted);
646
+ }
647
+
648
+ template <class A=allocator_type, class ... Args>
649
+ typename std::enable_if<traits_extension::is_stateless<A>::value,iterator>::type
650
+ try_emplace(iterator hint, const string_view_type& name, Args&&... args)
651
+ {
652
+ iterator it = hint;
653
+
654
+ if (hint != members_.end() && hint->key() <= name)
655
+ {
656
+ it = std::lower_bound(hint,members_.end(), name,
657
+ Comp());
658
+ }
659
+ else
660
+ {
661
+ it = std::lower_bound(members_.begin(),members_.end(), name,
662
+ Comp());
663
+ }
664
+
665
+ if (it == members_.end())
666
+ {
667
+ members_.emplace_back(key_type(name.begin(),name.end()),
668
+ std::forward<Args>(args)...);
669
+ it = members_.begin() + (members_.size() - 1);
670
+ }
671
+ else if (it->key() == name)
672
+ {
673
+ }
674
+ else
675
+ {
676
+ it = members_.emplace(it,
677
+ key_type(name.begin(),name.end()),
678
+ std::forward<Args>(args)...);
679
+ }
680
+
681
+ return it;
682
+ }
683
+
684
+ template <class A=allocator_type, class ... Args>
685
+ typename std::enable_if<!traits_extension::is_stateless<A>::value,iterator>::type
686
+ try_emplace(iterator hint, const string_view_type& name, Args&&... args)
687
+ {
688
+ iterator it = hint;
689
+ if (hint != members_.end() && hint->key() <= name)
690
+ {
691
+ it = std::lower_bound(hint,members_.end(), name,
692
+ Comp());
693
+ }
694
+ else
695
+ {
696
+ it = std::lower_bound(members_.begin(),members_.end(), name,
697
+ Comp());
698
+ }
699
+
700
+ if (it == members_.end())
701
+ {
702
+ members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()),
703
+ std::forward<Args>(args)...);
704
+ it = members_.begin() + (members_.size() - 1);
705
+ }
706
+ else if (it->key() == name)
707
+ {
708
+ }
709
+ else
710
+ {
711
+ it = members_.emplace(it,
712
+ key_type(name.begin(),name.end(), get_allocator()),
713
+ std::forward<Args>(args)...);
714
+ }
715
+ return it;
716
+ }
717
+
718
+ // insert_or_assign
719
+
720
+ template <class T, class A=allocator_type>
721
+ typename std::enable_if<traits_extension::is_stateless<A>::value,iterator>::type
722
+ insert_or_assign(iterator hint, const string_view_type& name, T&& value)
723
+ {
724
+ iterator it;
725
+ if (hint != members_.end() && hint->key() <= name)
726
+ {
727
+ it = std::lower_bound(hint,members_.end(), name,
728
+ [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;});
729
+ }
730
+ else
731
+ {
732
+ it = std::lower_bound(members_.begin(),members_.end(), name,
733
+ [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;});
734
+ }
735
+
736
+ if (it == members_.end())
737
+ {
738
+ members_.emplace_back(key_type(name.begin(),name.end()),
739
+ std::forward<T>(value));
740
+ it = members_.begin() + (members_.size() - 1);
741
+ }
742
+ else if (it->key() == name)
743
+ {
744
+ it->value(Json(std::forward<T>(value)));
745
+ }
746
+ else
747
+ {
748
+ it = members_.emplace(it,
749
+ key_type(name.begin(),name.end()),
750
+ std::forward<T>(value));
751
+ }
752
+ return it;
753
+ }
754
+
755
+ template <class T, class A=allocator_type>
756
+ typename std::enable_if<!traits_extension::is_stateless<A>::value,iterator>::type
757
+ insert_or_assign(iterator hint, const string_view_type& name, T&& value)
758
+ {
759
+ iterator it;
760
+ if (hint != members_.end() && hint->key() <= name)
761
+ {
762
+ it = std::lower_bound(hint,members_.end(), name,
763
+ Comp());
764
+ }
765
+ else
766
+ {
767
+ it = std::lower_bound(members_.begin(),members_.end(), name,
768
+ Comp());
769
+ }
770
+
771
+ if (it == members_.end())
772
+ {
773
+ members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()),
774
+ std::forward<T>(value),get_allocator());
775
+ it = members_.begin() + (members_.size() - 1);
776
+ }
777
+ else if (it->key() == name)
778
+ {
779
+ it->value(Json(std::forward<T>(value),get_allocator()));
780
+ }
781
+ else
782
+ {
783
+ it = members_.emplace(it,
784
+ key_type(name.begin(),name.end(), get_allocator()),
785
+ std::forward<T>(value),get_allocator());
786
+ }
787
+ return it;
788
+ }
789
+
790
+ // merge
791
+
792
+ void merge(const sorted_json_object& source)
793
+ {
794
+ for (auto it = source.begin(); it != source.end(); ++it)
795
+ {
796
+ try_emplace(it->key(),it->value());
797
+ }
798
+ }
799
+
800
+ void merge(sorted_json_object&& source)
801
+ {
802
+ auto it = std::make_move_iterator(source.begin());
803
+ auto end = std::make_move_iterator(source.end());
804
+ for (; it != end; ++it)
805
+ {
806
+ auto pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(),
807
+ Comp());
808
+ if (pos == members_.end() )
809
+ {
810
+ members_.emplace_back(*it);
811
+ }
812
+ else if ((*it).key() != pos->key())
813
+ {
814
+ members_.emplace(pos,*it);
815
+ }
816
+ }
817
+ }
818
+
819
+ void merge(iterator hint, const sorted_json_object& source)
820
+ {
821
+ for (auto it = source.begin(); it != source.end(); ++it)
822
+ {
823
+ hint = try_emplace(hint, (*it).key(),(*it).value());
824
+ }
825
+ }
826
+
827
+ void merge(iterator hint, sorted_json_object&& source)
828
+ {
829
+ auto it = std::make_move_iterator(source.begin());
830
+ auto end = std::make_move_iterator(source.end());
831
+ for (; it != end; ++it)
832
+ {
833
+ iterator pos;
834
+ if (hint != members_.end() && hint->key() <= (*it).key())
835
+ {
836
+ pos = std::lower_bound(hint,members_.end(), (*it).key(),
837
+ Comp());
838
+ }
839
+ else
840
+ {
841
+ pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(),
842
+ Comp());
843
+ }
844
+ if (pos == members_.end() )
845
+ {
846
+ members_.emplace_back(*it);
847
+ hint = members_.begin() + (members_.size() - 1);
848
+ }
849
+ else if ((*it).key() != pos->key())
850
+ {
851
+ hint = members_.emplace(pos,*it);
852
+ }
853
+ }
854
+ }
855
+
856
+ // merge_or_update
857
+
858
+ void merge_or_update(const sorted_json_object& source)
859
+ {
860
+ for (auto it = source.begin(); it != source.end(); ++it)
861
+ {
862
+ insert_or_assign((*it).key(),(*it).value());
863
+ }
864
+ }
865
+
866
+ void merge_or_update(sorted_json_object&& source)
867
+ {
868
+ auto it = std::make_move_iterator(source.begin());
869
+ auto end = std::make_move_iterator(source.end());
870
+ for (; it != end; ++it)
871
+ {
872
+ auto pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(),
873
+ Comp());
874
+ if (pos == members_.end() )
875
+ {
876
+ members_.emplace_back(*it);
877
+ }
878
+ else
879
+ {
880
+ pos->value((*it).value());
881
+ }
882
+ }
883
+ }
884
+
885
+ void merge_or_update(iterator hint, const sorted_json_object& source)
886
+ {
887
+ for (auto it = source.begin(); it != source.end(); ++it)
888
+ {
889
+ hint = insert_or_assign(hint, (*it).key(),(*it).value());
890
+ }
891
+ }
892
+
893
+ void merge_or_update(iterator hint, sorted_json_object&& source)
894
+ {
895
+ auto it = std::make_move_iterator(source.begin());
896
+ auto end = std::make_move_iterator(source.end());
897
+ for (; it != end; ++it)
898
+ {
899
+ iterator pos;
900
+ if (hint != members_.end() && hint->key() <= (*it).key())
901
+ {
902
+ pos = std::lower_bound(hint,members_.end(), (*it).key(),
903
+ Comp());
904
+ }
905
+ else
906
+ {
907
+ pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(),
908
+ Comp());
909
+ }
910
+ if (pos == members_.end() )
911
+ {
912
+ members_.emplace_back(*it);
913
+ hint = members_.begin() + (members_.size() - 1);
914
+ }
915
+ else
916
+ {
917
+ pos->value((*it).value());
918
+ hint = pos;
919
+ }
920
+ }
921
+ }
922
+
923
+ bool operator==(const sorted_json_object& rhs) const
924
+ {
925
+ return members_ == rhs.members_;
926
+ }
927
+
928
+ bool operator<(const sorted_json_object& rhs) const
929
+ {
930
+ return members_ < rhs.members_;
931
+ }
932
+ private:
933
+
934
+ void flatten_and_destroy() noexcept
935
+ {
936
+ if (!members_.empty())
937
+ {
938
+ json_array<Json> temp(get_allocator());
939
+
940
+ for (auto& kv : members_)
941
+ {
942
+ switch (kv.value().storage_kind())
943
+ {
944
+ case json_storage_kind::array_value:
945
+ case json_storage_kind::object_value:
946
+ if (!kv.value().empty())
947
+ {
948
+ temp.emplace_back(std::move(kv.value()));
949
+ }
950
+ break;
951
+ default:
952
+ break;
953
+ }
954
+ }
955
+ }
956
+ }
957
+ };
958
+
959
+ // Preserve order
960
+ template <class KeyT,class Json,template<typename,typename> class SequenceContainer = std::vector>
961
+ class order_preserving_json_object : public allocator_holder<typename Json::allocator_type>
962
+ {
963
+ public:
964
+ using allocator_type = typename Json::allocator_type;
965
+ using char_type = typename Json::char_type;
966
+ using key_type = KeyT;
967
+ //using mapped_type = Json;
968
+ using string_view_type = typename Json::string_view_type;
969
+ using key_value_type = key_value<KeyT,Json>;
970
+ //using implementation_policy = typename Json::implementation_policy;
971
+ private:
972
+
973
+ using key_value_allocator_type = typename std::allocator_traits<allocator_type>:: template rebind_alloc<key_value_type>;
974
+ using key_value_container_type = SequenceContainer<key_value_type,key_value_allocator_type>;
975
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<std::size_t> index_allocator_type;
976
+ //using index_container_type = typename implementation_policy::template sequence_container_type<std::size_t,index_allocator_type>;
977
+ using index_container_type = SequenceContainer<std::size_t,index_allocator_type>;
978
+
979
+ key_value_container_type members_;
980
+ index_container_type index_;
981
+
982
+ struct Comp
983
+ {
984
+ const key_value_container_type& members_;
985
+
986
+ Comp(const key_value_container_type& members_)
987
+ : members_(members_)
988
+ {
989
+ }
990
+
991
+ bool operator() (std::size_t i, string_view_type k) const { return members_.at(i).key() < k; }
992
+ bool operator() (string_view_type k, std::size_t i) const { return k < members_.at(i).key(); }
993
+ };
994
+ public:
995
+ using iterator = typename key_value_container_type::iterator;
996
+ using const_iterator = typename key_value_container_type::const_iterator;
997
+
998
+ using allocator_holder<allocator_type>::get_allocator;
999
+
1000
+ order_preserving_json_object()
1001
+ {
1002
+ }
1003
+ order_preserving_json_object(const allocator_type& alloc)
1004
+ : allocator_holder<allocator_type>(alloc),
1005
+ members_(key_value_allocator_type(alloc)),
1006
+ index_(index_allocator_type(alloc))
1007
+ {
1008
+ }
1009
+
1010
+ order_preserving_json_object(const order_preserving_json_object& val)
1011
+ : allocator_holder<allocator_type>(val.get_allocator()),
1012
+ members_(val.members_),
1013
+ index_(val.index_)
1014
+ {
1015
+ }
1016
+
1017
+ order_preserving_json_object(order_preserving_json_object&& val)
1018
+ : allocator_holder<allocator_type>(val.get_allocator()),
1019
+ members_(std::move(val.members_)),
1020
+ index_(std::move(val.index_))
1021
+ {
1022
+ }
1023
+
1024
+ order_preserving_json_object(const order_preserving_json_object& val, const allocator_type& alloc)
1025
+ : allocator_holder<allocator_type>(alloc),
1026
+ members_(val.members_,key_value_allocator_type(alloc)),
1027
+ index_(val.index_,index_allocator_type(alloc))
1028
+ {
1029
+ }
1030
+
1031
+ order_preserving_json_object(order_preserving_json_object&& val,const allocator_type& alloc)
1032
+ : allocator_holder<allocator_type>(alloc),
1033
+ members_(std::move(val.members_),key_value_allocator_type(alloc)),
1034
+ index_(std::move(val.index_),index_allocator_type(alloc))
1035
+ {
1036
+ }
1037
+
1038
+ template<class InputIt>
1039
+ order_preserving_json_object(InputIt first, InputIt last)
1040
+ {
1041
+ std::size_t count = std::distance(first,last);
1042
+ members_.reserve(count);
1043
+ for (auto s = first; s != last; ++s)
1044
+ {
1045
+ members_.emplace_back(get_key_value<KeyT,Json>()(*s));
1046
+ }
1047
+
1048
+ build_index();
1049
+ auto last_unique = std::unique(index_.begin(), index_.end(),
1050
+ [&](std::size_t a, std::size_t b) { return !(members_.at(a).key().compare(members_.at(b).key())); });
1051
+
1052
+ if (last_unique != index_.end())
1053
+ {
1054
+ index_.erase(last_unique, index_.end());
1055
+ std::sort(index_.begin(), index_.end());
1056
+
1057
+ auto result = index_.rbegin();
1058
+ if (*result != members_.size())
1059
+ {
1060
+ members_.erase(members_.begin() + (*result + 1), members_.end());
1061
+ }
1062
+ for (auto it = index_.rbegin() + 1; it != index_.rend(); ++it, ++result)
1063
+ {
1064
+ if (*result - *it > 1)
1065
+ {
1066
+ members_.erase(members_.begin() + (*it + 1), members_.begin() + *result);
1067
+ }
1068
+ }
1069
+ }
1070
+ build_index();
1071
+ }
1072
+
1073
+ template<class InputIt>
1074
+ order_preserving_json_object(InputIt first, InputIt last,
1075
+ const allocator_type& alloc)
1076
+ : allocator_holder<allocator_type>(alloc),
1077
+ members_(key_value_allocator_type(alloc)),
1078
+ index_(index_allocator_type(alloc))
1079
+ {
1080
+ std::size_t count = std::distance(first,last);
1081
+ members_.reserve(count);
1082
+ for (auto s = first; s != last; ++s)
1083
+ {
1084
+ members_.emplace_back(get_key_value<KeyT,Json>()(*s));
1085
+ }
1086
+
1087
+ build_index();
1088
+ auto last_unique = std::unique(index_.begin(), index_.end(),
1089
+ [&](std::size_t a, std::size_t b) { return !(members_.at(a).key().compare(members_.at(b).key())); });
1090
+
1091
+ if (last_unique != index_.end())
1092
+ {
1093
+ index_.erase(last_unique, index_.end());
1094
+ std::sort(index_.begin(), index_.end());
1095
+
1096
+ auto result = index_.rbegin();
1097
+ if (*result != members_.size())
1098
+ {
1099
+ members_.erase(members_.begin() + (*result + 1), members_.end());
1100
+ }
1101
+ for (auto it = index_.rbegin() + 1; it != index_.rend(); ++it, ++result)
1102
+ {
1103
+ if (*result - *it > 1)
1104
+ {
1105
+ members_.erase(members_.begin() + (*it + 1), members_.begin() + *result);
1106
+ }
1107
+ }
1108
+ }
1109
+ build_index();
1110
+ }
1111
+
1112
+ order_preserving_json_object(std::initializer_list<std::pair<std::basic_string<char_type>,Json>> init,
1113
+ const allocator_type& alloc = allocator_type())
1114
+ : allocator_holder<allocator_type>(alloc),
1115
+ members_(key_value_allocator_type(alloc)),
1116
+ index_(index_allocator_type(alloc))
1117
+ {
1118
+ members_.reserve(init.size());
1119
+ for (auto& item : init)
1120
+ {
1121
+ insert_or_assign(item.first, item.second);
1122
+ }
1123
+ }
1124
+
1125
+ ~order_preserving_json_object() noexcept
1126
+ {
1127
+ flatten_and_destroy();
1128
+ }
1129
+
1130
+ order_preserving_json_object& operator=(order_preserving_json_object&& val)
1131
+ {
1132
+ val.swap(*this);
1133
+ return *this;
1134
+ }
1135
+
1136
+ order_preserving_json_object& operator=(const order_preserving_json_object& val)
1137
+ {
1138
+ allocator_holder<allocator_type>::operator=(val.get_allocator());
1139
+ members_ = val.members_;
1140
+ index_ = val.index_;
1141
+ return *this;
1142
+ }
1143
+
1144
+ void swap(order_preserving_json_object& val) noexcept
1145
+ {
1146
+ members_.swap(val.members_);
1147
+ }
1148
+
1149
+ bool empty() const
1150
+ {
1151
+ return members_.empty();
1152
+ }
1153
+
1154
+ iterator begin()
1155
+ {
1156
+ return members_.begin();
1157
+ }
1158
+
1159
+ iterator end()
1160
+ {
1161
+ return members_.end();
1162
+ }
1163
+
1164
+ const_iterator begin() const
1165
+ {
1166
+ return members_.begin();
1167
+ }
1168
+
1169
+ const_iterator end() const
1170
+ {
1171
+ return members_.end();
1172
+ }
1173
+
1174
+ std::size_t size() const {return members_.size();}
1175
+
1176
+ std::size_t capacity() const {return members_.capacity();}
1177
+
1178
+ void clear()
1179
+ {
1180
+ members_.clear();
1181
+ index_.clear();
1182
+ }
1183
+
1184
+ void shrink_to_fit()
1185
+ {
1186
+ for (std::size_t i = 0; i < members_.size(); ++i)
1187
+ {
1188
+ members_[i].shrink_to_fit();
1189
+ }
1190
+ members_.shrink_to_fit();
1191
+ index_.shrink_to_fit();
1192
+ }
1193
+
1194
+ void reserve(std::size_t n) {members_.reserve(n);}
1195
+
1196
+ Json& at(std::size_t i)
1197
+ {
1198
+ if (i >= members_.size())
1199
+ {
1200
+ JSONCONS_THROW(json_runtime_error<std::out_of_range>("Invalid array subscript"));
1201
+ }
1202
+ return members_[i].value();
1203
+ }
1204
+
1205
+ const Json& at(std::size_t i) const
1206
+ {
1207
+ if (i >= members_.size())
1208
+ {
1209
+ JSONCONS_THROW(json_runtime_error<std::out_of_range>("Invalid array subscript"));
1210
+ }
1211
+ return members_[i].value();
1212
+ }
1213
+
1214
+ iterator find(const string_view_type& name) noexcept
1215
+ {
1216
+ auto p = std::equal_range(index_.begin(),index_.end(), name,
1217
+ Comp(members_));
1218
+ return p.first == p.second ? members_.end() : members_.begin() + *p.first;
1219
+ }
1220
+
1221
+ const_iterator find(const string_view_type& name) const noexcept
1222
+ {
1223
+ auto p = std::equal_range(index_.begin(),index_.end(), name,
1224
+ Comp(members_));
1225
+ return p.first == p.second ? members_.end() : members_.begin() + *p.first;
1226
+ }
1227
+
1228
+ iterator erase(const_iterator pos)
1229
+ {
1230
+ if (pos != members_.end())
1231
+ {
1232
+ std::size_t pos1 = pos - members_.begin();
1233
+ std::size_t pos2 = pos1 + 1;
1234
+
1235
+ erase_index_entries(pos1, pos2);
1236
+ #if defined(JSONCONS_NO_VECTOR_ERASE_TAKES_CONST_ITERATOR)
1237
+ iterator it = members_.begin() + (pos - members_.begin());
1238
+ return members_.erase(it);
1239
+ #else
1240
+ return members_.erase(pos);
1241
+ #endif
1242
+ }
1243
+ else
1244
+ {
1245
+ return members_.end();
1246
+ }
1247
+ }
1248
+
1249
+ iterator erase(const_iterator first, const_iterator last)
1250
+ {
1251
+ std::size_t pos1 = first == members_.end() ? members_.size() : first - members_.begin();
1252
+ std::size_t pos2 = last == members_.end() ? members_.size() : last - members_.begin();
1253
+
1254
+ if (pos1 < members_.size() && pos2 <= members_.size())
1255
+ {
1256
+ erase_index_entries(pos1,pos2);
1257
+
1258
+ #if defined(JSONCONS_NO_VECTOR_ERASE_TAKES_CONST_ITERATOR)
1259
+ iterator it1 = members_.begin() + (first - members_.begin());
1260
+ iterator it2 = members_.begin() + (last - members_.begin());
1261
+ return members_.erase(it1,it2);
1262
+ #else
1263
+ return members_.erase(first,last);
1264
+ #endif
1265
+ }
1266
+ else
1267
+ {
1268
+ return members_.end();
1269
+ }
1270
+ }
1271
+
1272
+ void erase(const string_view_type& name)
1273
+ {
1274
+ auto pos = find(name);
1275
+ if (pos != members_.end())
1276
+ {
1277
+ std::size_t pos1 = pos - members_.begin();
1278
+ std::size_t pos2 = pos1 + 1;
1279
+
1280
+ erase_index_entries(pos1, pos2);
1281
+ #if defined(JSONCONS_NO_VECTOR_ERASE_TAKES_CONST_ITERATOR)
1282
+ iterator it = members_.begin() + (pos - members_.begin());
1283
+ members_.erase(it);
1284
+ #else
1285
+ members_.erase(pos);
1286
+ #endif
1287
+ }
1288
+ }
1289
+
1290
+ template<class InputIt, class Convert>
1291
+ void insert(InputIt first, InputIt last, Convert convert)
1292
+ {
1293
+ std::size_t count = std::distance(first,last);
1294
+ members_.reserve(members_.size() + count);
1295
+ for (auto s = first; s != last; ++s)
1296
+ {
1297
+ members_.emplace_back(convert(*s));
1298
+ }
1299
+
1300
+ build_index();
1301
+ auto last_unique = std::unique(index_.begin(), index_.end(),
1302
+ [&](std::size_t a, std::size_t b) { return !(members_.at(a).key().compare(members_.at(b).key())); });
1303
+
1304
+ if (last_unique != index_.end())
1305
+ {
1306
+ index_.erase(last_unique, index_.end());
1307
+ std::sort(index_.begin(), index_.end());
1308
+
1309
+ auto result = index_.rbegin();
1310
+ if (*result != members_.size())
1311
+ {
1312
+ members_.erase(members_.begin() + (*result + 1), members_.end());
1313
+ }
1314
+ for (auto it = index_.rbegin() + 1; it != index_.rend(); ++it, ++result)
1315
+ {
1316
+ if (*result - *it > 1)
1317
+ {
1318
+ members_.erase(members_.begin() + (*it + 1), members_.begin() + *result);
1319
+ }
1320
+ }
1321
+ }
1322
+ build_index();
1323
+ }
1324
+
1325
+ template<class InputIt, class Convert>
1326
+ void insert(sorted_unique_range_tag, InputIt first, InputIt last, Convert convert)
1327
+ {
1328
+ std::size_t count = std::distance(first,last);
1329
+
1330
+ members_.reserve(members_.size() + count);
1331
+ for (auto s = first; s != last; ++s)
1332
+ {
1333
+ members_.emplace_back(convert(*s));
1334
+ }
1335
+
1336
+ build_index();
1337
+ }
1338
+
1339
+ template <class T, class A=allocator_type>
1340
+ typename std::enable_if<traits_extension::is_stateless<A>::value,std::pair<iterator,bool>>::type
1341
+ insert_or_assign(const string_view_type& name, T&& value)
1342
+ {
1343
+ auto result = insert_index_entry(name,members_.size());
1344
+ if (result.second)
1345
+ {
1346
+ members_.emplace_back(key_type(name.begin(), name.end()), std::forward<T>(value));
1347
+ auto it = members_.begin() + result.first;
1348
+ return std::make_pair(it,true);
1349
+ }
1350
+ else
1351
+ {
1352
+ auto it = members_.begin() + result.first;
1353
+ it->value(Json(std::forward<T>(value)));
1354
+ return std::make_pair(it,false);
1355
+ }
1356
+ }
1357
+
1358
+ template <class T, class A=allocator_type>
1359
+ typename std::enable_if<!traits_extension::is_stateless<A>::value,std::pair<iterator,bool>>::type
1360
+ insert_or_assign(const string_view_type& name, T&& value)
1361
+ {
1362
+ auto result = insert_index_entry(name,members_.size());
1363
+ if (result.second)
1364
+ {
1365
+ members_.emplace_back(key_type(name.begin(),name.end(),get_allocator()),
1366
+ std::forward<T>(value),get_allocator());
1367
+ auto it = members_.begin() + result.first;
1368
+ return std::make_pair(it,true);
1369
+ }
1370
+ else
1371
+ {
1372
+ auto it = members_.begin() + result.first;
1373
+ it->value(Json(std::forward<T>(value),get_allocator()));
1374
+ return std::make_pair(it,false);
1375
+ }
1376
+ }
1377
+
1378
+ template <class A=allocator_type, class T>
1379
+ typename std::enable_if<traits_extension::is_stateless<A>::value,iterator>::type
1380
+ insert_or_assign(iterator hint, const string_view_type& key, T&& value)
1381
+ {
1382
+ if (hint == members_.end())
1383
+ {
1384
+ auto result = insert_or_assign(key, std::forward<T>(value));
1385
+ return result.first;
1386
+ }
1387
+ else
1388
+ {
1389
+ std::size_t pos = hint - members_.begin();
1390
+ auto result = insert_index_entry(key,pos);
1391
+
1392
+ if (result.second)
1393
+ {
1394
+ auto it = members_.emplace(hint, key_type(key.begin(), key.end()), std::forward<T>(value));
1395
+ return it;
1396
+ }
1397
+ else
1398
+ {
1399
+ auto it = members_.begin() + result.first;
1400
+ it->value(Json(std::forward<T>(value)));
1401
+ return it;
1402
+ }
1403
+ }
1404
+ }
1405
+
1406
+ template <class A=allocator_type, class T>
1407
+ typename std::enable_if<!traits_extension::is_stateless<A>::value,iterator>::type
1408
+ insert_or_assign(iterator hint, const string_view_type& key, T&& value)
1409
+ {
1410
+ if (hint == members_.end())
1411
+ {
1412
+ auto result = insert_or_assign(key, std::forward<T>(value));
1413
+ return result.first;
1414
+ }
1415
+ else
1416
+ {
1417
+ std::size_t pos = hint - members_.begin();
1418
+ auto result = insert_index_entry(key,pos);
1419
+
1420
+ if (result.second)
1421
+ {
1422
+ auto it = members_.emplace(hint,
1423
+ key_type(key.begin(),key.end(),get_allocator()),
1424
+ std::forward<T>(value),get_allocator());
1425
+ return it;
1426
+ }
1427
+ else
1428
+ {
1429
+ auto it = members_.begin() + result.first;
1430
+ it->value(Json(std::forward<T>(value),get_allocator()));
1431
+ return it;
1432
+ }
1433
+ }
1434
+ }
1435
+
1436
+ // merge
1437
+
1438
+ void merge(const order_preserving_json_object& source)
1439
+ {
1440
+ for (auto it = source.begin(); it != source.end(); ++it)
1441
+ {
1442
+ try_emplace((*it).key(),(*it).value());
1443
+ }
1444
+ }
1445
+
1446
+ void merge(order_preserving_json_object&& source)
1447
+ {
1448
+ auto it = std::make_move_iterator(source.begin());
1449
+ auto end = std::make_move_iterator(source.end());
1450
+ for (; it != end; ++it)
1451
+ {
1452
+ auto pos = find((*it).key());
1453
+ if (pos == members_.end() )
1454
+ {
1455
+ try_emplace((*it).key(),std::move((*it).value()));
1456
+ }
1457
+ }
1458
+ }
1459
+
1460
+ void merge(iterator hint, const order_preserving_json_object& source)
1461
+ {
1462
+ std::size_t pos = hint - members_.begin();
1463
+ for (auto it = source.begin(); it != source.end(); ++it)
1464
+ {
1465
+ hint = try_emplace(hint, (*it).key(),(*it).value());
1466
+ std::size_t newpos = hint - members_.begin();
1467
+ if (newpos == pos)
1468
+ {
1469
+ ++hint;
1470
+ pos = hint - members_.begin();
1471
+ }
1472
+ else
1473
+ {
1474
+ hint = members_.begin() + pos;
1475
+ }
1476
+ }
1477
+ }
1478
+
1479
+ void merge(iterator hint, order_preserving_json_object&& source)
1480
+ {
1481
+ std::size_t pos = hint - members_.begin();
1482
+
1483
+ auto it = std::make_move_iterator(source.begin());
1484
+ auto end = std::make_move_iterator(source.end());
1485
+ for (; it != end; ++it)
1486
+ {
1487
+ hint = try_emplace(hint, (*it).key(), std::move((*it).value()));
1488
+ std::size_t newpos = hint - members_.begin();
1489
+ if (newpos == pos)
1490
+ {
1491
+ ++hint;
1492
+ pos = hint - members_.begin();
1493
+ }
1494
+ else
1495
+ {
1496
+ hint = members_.begin() + pos;
1497
+ }
1498
+ }
1499
+ }
1500
+
1501
+ // merge_or_update
1502
+
1503
+ void merge_or_update(const order_preserving_json_object& source)
1504
+ {
1505
+ for (auto it = source.begin(); it != source.end(); ++it)
1506
+ {
1507
+ insert_or_assign((*it).key(),(*it).value());
1508
+ }
1509
+ }
1510
+
1511
+ void merge_or_update(order_preserving_json_object&& source)
1512
+ {
1513
+ auto it = std::make_move_iterator(source.begin());
1514
+ auto end = std::make_move_iterator(source.end());
1515
+ for (; it != end; ++it)
1516
+ {
1517
+ auto pos = find((*it).key());
1518
+ if (pos == members_.end() )
1519
+ {
1520
+ insert_or_assign((*it).key(),std::move((*it).value()));
1521
+ }
1522
+ else
1523
+ {
1524
+ pos->value(std::move((*it).value()));
1525
+ }
1526
+ }
1527
+ }
1528
+
1529
+ void merge_or_update(iterator hint, const order_preserving_json_object& source)
1530
+ {
1531
+ std::size_t pos = hint - members_.begin();
1532
+ for (auto it = source.begin(); it != source.end(); ++it)
1533
+ {
1534
+ hint = insert_or_assign(hint, (*it).key(),(*it).value());
1535
+ std::size_t newpos = hint - members_.begin();
1536
+ if (newpos == pos)
1537
+ {
1538
+ ++hint;
1539
+ pos = hint - members_.begin();
1540
+ }
1541
+ else
1542
+ {
1543
+ hint = members_.begin() + pos;
1544
+ }
1545
+ }
1546
+ }
1547
+
1548
+ void merge_or_update(iterator hint, order_preserving_json_object&& source)
1549
+ {
1550
+ std::size_t pos = hint - members_.begin();
1551
+ auto it = std::make_move_iterator(source.begin());
1552
+ auto end = std::make_move_iterator(source.end());
1553
+ for (; it != end; ++it)
1554
+ {
1555
+ hint = insert_or_assign(hint, (*it).key(), std::move((*it).value()));
1556
+ std::size_t newpos = hint - members_.begin();
1557
+ if (newpos == pos)
1558
+ {
1559
+ ++hint;
1560
+ pos = hint - members_.begin();
1561
+ }
1562
+ else
1563
+ {
1564
+ hint = members_.begin() + pos;
1565
+ }
1566
+ }
1567
+ }
1568
+
1569
+ // try_emplace
1570
+
1571
+ template <class A=allocator_type, class... Args>
1572
+ typename std::enable_if<traits_extension::is_stateless<A>::value,std::pair<iterator,bool>>::type
1573
+ try_emplace(const string_view_type& name, Args&&... args)
1574
+ {
1575
+ auto result = insert_index_entry(name,members_.size());
1576
+ if (result.second)
1577
+ {
1578
+ members_.emplace_back(key_type(name.begin(), name.end()), std::forward<Args>(args)...);
1579
+ auto it = members_.begin() + result.first;
1580
+ return std::make_pair(it,true);
1581
+ }
1582
+ else
1583
+ {
1584
+ auto it = members_.begin() + result.first;
1585
+ return std::make_pair(it,false);
1586
+ }
1587
+ }
1588
+
1589
+ template <class A=allocator_type, class... Args>
1590
+ typename std::enable_if<!traits_extension::is_stateless<A>::value,std::pair<iterator,bool>>::type
1591
+ try_emplace(const string_view_type& key, Args&&... args)
1592
+ {
1593
+ auto result = insert_index_entry(key,members_.size());
1594
+ if (result.second)
1595
+ {
1596
+ members_.emplace_back(key_type(key.begin(),key.end(), get_allocator()),
1597
+ std::forward<Args>(args)...);
1598
+ auto it = members_.begin() + result.first;
1599
+ return std::make_pair(it,true);
1600
+ }
1601
+ else
1602
+ {
1603
+ auto it = members_.begin() + result.first;
1604
+ return std::make_pair(it,false);
1605
+ }
1606
+ }
1607
+
1608
+ template <class A=allocator_type, class ... Args>
1609
+ typename std::enable_if<traits_extension::is_stateless<A>::value,iterator>::type
1610
+ try_emplace(iterator hint, const string_view_type& key, Args&&... args)
1611
+ {
1612
+ if (hint == members_.end())
1613
+ {
1614
+ auto result = try_emplace(key, std::forward<Args>(args)...);
1615
+ return result.first;
1616
+ }
1617
+ else
1618
+ {
1619
+ std::size_t pos = hint - members_.begin();
1620
+ auto result = insert_index_entry(key, pos);
1621
+
1622
+ if (result.second)
1623
+ {
1624
+ auto it = members_.emplace(hint, key_type(key.begin(), key.end()), std::forward<Args>(args)...);
1625
+ return it;
1626
+ }
1627
+ else
1628
+ {
1629
+ auto it = members_.begin() + result.first;
1630
+ return it;
1631
+ }
1632
+ }
1633
+ }
1634
+
1635
+ template <class A=allocator_type, class ... Args>
1636
+ typename std::enable_if<!traits_extension::is_stateless<A>::value,iterator>::type
1637
+ try_emplace(iterator hint, const string_view_type& key, Args&&... args)
1638
+ {
1639
+ if (hint == members_.end())
1640
+ {
1641
+ auto result = try_emplace(key, std::forward<Args>(args)...);
1642
+ return result.first;
1643
+ }
1644
+ else
1645
+ {
1646
+ std::size_t pos = hint - members_.begin();
1647
+ auto result = insert_index_entry(key, pos);
1648
+
1649
+ if (result.second)
1650
+ {
1651
+ auto it = members_.emplace(hint,
1652
+ key_type(key.begin(),key.end(), get_allocator()),
1653
+ std::forward<Args>(args)...);
1654
+ return it;
1655
+ }
1656
+ else
1657
+ {
1658
+ auto it = members_.begin() + result.first;
1659
+ return it;
1660
+ }
1661
+ }
1662
+ }
1663
+
1664
+ bool operator==(const order_preserving_json_object& rhs) const
1665
+ {
1666
+ return members_ == rhs.members_;
1667
+ }
1668
+
1669
+ bool operator<(const order_preserving_json_object& rhs) const
1670
+ {
1671
+ return members_ < rhs.members_;
1672
+ }
1673
+ private:
1674
+
1675
+ void flatten_and_destroy() noexcept
1676
+ {
1677
+ if (!members_.empty())
1678
+ {
1679
+ json_array<Json> temp(get_allocator());
1680
+
1681
+ for (auto&& kv : members_)
1682
+ {
1683
+ if (kv.value().size() > 0)
1684
+ {
1685
+ temp.emplace_back(std::move(kv.value()));
1686
+ }
1687
+ }
1688
+ }
1689
+ }
1690
+
1691
+ std::pair<std::size_t,bool> insert_index_entry(const string_view_type& key, std::size_t pos)
1692
+ {
1693
+ JSONCONS_ASSERT(pos <= index_.size());
1694
+
1695
+ auto it = std::lower_bound(index_.begin(),index_.end(), key,
1696
+ Comp(members_));
1697
+
1698
+ if (it == index_.end())
1699
+ {
1700
+ std::size_t count = index_.size() - pos;
1701
+ for (std::size_t i = 0; count > 0 && i < index_.size(); ++i)
1702
+ {
1703
+ if (index_[i] >= pos)
1704
+ {
1705
+ ++index_[i];
1706
+ --count;
1707
+ }
1708
+ }
1709
+ index_.push_back(pos);
1710
+ return std::make_pair(pos,true);
1711
+ }
1712
+ else if (members_.at(*it).key() != key)
1713
+ {
1714
+ std::size_t count = index_.size() - pos;
1715
+ for (std::size_t i = 0; count > 0 && i < index_.size(); ++i)
1716
+ {
1717
+ if (index_[i] >= pos)
1718
+ {
1719
+ ++index_[i];
1720
+ --count;
1721
+ }
1722
+ }
1723
+ auto it2 = index_.insert(it, pos);
1724
+ return std::make_pair(*it2,true);
1725
+ }
1726
+ else
1727
+ {
1728
+ return std::make_pair(*it,false);
1729
+ }
1730
+ }
1731
+
1732
+ void erase_index_entries(std::size_t pos1, std::size_t pos2)
1733
+ {
1734
+ JSONCONS_ASSERT(pos1 <= pos2);
1735
+ JSONCONS_ASSERT(pos2 <= index_.size());
1736
+
1737
+ const size_t offset = pos2 - pos1;
1738
+ const size_t n = index_.size() - offset;
1739
+ for (std::size_t i = 0; i < index_.size(); ++i)
1740
+ {
1741
+ if (index_[i] >= pos1 && index_[i] < pos2)
1742
+ {
1743
+ index_.erase(index_.begin()+i);
1744
+ --i;
1745
+ }
1746
+ }
1747
+ for (std::size_t i = 0; i < index_.size(); ++i)
1748
+ {
1749
+ if (index_[i] >= pos2)
1750
+ {
1751
+ index_[i] -= offset;
1752
+ }
1753
+ }
1754
+ JSONCONS_ASSERT(index_.size() == n);
1755
+ }
1756
+
1757
+ void build_index()
1758
+ {
1759
+ index_.clear();
1760
+ index_.reserve(members_.size());
1761
+ for (std::size_t i = 0; i < members_.size(); ++i)
1762
+ {
1763
+ index_.push_back(i);
1764
+ }
1765
+ std::stable_sort(index_.begin(),index_.end(),
1766
+ [&](std::size_t a, std::size_t b) -> bool {return members_.at(a).key().compare(members_.at(b).key()) < 0;});
1767
+ }
1768
+ };
1769
+
1770
+ } // namespace jsoncons
1771
+
1772
+ #endif