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