Coverage Report

Created: 2026-02-14 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jsoncons/include/jsoncons/json_array.hpp
Line
Count
Source
1
// Copyright 2013-2026 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_ARRAY_HPP
8
#define JSONCONS_JSON_ARRAY_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 <type_traits> // std::enable_if
17
#include <utility>
18
#include <utility> // std::move
19
#include <vector>
20
21
#include <jsoncons/allocator_holder.hpp>
22
#include <jsoncons/json_type.hpp>
23
24
namespace jsoncons {
25
26
    // json_array
27
28
    template <typename Json,template <typename,typename> class SequenceContainer = std::vector>
29
    class json_array : public allocator_holder<typename Json::allocator_type>
30
    {
31
    public:
32
        using allocator_type = typename Json::allocator_type;
33
        using value_type = Json;
34
    private:
35
        using value_allocator_type = typename std::allocator_traits<allocator_type>:: template rebind_alloc<value_type>;                   
36
        using value_container_type = SequenceContainer<value_type,value_allocator_type>;
37
        value_container_type elements_;
38
    public:
39
        using iterator = typename value_container_type::iterator;
40
        using const_iterator = typename value_container_type::const_iterator;
41
        using reference = typename std::iterator_traits<iterator>::reference;
42
        using const_reference = typename std::iterator_traits<const_iterator>::reference;
43
44
        using allocator_holder<allocator_type>::get_allocator;
45
46
        json_array()
47
5.58M
        {
48
5.58M
        }
49
50
        explicit json_array(const allocator_type& alloc)
51
16.1k
            : allocator_holder<allocator_type>(alloc), 
52
16.1k
              elements_(value_allocator_type(alloc))
53
16.1k
        {
54
16.1k
        }
55
56
        explicit json_array(std::size_t n, 
57
                            const allocator_type& alloc = allocator_type())
58
            : allocator_holder<allocator_type>(alloc), 
59
              elements_(n,Json(),value_allocator_type(alloc))
60
        {
61
        }
62
63
        explicit json_array(std::size_t n, 
64
                            const Json& value, 
65
                            const allocator_type& alloc = allocator_type())
66
            : allocator_holder<allocator_type>(alloc), 
67
              elements_(n,value,value_allocator_type(alloc))
68
        {
69
        }
70
71
        template <typename InputIterator>
72
        json_array(InputIterator begin, InputIterator end, const allocator_type& alloc = allocator_type())
73
            : allocator_holder<allocator_type>(alloc), 
74
              elements_(begin,end,value_allocator_type(alloc))
75
        {
76
        }
77
78
        json_array(const json_array& other)
79
            : allocator_holder<allocator_type>(other.get_allocator()),
80
              elements_(other.elements_)
81
        {
82
        }
83
        json_array(const json_array& other, const allocator_type& alloc)
84
            : allocator_holder<allocator_type>(alloc), 
85
              elements_(other.elements_,value_allocator_type(alloc))
86
        {
87
        }
88
89
        json_array(json_array&& other) noexcept
90
            : allocator_holder<allocator_type>(other.get_allocator()), 
91
              elements_(std::move(other.elements_))
92
        {
93
        }
94
        json_array(json_array&& other, const allocator_type& alloc)
95
            : allocator_holder<allocator_type>(alloc), 
96
              elements_(std::move(other.elements_),value_allocator_type(alloc))
97
        {
98
        }
99
100
        json_array(const std::initializer_list<Json>& init, 
101
                   const allocator_type& alloc = allocator_type())
102
            : allocator_holder<allocator_type>(alloc), 
103
              elements_(init,value_allocator_type(alloc))
104
        {
105
        }
106
        ~json_array() noexcept
107
5.60M
        {
108
5.60M
            flatten_and_destroy();
109
5.60M
        }
110
111
        reference back()
112
        {
113
            return elements_.back();
114
        }
115
116
        const_reference back() const
117
        {
118
            return elements_.back();
119
        }
120
121
        void pop_back()
122
        {
123
            elements_.pop_back();
124
        }
125
126
        bool empty() const
127
152k
        {
128
152k
            return elements_.empty();
129
152k
        }
jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::empty() const
Line
Count
Source
127
152k
        {
128
152k
            return elements_.empty();
129
152k
        }
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::empty() const
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<char, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::empty() const
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::empty() const
130
131
        void swap(json_array& other) noexcept
132
        {
133
            elements_.swap(other.elements_);
134
        }
135
136
        std::size_t size() const {return elements_.size();}
137
138
        std::size_t capacity() const {return elements_.capacity();}
139
140
51.4k
        void clear() {elements_.clear();}
jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::clear()
Line
Count
Source
140
51.4k
        void clear() {elements_.clear();}
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::clear()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<char, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::clear()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::clear()
141
142
        void shrink_to_fit() 
143
        {
144
            for (std::size_t i = 0; i < elements_.size(); ++i)
145
            {
146
                elements_[i].shrink_to_fit();
147
            }
148
            elements_.shrink_to_fit();
149
        }
150
151
23.6k
        void reserve(std::size_t n) {elements_.reserve(n);}
jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::reserve(unsigned long)
Line
Count
Source
151
23.6k
        void reserve(std::size_t n) {elements_.reserve(n);}
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::reserve(unsigned long)
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<char, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::reserve(unsigned long)
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::reserve(unsigned long)
152
153
        void resize(std::size_t n) {elements_.resize(n);}
154
155
        void resize(std::size_t n, const Json& val) {elements_.resize(n,val);}
156
157
        iterator erase(const_iterator pos) 
158
        {
159
            return elements_.erase(pos);
160
        }
161
162
        iterator erase(const_iterator first, const_iterator last) 
163
        {
164
            return elements_.erase(first,last);
165
        }
166
167
        Json& operator[](std::size_t i) {return elements_[i];}
168
169
        const Json& operator[](std::size_t i) const {return elements_[i];}
170
171
        // push_back
172
173
        template <typename T,typename A=allocator_type>
174
        typename std::enable_if<std::allocator_traits<A>::is_always_equal::value,void>::type 
175
        push_back(T&& value)
176
2.84M
        {
177
2.84M
            elements_.emplace_back(std::forward<T>(value));
178
2.84M
        }
_ZN8jsoncons10json_arrayINS_10basic_jsonIcNS_13sorted_policyENSt3__19allocatorIcEEEENS3_6vectorEE9push_backIS6_S5_EENS3_9enable_ifIXsr3std16allocator_traitsIT0_E15is_always_equalE5valueEvE4typeEOT_
Line
Count
Source
176
2.84M
        {
177
2.84M
            elements_.emplace_back(std::forward<T>(value));
178
2.84M
        }
Unexecuted instantiation: _ZN8jsoncons10json_arrayINS_10basic_jsonIwNS_13sorted_policyENSt3__19allocatorIcEEEENS3_6vectorEE9push_backIS6_S5_EENS3_9enable_ifIXsr3std16allocator_traitsIT0_E15is_always_equalE5valueEvE4typeEOT_
Unexecuted instantiation: _ZN8jsoncons10json_arrayINS_10basic_jsonIcNS_23order_preserving_policyENSt3__19allocatorIcEEEENS3_6vectorEE9push_backIS6_S5_EENS3_9enable_ifIXsr3std16allocator_traitsIT0_E15is_always_equalE5valueEvE4typeEOT_
Unexecuted instantiation: _ZN8jsoncons10json_arrayINS_10basic_jsonIwNS_23order_preserving_policyENSt3__19allocatorIcEEEENS3_6vectorEE9push_backIS6_S5_EENS3_9enable_ifIXsr3std16allocator_traitsIT0_E15is_always_equalE5valueEvE4typeEOT_
179
180
        template <typename T,typename A=allocator_type>
181
        typename std::enable_if<!std::allocator_traits<A>::is_always_equal::value,void>::type 
182
        push_back(T&& value)
183
        {
184
            elements_.emplace_back(std::forward<T>(value));
185
        }
186
187
        template <typename T,typename A=allocator_type>
188
        typename std::enable_if<std::allocator_traits<A>::is_always_equal::value,iterator>::type 
189
        insert(const_iterator pos, T&& value)
190
        {
191
            return elements_.emplace(pos, std::forward<T>(value));
192
        }
193
        template <typename T,typename A=allocator_type>
194
        typename std::enable_if<!std::allocator_traits<A>::is_always_equal::value,iterator>::type 
195
        insert(const_iterator pos, T&& value)
196
        {
197
            return elements_.emplace(pos, std::forward<T>(value));
198
        }
199
200
        template <typename InputIt>
201
        iterator insert(const_iterator pos, InputIt first, InputIt last)
202
        {
203
            return elements_.insert(pos, first, last);
204
        }
205
206
        template <typename A=allocator_type,typename... Args>
207
        typename std::enable_if<std::allocator_traits<A>::is_always_equal::value,iterator>::type 
208
        emplace(const_iterator pos, Args&&... args)
209
        {
210
            return elements_.emplace(pos, std::forward<Args>(args)...);
211
        }
212
213
        template <typename... Args>
214
        Json& emplace_back(Args&&... args)
215
5.46k
        {
216
5.46k
            elements_.emplace_back(std::forward<Args>(args)...);
217
5.46k
            return elements_.back();
218
5.46k
        }
jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >& jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::emplace_back<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> > >(jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >&&)
Line
Count
Source
215
5.46k
        {
216
5.46k
            elements_.emplace_back(std::forward<Args>(args)...);
217
5.46k
            return elements_.back();
218
5.46k
        }
Unexecuted instantiation: jsoncons::basic_json<wchar_t, jsoncons::sorted_policy, std::__1::allocator<char> >& jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::emplace_back<jsoncons::basic_json<wchar_t, jsoncons::sorted_policy, std::__1::allocator<char> > >(jsoncons::basic_json<wchar_t, jsoncons::sorted_policy, std::__1::allocator<char> >&&)
Unexecuted instantiation: jsoncons::basic_json<char, jsoncons::order_preserving_policy, std::__1::allocator<char> >& jsoncons::json_array<jsoncons::basic_json<char, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::emplace_back<jsoncons::basic_json<char, jsoncons::order_preserving_policy, std::__1::allocator<char> > >(jsoncons::basic_json<char, jsoncons::order_preserving_policy, std::__1::allocator<char> >&&)
Unexecuted instantiation: jsoncons::basic_json<wchar_t, jsoncons::order_preserving_policy, std::__1::allocator<char> >& jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::emplace_back<jsoncons::basic_json<wchar_t, jsoncons::order_preserving_policy, std::__1::allocator<char> > >(jsoncons::basic_json<wchar_t, jsoncons::order_preserving_policy, std::__1::allocator<char> >&&)
219
220
51.4k
        iterator begin() {return elements_.begin();}
jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::begin()
Line
Count
Source
220
51.4k
        iterator begin() {return elements_.begin();}
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::begin()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<char, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::begin()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::begin()
221
222
51.4k
        iterator end() {return elements_.end();}
jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::end()
Line
Count
Source
222
51.4k
        iterator end() {return elements_.end();}
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::end()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<char, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::end()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::end()
223
224
        const_iterator begin() const {return elements_.begin();}
225
226
        const_iterator end() const {return elements_.end();}
227
228
        bool operator==(const json_array& rhs) const noexcept
229
        {
230
            return elements_ == rhs.elements_;
231
        }
232
233
        bool operator<(const json_array& rhs) const noexcept
234
        {
235
            return elements_ < rhs.elements_;
236
        }
237
238
        json_array& operator=(const json_array& other)
239
        {
240
            elements_ = other.elements_;
241
            return *this;
242
        }
243
    private:
244
245
        void flatten_and_destroy() noexcept
246
5.60M
        {
247
6.60M
            while (!elements_.empty())
248
1.00M
            {
249
1.00M
                value_type current = std::move(elements_.back());
250
1.00M
                elements_.pop_back();
251
1.00M
                switch (current.storage_kind())
252
1.00M
                {
253
51.4k
                    case json_storage_kind::array:
254
51.4k
                    {
255
51.4k
                        for (auto&& item : current.array_range())
256
1.88M
                        {
257
1.88M
                            if ((item.storage_kind() == json_storage_kind::array || item.storage_kind() == json_storage_kind::object)
258
156k
                                && !item.empty()) // non-empty object or array
259
18.5k
                            {
260
18.5k
                                elements_.push_back(std::move(item));
261
18.5k
                            }
262
1.88M
                        }
263
51.4k
                        current.clear();                           
264
51.4k
                        break;
265
0
                    }
266
348k
                    case json_storage_kind::object:
267
348k
                    {
268
348k
                        for (auto&& kv : current.object_range())
269
80.4k
                        {
270
80.4k
                            if ((kv.value().storage_kind() == json_storage_kind::array || kv.value().storage_kind() == json_storage_kind::object)
271
18.9k
                                && !kv.value().empty()) // non-empty object or array
272
15.7k
                            {
273
15.7k
                                elements_.push_back(std::move(kv.value()));
274
15.7k
                            }
275
80.4k
                        }
276
348k
                        current.clear();                           
277
348k
                        break;
278
0
                    }
279
600k
                    default:
280
600k
                        break;
281
1.00M
                }
282
1.00M
            }
283
5.60M
        }
jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::flatten_and_destroy()
Line
Count
Source
246
5.60M
        {
247
6.60M
            while (!elements_.empty())
248
1.00M
            {
249
1.00M
                value_type current = std::move(elements_.back());
250
1.00M
                elements_.pop_back();
251
1.00M
                switch (current.storage_kind())
252
1.00M
                {
253
51.4k
                    case json_storage_kind::array:
254
51.4k
                    {
255
51.4k
                        for (auto&& item : current.array_range())
256
1.88M
                        {
257
1.88M
                            if ((item.storage_kind() == json_storage_kind::array || item.storage_kind() == json_storage_kind::object)
258
156k
                                && !item.empty()) // non-empty object or array
259
18.5k
                            {
260
18.5k
                                elements_.push_back(std::move(item));
261
18.5k
                            }
262
1.88M
                        }
263
51.4k
                        current.clear();                           
264
51.4k
                        break;
265
0
                    }
266
348k
                    case json_storage_kind::object:
267
348k
                    {
268
348k
                        for (auto&& kv : current.object_range())
269
80.4k
                        {
270
80.4k
                            if ((kv.value().storage_kind() == json_storage_kind::array || kv.value().storage_kind() == json_storage_kind::object)
271
18.9k
                                && !kv.value().empty()) // non-empty object or array
272
15.7k
                            {
273
15.7k
                                elements_.push_back(std::move(kv.value()));
274
15.7k
                            }
275
80.4k
                        }
276
348k
                        current.clear();                           
277
348k
                        break;
278
0
                    }
279
600k
                    default:
280
600k
                        break;
281
1.00M
                }
282
1.00M
            }
283
5.60M
        }
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::flatten_and_destroy()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<char, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::flatten_and_destroy()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::order_preserving_policy, std::__1::allocator<char> >, std::__1::vector>::flatten_and_destroy()
284
    };
285
286
} // namespace jsoncons
287
288
#endif // JSONCONS_JSON_ARRAY_HPP