Coverage Report

Created: 2025-11-09 06:43

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