jsoncons 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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