Coverage Report

Created: 2026-10-16 06:21

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 data_;
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
170k
        json_array() = default;
47
48
        explicit json_array(const allocator_type& alloc)
49
9.46k
            : allocator_holder<allocator_type>(alloc), 
50
9.46k
              data_(value_allocator_type(alloc))
51
9.46k
        {
52
9.46k
        }
53
54
        explicit json_array(std::size_t n, 
55
                            const allocator_type& alloc = allocator_type())
56
            : allocator_holder<allocator_type>(alloc), 
57
              data_(n,Json(),value_allocator_type(alloc))
58
        {
59
        }
60
61
        explicit json_array(std::size_t n, 
62
                            const Json& value, 
63
                            const allocator_type& alloc = allocator_type())
64
            : allocator_holder<allocator_type>(alloc), 
65
              data_(n,value,value_allocator_type(alloc))
66
        {
67
        }
68
69
        template <typename InputIterator>
70
        json_array(InputIterator begin, InputIterator end, const allocator_type& alloc = allocator_type())
71
            : allocator_holder<allocator_type>(alloc), 
72
              data_(begin,end,value_allocator_type(alloc))
73
        {
74
        }
75
76
        json_array(const json_array& other)
77
            : allocator_holder<allocator_type>(other.get_allocator()),
78
              data_(other.data_)
79
        {
80
        }
81
        json_array(const json_array& other, const allocator_type& alloc)
82
            : allocator_holder<allocator_type>(alloc), 
83
              data_(other.data_,value_allocator_type(alloc))
84
        {
85
        }
86
87
        json_array(json_array&& other) noexcept
88
            : allocator_holder<allocator_type>(other.get_allocator()), 
89
              data_(std::move(other.data_))
90
        {
91
        }
92
        json_array(json_array&& other, const allocator_type& alloc)
93
            : allocator_holder<allocator_type>(alloc), 
94
              data_(std::move(other.data_),value_allocator_type(alloc))
95
        {
96
        }
97
98
        json_array(const std::initializer_list<Json>& init, 
99
                   const allocator_type& alloc = allocator_type())
100
            : allocator_holder<allocator_type>(alloc), 
101
              data_(init,value_allocator_type(alloc))
102
        {
103
        }
104
        ~json_array() noexcept
105
180k
        {
106
180k
            flatten_and_destroy();
107
180k
        }
108
109
        reference back()
110
        {
111
            return data_.back();
112
        }
113
114
        const_reference back() const
115
        {
116
            return data_.back();
117
        }
118
119
        void pop_back()
120
        {
121
            data_.pop_back();
122
        }
123
124
        bool empty() const
125
15.9k
        {
126
15.9k
            return data_.empty();
127
15.9k
        }
jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::empty() const
Line
Count
Source
125
15.9k
        {
126
15.9k
            return data_.empty();
127
15.9k
        }
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::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::empty() const
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::empty() const
128
129
        void swap(json_array& other) noexcept
130
        {
131
            data_.swap(other.data_);
132
        }
133
134
        std::size_t size() const {return data_.size();}
135
136
        std::size_t capacity() const {return data_.capacity();}
137
138
        // Direct access to data
139
        value_type* data() noexcept { return data_.data(); }
140
        const value_type* data() const noexcept { return data_.data(); }
141
142
12.9k
        void clear() {data_.clear();}
jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::clear()
Line
Count
Source
142
12.9k
        void clear() {data_.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::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::clear()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::clear()
143
144
        void shrink_to_fit() 
145
        {
146
            for (std::size_t i = 0; i < data_.size(); ++i)
147
            {
148
                data_[i].shrink_to_fit();
149
            }
150
            data_.shrink_to_fit();
151
        }
152
153
17.0k
        void reserve(std::size_t n) {data_.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
153
17.0k
        void reserve(std::size_t n) {data_.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::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::reserve(unsigned long)
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::reserve(unsigned long)
154
155
        void resize(std::size_t n) {data_.resize(n);}
156
157
        void resize(std::size_t n, const Json& val) {data_.resize(n,val);}
158
159
        iterator erase(const_iterator pos) 
160
        {
161
            return data_.erase(pos);
162
        }
163
164
        iterator erase(const_iterator first, const_iterator last) 
165
        {
166
            return data_.erase(first,last);
167
        }
168
169
        Json& operator[](std::size_t i) {return data_[i];}
170
171
        const Json& operator[](std::size_t i) const {return data_[i];}
172
173
        // push_back
174
175
        template <typename T,typename A=allocator_type>
176
        typename std::enable_if<std::allocator_traits<A>::is_always_equal::value,void>::type 
177
        push_back(T&& value)
178
3.70M
        {
179
3.70M
            data_.emplace_back(std::forward<T>(value));
180
3.70M
        }
_ZN8jsoncons10json_arrayINS_10basic_jsonIcNS_13sorted_policyENSt3__19allocatorIcEEEENS3_6vectorEE9push_backIS6_S5_EENS3_9enable_ifIXsr3std16allocator_traitsIT0_E15is_always_equalE5valueEvE4typeEOT_
Line
Count
Source
178
3.70M
        {
179
3.70M
            data_.emplace_back(std::forward<T>(value));
180
3.70M
        }
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_14ordered_policyENSt3__19allocatorIcEEEENS3_6vectorEE9push_backIS6_S5_EENS3_9enable_ifIXsr3std16allocator_traitsIT0_E15is_always_equalE5valueEvE4typeEOT_
Unexecuted instantiation: _ZN8jsoncons10json_arrayINS_10basic_jsonIwNS_14ordered_policyENSt3__19allocatorIcEEEENS3_6vectorEE9push_backIS6_S5_EENS3_9enable_ifIXsr3std16allocator_traitsIT0_E15is_always_equalE5valueEvE4typeEOT_
181
182
        template <typename T,typename A=allocator_type>
183
        typename std::enable_if<!std::allocator_traits<A>::is_always_equal::value,void>::type 
184
        push_back(T&& value)
185
        {
186
            data_.emplace_back(std::forward<T>(value));
187
        }
188
189
        template <typename T,typename A=allocator_type>
190
        typename std::enable_if<std::allocator_traits<A>::is_always_equal::value,iterator>::type 
191
        insert(const_iterator pos, T&& value)
192
        {
193
            return data_.emplace(pos, std::forward<T>(value));
194
        }
195
        template <typename T,typename A=allocator_type>
196
        typename std::enable_if<!std::allocator_traits<A>::is_always_equal::value,iterator>::type 
197
        insert(const_iterator pos, T&& value)
198
        {
199
            return data_.emplace(pos, std::forward<T>(value));
200
        }
201
202
        template <typename InputIt>
203
        iterator insert(const_iterator pos, InputIt first, InputIt last)
204
        {
205
            return data_.insert(pos, first, last);
206
        }
207
208
        template <typename A=allocator_type,typename... Args>
209
        typename std::enable_if<std::allocator_traits<A>::is_always_equal::value,iterator>::type 
210
        emplace(const_iterator pos, Args&&... args)
211
        {
212
            return data_.emplace(pos, std::forward<Args>(args)...);
213
        }
214
215
        template <typename... Args>
216
        Json& emplace_back(Args&&... args)
217
1.97k
        {
218
1.97k
            data_.emplace_back(std::forward<Args>(args)...);
219
1.97k
            return data_.back();
220
1.97k
        }
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
217
1.97k
        {
218
1.97k
            data_.emplace_back(std::forward<Args>(args)...);
219
1.97k
            return data_.back();
220
1.97k
        }
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::ordered_policy, std::__1::allocator<char> >& jsoncons::json_array<jsoncons::basic_json<char, jsoncons::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::emplace_back<jsoncons::basic_json<char, jsoncons::ordered_policy, std::__1::allocator<char> > >(jsoncons::basic_json<char, jsoncons::ordered_policy, std::__1::allocator<char> >&&)
Unexecuted instantiation: jsoncons::basic_json<wchar_t, jsoncons::ordered_policy, std::__1::allocator<char> >& jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::emplace_back<jsoncons::basic_json<wchar_t, jsoncons::ordered_policy, std::__1::allocator<char> > >(jsoncons::basic_json<wchar_t, jsoncons::ordered_policy, std::__1::allocator<char> >&&)
221
222
12.9k
        iterator begin() {return data_.begin();}
jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::begin()
Line
Count
Source
222
12.9k
        iterator begin() {return data_.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::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::begin()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::begin()
223
224
12.9k
        iterator end() {return data_.end();}
jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::end()
Line
Count
Source
224
12.9k
        iterator end() {return data_.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::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::end()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::end()
225
226
        const_iterator begin() const {return data_.begin();}
227
228
        const_iterator end() const {return data_.end();}
229
230
        bool operator==(const json_array& rhs) const noexcept
231
        {
232
            return data_ == rhs.data_;
233
        }
234
235
        bool operator<(const json_array& rhs) const noexcept
236
        {
237
            return data_ < rhs.data_;
238
        }
239
240
        json_array& operator=(const json_array& other)
241
        {
242
            data_ = other.data_;
243
            return *this;
244
        }
245
    private:
246
247
        void flatten_and_destroy() noexcept
248
180k
        {
249
3.87M
            while (!data_.empty())
250
3.69M
            {
251
3.69M
                value_type current = std::move(data_.back());
252
3.69M
                data_.pop_back();
253
3.69M
                switch (current.storage_kind())
254
3.69M
                {
255
12.9k
                    case json_storage_kind::array:
256
12.9k
                    {
257
12.9k
                        for (auto&& item : current.array_range())
258
16.6k
                        {
259
16.6k
                            if ((item.storage_kind() == json_storage_kind::array || item.storage_kind() == json_storage_kind::object)
260
8.23k
                                && !item.empty()) // non-empty object or array
261
7.83k
                            {
262
7.83k
                                data_.push_back(std::move(item));
263
7.83k
                            }
264
16.6k
                        }
265
12.9k
                        current.clear();                           
266
12.9k
                        break;
267
0
                    }
268
5.13k
                    case json_storage_kind::object:
269
5.13k
                    {
270
5.13k
                        for (auto&& kv : current.object_range())
271
18.6k
                        {
272
18.6k
                            if ((kv.value().storage_kind() == json_storage_kind::array || kv.value().storage_kind() == json_storage_kind::object)
273
11.5k
                                && !kv.value().empty()) // non-empty object or array
274
3.57k
                            {
275
3.57k
                                data_.push_back(std::move(kv.value()));
276
3.57k
                            }
277
18.6k
                        }
278
5.13k
                        current.clear();                           
279
5.13k
                        break;
280
0
                    }
281
3.68M
                    default:
282
3.68M
                        break;
283
3.69M
                }
284
3.69M
            }
285
180k
        }
jsoncons::json_array<jsoncons::basic_json<char, jsoncons::sorted_policy, std::__1::allocator<char> >, std::__1::vector>::flatten_and_destroy()
Line
Count
Source
248
180k
        {
249
3.87M
            while (!data_.empty())
250
3.69M
            {
251
3.69M
                value_type current = std::move(data_.back());
252
3.69M
                data_.pop_back();
253
3.69M
                switch (current.storage_kind())
254
3.69M
                {
255
12.9k
                    case json_storage_kind::array:
256
12.9k
                    {
257
12.9k
                        for (auto&& item : current.array_range())
258
16.6k
                        {
259
16.6k
                            if ((item.storage_kind() == json_storage_kind::array || item.storage_kind() == json_storage_kind::object)
260
8.23k
                                && !item.empty()) // non-empty object or array
261
7.83k
                            {
262
7.83k
                                data_.push_back(std::move(item));
263
7.83k
                            }
264
16.6k
                        }
265
12.9k
                        current.clear();                           
266
12.9k
                        break;
267
0
                    }
268
5.13k
                    case json_storage_kind::object:
269
5.13k
                    {
270
5.13k
                        for (auto&& kv : current.object_range())
271
18.6k
                        {
272
18.6k
                            if ((kv.value().storage_kind() == json_storage_kind::array || kv.value().storage_kind() == json_storage_kind::object)
273
11.5k
                                && !kv.value().empty()) // non-empty object or array
274
3.57k
                            {
275
3.57k
                                data_.push_back(std::move(kv.value()));
276
3.57k
                            }
277
18.6k
                        }
278
5.13k
                        current.clear();                           
279
5.13k
                        break;
280
0
                    }
281
3.68M
                    default:
282
3.68M
                        break;
283
3.69M
                }
284
3.69M
            }
285
180k
        }
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::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::flatten_and_destroy()
Unexecuted instantiation: jsoncons::json_array<jsoncons::basic_json<wchar_t, jsoncons::ordered_policy, std::__1::allocator<char> >, std::__1::vector>::flatten_and_destroy()
286
    };
287
288
} // namespace jsoncons
289
290
#endif // JSONCONS_JSON_ARRAY_HPP