GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: impl/array.ipp
Date: 2025-12-23 17:20:53
Exec Total Coverage
Lines: 389 389 100.0%
Functions: 40 40 100.0%
Branches: 125 142 88.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/json
8 //
9
10 #ifndef BOOST_JSON_IMPL_ARRAY_IPP
11 #define BOOST_JSON_IMPL_ARRAY_IPP
12
13 #include <boost/container_hash/hash.hpp>
14 #include <boost/json/array.hpp>
15 #include <boost/json/pilfer.hpp>
16 #include <boost/json/detail/except.hpp>
17 #include <cstdlib>
18 #include <limits>
19 #include <new>
20 #include <utility>
21
22 namespace boost {
23 namespace json {
24
25 //----------------------------------------------------------
26
27 constexpr array::table::table() = default;
28
29 // empty arrays point here
30 BOOST_JSON_REQUIRE_CONST_INIT
31 array::table array::empty_;
32
33 auto
34 2578 array::
35 table::
36 allocate(
37 std::size_t capacity,
38 storage_ptr const& sp) ->
39 table*
40 {
41
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2578 times.
2578 BOOST_ASSERT(capacity > 0);
42
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2576 times.
2578 if(capacity > array::max_size())
43 {
44 BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
45 2 detail::throw_system_error( error::array_too_large, &loc );
46 }
47 auto p = reinterpret_cast<
48 2576 table*>(sp->allocate(
49 sizeof(table) +
50 2576 capacity * sizeof(value),
51 alignof(value)));
52 2437 p->capacity = static_cast<
53 std::uint32_t>(capacity);
54 2437 return p;
55 }
56
57 void
58 4503 array::
59 table::
60 deallocate(
61 table* p,
62 storage_ptr const& sp)
63 {
64
2/2
✓ Branch 0 taken 2070 times.
✓ Branch 1 taken 2433 times.
4503 if(p->capacity == 0)
65 2070 return;
66 2433 sp->deallocate(p,
67 sizeof(table) +
68 2433 p->capacity * sizeof(value),
69 alignof(value));
70 }
71
72 //----------------------------------------------------------
73
74 37 array::
75 revert_insert::
76 revert_insert(
77 const_iterator pos,
78 std::size_t n,
79 37 array& arr)
80 37 : arr_(&arr)
81 37 , i_(pos - arr_->data())
82 37 , n_(n)
83 {
84
2/4
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
37 BOOST_ASSERT(
85 pos >= arr_->begin() &&
86 pos <= arr_->end());
87
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 35 times.
74 if( n_ <= arr_->capacity() -
88 37 arr_->size())
89 {
90 // fast path
91 2 p = arr_->data() + i_;
92
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(n_ == 0)
93 1 return;
94 1 relocate(
95 1 p + n_,
96 p,
97 1 arr_->size() - i_);
98 1 arr_->t_->size = static_cast<
99 std::uint32_t>(
100 1 arr_->t_->size + n_);
101 1 return;
102 }
103
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 34 times.
35 if(n_ > max_size() - arr_->size())
104 {
105 BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
106 1 detail::throw_system_error( error::array_too_large, &loc );
107 }
108 34 auto t = table::allocate(
109 34 arr_->growth(arr_->size() + n_),
110 34 arr_->sp_);
111 24 t->size = static_cast<std::uint32_t>(
112 24 arr_->size() + n_);
113 24 p = &(*t)[0] + i_;
114 24 relocate(
115 24 &(*t)[0],
116 24 arr_->data(),
117 24 i_);
118 24 relocate(
119 24 &(*t)[i_ + n_],
120 24 arr_->data() + i_,
121 24 arr_->size() - i_);
122 24 t = detail::exchange(arr_->t_, t);
123 24 table::deallocate(t, arr_->sp_);
124 }
125
126 26 array::
127 revert_insert::
128 8 ~revert_insert()
129 {
130
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 8 times.
26 if(! arr_)
131 18 return;
132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 BOOST_ASSERT(n_ != 0);
133 auto const pos =
134 8 arr_->data() + i_;
135 8 arr_->destroy(pos, p);
136 8 arr_->t_->size = static_cast<
137 std::uint32_t>(
138 8 arr_->t_->size - n_);
139 8 relocate(
140 pos,
141 8 pos + n_,
142 8 arr_->size() - i_);
143 26 }
144
145 //----------------------------------------------------------
146
147 void
148 25 array::
149 destroy(
150 value* first, value* last) noexcept
151 {
152
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 24 times.
25 if(sp_.is_not_shared_and_deallocate_is_trivial())
153 1 return;
154
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 24 times.
50 while(last-- != first)
155 26 last->~value();
156 }
157
158 void
159 3732 array::
160 destroy() noexcept
161 {
162
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 3727 times.
3732 if(sp_.is_not_shared_and_deallocate_is_trivial())
163 5 return;
164 3727 auto last = end();
165 3727 auto const first = begin();
166
2/2
✓ Branch 0 taken 17247 times.
✓ Branch 1 taken 3727 times.
20974 while(last-- != first)
167 17247 last->~value();
168 3727 table::deallocate(t_, sp_);
169 }
170
171 //----------------------------------------------------------
172 //
173 // Special Members
174 //
175 //----------------------------------------------------------
176
177 2120 array::
178 2120 array(detail::unchecked_array&& ua)
179 2120 : sp_(ua.storage())
180 {
181 BOOST_STATIC_ASSERT(
182 alignof(table) == alignof(value));
183
2/2
✓ Branch 1 taken 819 times.
✓ Branch 2 taken 1301 times.
2120 if(ua.size() == 0)
184 {
185 819 t_ = &empty_;
186 819 return;
187 }
188
1/1
✓ Branch 1 taken 1263 times.
1301 t_= table::allocate(
189 1301 ua.size(), sp_);
190 1263 t_->size = static_cast<
191 1263 std::uint32_t>(ua.size());
192 1263 ua.relocate(data());
193 38 }
194
195 3668 array::
196 ~array() noexcept
197 {
198 3668 destroy();
199 3668 }
200
201 35 array::
202 array(
203 std::size_t count,
204 value const& v,
205 35 storage_ptr sp)
206 35 : sp_(std::move(sp))
207 {
208
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 34 times.
35 if(count == 0)
209 {
210 1 t_ = &empty_;
211 1 return;
212 }
213 63 t_= table::allocate(
214
1/1
✓ Branch 1 taken 29 times.
34 count, sp_);
215 29 t_->size = 0;
216 29 revert_construct r(*this);
217
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 13 times.
98 while(count--)
218 {
219
2/3
✓ Branch 4 taken 69 times.
✓ Branch 8 taken 16 times.
✗ Branch 9 not taken.
101 ::new(end()) value(v, sp_);
220 69 ++t_->size;
221 }
222 13 r.commit();
223 50 }
224
225 16 array::
226 array(
227 std::size_t count,
228 16 storage_ptr sp)
229 16 : sp_(std::move(sp))
230 {
231
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
16 if(count == 0)
232 {
233 1 t_ = &empty_;
234 1 return;
235 }
236 26 t_ = table::allocate(
237
1/1
✓ Branch 1 taken 11 times.
15 count, sp_);
238 11 t_->size = static_cast<
239 std::uint32_t>(count);
240 11 auto p = data();
241 do
242 {
243 34 ::new(p++) value(sp_);
244 }
245
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 11 times.
34 while(--count);
246 4 }
247
248 8 array::
249 8 array(array const& other)
250
1/1
✓ Branch 2 taken 8 times.
8 : array(other, other.sp_)
251 {
252 8 }
253
254 153 array::
255 array(
256 array const& other,
257 153 storage_ptr sp)
258 153 : sp_(std::move(sp))
259 {
260
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 139 times.
153 if(other.empty())
261 {
262 14 t_ = &empty_;
263 14 return;
264 }
265
1/1
✓ Branch 1 taken 120 times.
139 t_ = table::allocate(
266 139 other.size(), sp_);
267 120 t_->size = 0;
268 120 revert_construct r(*this);
269 120 auto src = other.data();
270 120 auto dest = data();
271 120 auto const n = other.size();
272 do
273 {
274
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 ::new(dest++) value(
275
1/1
✓ Branch 3 taken 2373 times.
2412 *src++, sp_);
276 2373 ++t_->size;
277 }
278
2/2
✓ Branch 0 taken 2266 times.
✓ Branch 1 taken 107 times.
2373 while(t_->size < n);
279 107 r.commit();
280 152 }
281
282 274 array::
283 array(
284 array&& other,
285 274 storage_ptr sp)
286 274 : sp_(std::move(sp))
287 {
288
2/2
✓ Branch 3 taken 251 times.
✓ Branch 4 taken 23 times.
274 if(*sp_ == *other.sp_)
289 {
290 // same resource
291 502 t_ = detail::exchange(
292 251 other.t_, &empty_);
293 255 return;
294 }
295
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 19 times.
23 else if(other.empty())
296 {
297 4 t_ = &empty_;
298 4 return;
299 }
300 // copy
301
1/1
✓ Branch 1 taken 14 times.
19 t_ = table::allocate(
302 19 other.size(), sp_);
303 14 t_->size = 0;
304 14 revert_construct r(*this);
305 14 auto src = other.data();
306 14 auto dest = data();
307 14 auto const n = other.size();
308 do
309 {
310
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 ::new(dest++) value(
311
1/1
✓ Branch 3 taken 30 times.
48 *src++, sp_);
312 30 ++t_->size;
313 }
314
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 8 times.
30 while(t_->size < n);
315 8 r.commit();
316 25 }
317
318 244 array::
319 array(
320 std::initializer_list<
321 value_ref> init,
322 244 storage_ptr sp)
323 244 : sp_(std::move(sp))
324 {
325
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 239 times.
244 if(init.size() == 0)
326 {
327 5 t_ = &empty_;
328 5 return;
329 }
330
1/1
✓ Branch 1 taken 212 times.
239 t_ = table::allocate(
331 239 init.size(), sp_);
332 212 t_->size = 0;
333 212 revert_construct r(*this);
334
1/1
✓ Branch 1 taken 197 times.
212 value_ref::write_array(
335 212 data(), init, sp_);
336 197 t_->size = static_cast<
337 197 std::uint32_t>(init.size());
338 197 r.commit();
339 254 }
340
341 //----------------------------------------------------------
342
343 array&
344 16 array::
345 operator=(array const& other)
346 {
347
1/1
✓ Branch 3 taken 12 times.
32 array(other,
348
1/1
✓ Branch 1 taken 12 times.
12 storage()).swap(*this);
349 12 return *this;
350 }
351
352 array&
353 7 array::
354 operator=(array&& other)
355 {
356
1/1
✓ Branch 4 taken 5 times.
14 array(std::move(other),
357
1/1
✓ Branch 1 taken 5 times.
5 storage()).swap(*this);
358 5 return *this;
359 }
360
361 array&
362 9 array::
363 operator=(
364 std::initializer_list<value_ref> init)
365 {
366
1/1
✓ Branch 3 taken 5 times.
18 array(init,
367
1/1
✓ Branch 1 taken 5 times.
5 storage()).swap(*this);
368 5 return *this;
369 }
370
371 //----------------------------------------------------------
372 //
373 // Element access
374 //
375 //----------------------------------------------------------
376
377 system::result<value&>
378 12 array::try_at(std::size_t pos) noexcept
379 {
380
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 if(pos >= t_->size)
381 {
382 8 system::error_code ec;
383 8 BOOST_JSON_FAIL(ec, error::out_of_range);
384 8 return ec;
385 }
386 4 return (*t_)[pos];
387 }
388
389 system::result<value const&>
390 106 array::try_at(std::size_t pos) const noexcept
391 {
392
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 94 times.
106 if(pos >= t_->size)
393 {
394 12 system::error_code ec;
395 12 BOOST_JSON_FAIL(ec, error::out_of_range);
396 12 return ec;
397 }
398 94 return (*t_)[pos];
399 }
400
401 value const&
402 100 array::
403 array::at(std::size_t pos, source_location const& loc) const&
404 {
405
1/1
✓ Branch 2 taken 89 times.
100 return try_at(pos).value(loc);
406 }
407
408 //----------------------------------------------------------
409 //
410 // Capacity
411 //
412 //----------------------------------------------------------
413
414 void
415 6 array::
416 shrink_to_fit() noexcept
417 {
418
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4 times.
6 if(capacity() <= size())
419 2 return;
420
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
4 if(size() == 0)
421 {
422 1 table::deallocate(t_, sp_);
423 1 t_ = &empty_;
424 1 return;
425 }
426
427 #ifndef BOOST_NO_EXCEPTIONS
428 try
429 {
430 #endif
431
1/1
✓ Branch 1 taken 2 times.
3 auto t = table::allocate(
432 3 size(), sp_);
433 4 relocate(
434 2 &(*t)[0],
435 data(),
436 size());
437 2 t->size = static_cast<
438 2 std::uint32_t>(size());
439 2 t = detail::exchange(
440 2 t_, t);
441
1/1
✓ Branch 1 taken 2 times.
2 table::deallocate(t, sp_);
442 #ifndef BOOST_NO_EXCEPTIONS
443 }
444 1 catch(...)
445 {
446 // eat the exception
447 1 return;
448 1 }
449 #endif
450 }
451
452 //----------------------------------------------------------
453 //
454 // Modifiers
455 //
456 //----------------------------------------------------------
457
458 void
459 4 array::
460 clear() noexcept
461 {
462
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
4 if(size() == 0)
463 1 return;
464 3 destroy(
465 begin(), end());
466 3 t_->size = 0;
467 }
468
469 auto
470 3 array::
471 insert(
472 const_iterator pos,
473 value const& v) ->
474 iterator
475 {
476 3 return emplace(pos, v);
477 }
478
479 auto
480 3 array::
481 insert(
482 const_iterator pos,
483 value&& v) ->
484 iterator
485 {
486 3 return emplace(pos, std::move(v));
487 }
488
489 auto
490 10 array::
491 insert(
492 const_iterator pos,
493 std::size_t count,
494 value const& v) ->
495 iterator
496 {
497 revert_insert r(
498
1/1
✓ Branch 1 taken 7 times.
10 pos, count, *this);
499
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 4 times.
17 while(count--)
500 {
501
2/3
✓ Branch 3 taken 10 times.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
16 ::new(r.p) value(v, sp_);
502 10 ++r.p;
503 }
504 8 return r.commit();
505 7 }
506
507 auto
508 3 array::
509 insert(
510 const_iterator pos,
511 std::initializer_list<
512 value_ref> init) ->
513 iterator
514 {
515 revert_insert r(
516
1/1
✓ Branch 2 taken 2 times.
3 pos, init.size(), *this);
517 2 value_ref::write_array(
518
1/1
✓ Branch 1 taken 1 times.
2 r.p, init, sp_);
519 2 return r.commit();
520 2 }
521
522 auto
523 7 array::
524 erase(
525 const_iterator pos) noexcept ->
526 iterator
527 {
528
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
7 BOOST_ASSERT(
529 pos >= begin() &&
530 pos <= end());
531 7 return erase(pos, pos + 1);
532 }
533
534 auto
535 8 array::
536 erase(
537 const_iterator first,
538 const_iterator last) noexcept ->
539 iterator
540 {
541
3/6
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
8 BOOST_ASSERT(
542 first >= begin() &&
543 last >= first &&
544 last <= end());
545 8 std::size_t const n =
546 8 last - first;
547 8 auto const p = &(*t_)[0] +
548 8 (first - &(*t_)[0]);
549 8 destroy(p, p + n);
550 8 relocate(p, p + n,
551 8 t_->size - (last -
552 8 &(*t_)[0]));
553 8 t_->size = static_cast<
554 8 std::uint32_t>(t_->size - n);
555 8 return p;
556 }
557
558 void
559 4 array::
560 push_back(value const& v)
561 {
562 4 emplace_back(v);
563 2 }
564
565 void
566 9 array::
567 push_back(value&& v)
568 {
569 9 emplace_back(std::move(v));
570 7 }
571
572 void
573 3 array::
574 pop_back() noexcept
575 {
576 3 auto const p = &back();
577 3 destroy(p, p + 1);
578 3 --t_->size;
579 3 }
580
581 void
582 15 array::
583 resize(std::size_t count)
584 {
585
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13 times.
15 if(count <= t_->size)
586 {
587 // shrink
588 4 destroy(
589 2 &(*t_)[0] + count,
590 2 &(*t_)[0] + t_->size);
591 2 t_->size = static_cast<
592 std::uint32_t>(count);
593 2 return;
594 }
595
596 13 reserve(count);
597 12 auto p = &(*t_)[t_->size];
598 12 auto const end = &(*t_)[count];
599
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 12 times.
32 while(p != end)
600 20 ::new(p++) value(sp_);
601 12 t_->size = static_cast<
602 std::uint32_t>(count);
603 }
604
605 void
606 7 array::
607 resize(
608 std::size_t count,
609 value const& v)
610 {
611
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6 times.
7 if(count <= size())
612 {
613 // shrink
614 2 destroy(
615 1 data() + count,
616 1 data() + size());
617 1 t_->size = static_cast<
618 std::uint32_t>(count);
619 1 return;
620 }
621 6 count -= size();
622 revert_insert r(
623
1/1
✓ Branch 2 taken 5 times.
6 end(), count, *this);
624
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 while(count--)
625 {
626
2/3
✓ Branch 3 taken 4 times.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
12 ::new(r.p) value(v, sp_);
627 4 ++r.p;
628 }
629 1 r.commit();
630 5 }
631
632 void
633 28 array::
634 swap(array& other)
635 {
636
2/2
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 4 times.
28 if(*sp_ == *other.sp_)
637 {
638 48 t_ = detail::exchange(
639 24 other.t_, t_);
640 24 return;
641 }
642 array temp1(
643 4 std::move(*this),
644
1/1
✓ Branch 3 taken 3 times.
9 other.storage());
645 array temp2(
646 3 std::move(other),
647
1/1
✓ Branch 3 taken 2 times.
7 this->storage());
648 2 this->~array();
649 6 ::new(this) array(
650 2 pilfer(temp2));
651 2 other.~array();
652 6 ::new(&other) array(
653 2 pilfer(temp1));
654 3 }
655
656 //----------------------------------------------------------
657 //
658 // Private
659 //
660 //----------------------------------------------------------
661
662 std::size_t
663 814 array::
664 growth(
665 std::size_t new_size) const
666 {
667
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 813 times.
814 if(new_size > max_size())
668 {
669 BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
670 1 detail::throw_system_error( error::array_too_large, &loc );
671 }
672 813 std::size_t const old = capacity();
673
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 812 times.
813 if(old > max_size() - old / 2)
674 1 return new_size;
675 812 std::size_t const g =
676 812 old + old / 2; // 1.5x
677
2/2
✓ Branch 0 taken 732 times.
✓ Branch 1 taken 80 times.
812 if(g < new_size)
678 732 return new_size;
679 80 return g;
680 }
681
682 // precondition: new_capacity > capacity()
683 void
684 702 array::
685 reserve_impl(
686 std::size_t new_capacity)
687 {
688
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 702 times.
702 BOOST_ASSERT(
689 new_capacity > t_->capacity);
690 701 auto t = table::allocate(
691 702 growth(new_capacity), sp_);
692 681 relocate(
693 681 &(*t)[0],
694 681 &(*t_)[0],
695 681 t_->size);
696 681 t->size = t_->size;
697 681 t = detail::exchange(t_, t);
698 681 table::deallocate(t, sp_);
699 681 }
700
701 // precondition: pv is not aliased
702 value&
703 7686 array::
704 push_back(
705 pilfered<value> pv)
706 {
707 7686 auto const n = t_->size;
708
2/2
✓ Branch 0 taken 7619 times.
✓ Branch 1 taken 67 times.
7686 if(n < t_->capacity)
709 {
710 // fast path
711 auto& v = *::new(
712 7619 &(*t_)[n]) value(pv);
713 7619 ++t_->size;
714 7619 return v;
715 }
716 auto const t =
717 67 detail::exchange(t_,
718 table::allocate(
719 67 growth(n + 1),
720 67 sp_));
721 auto& v = *::new(
722 62 &(*t_)[n]) value(pv);
723 62 relocate(
724 62 &(*t_)[0],
725 62 &(*t)[0],
726 n);
727 62 t_->size = n + 1;
728 62 table::deallocate(t, sp_);
729 62 return v;
730 }
731
732 // precondition: pv is not aliased
733 auto
734 12 array::
735 insert(
736 const_iterator pos,
737 pilfered<value> pv) ->
738 iterator
739 {
740
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 BOOST_ASSERT(
741 pos >= begin() &&
742 pos <= end());
743 12 std::size_t const n =
744 12 t_->size;
745 std::size_t const i =
746 12 pos - &(*t_)[0];
747
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 11 times.
12 if(n < t_->capacity)
748 {
749 // fast path
750 auto const p =
751 1 &(*t_)[i];
752 1 relocate(
753 p + 1,
754 p,
755 n - i);
756 1 ::new(p) value(pv);
757 1 ++t_->size;
758 1 return p;
759 }
760 auto t =
761 11 table::allocate(
762 11 growth(n + 1), sp_);
763 6 auto const p = &(*t)[i];
764 6 ::new(p) value(pv);
765 6 relocate(
766 6 &(*t)[0],
767 6 &(*t_)[0],
768 i);
769 6 relocate(
770 p + 1,
771 6 &(*t_)[i],
772 n - i);
773 6 t->size = static_cast<
774 6 std::uint32_t>(size() + 1);
775 6 t = detail::exchange(t_, t);
776 6 table::deallocate(t, sp_);
777 6 return p;
778 }
779
780 //----------------------------------------------------------
781
782 bool
783 88 array::
784 equal(
785 array const& other) const noexcept
786 {
787
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 86 times.
88 if(size() != other.size())
788 2 return false;
789
2/2
✓ Branch 1 taken 3204 times.
✓ Branch 2 taken 80 times.
3284 for(std::size_t i = 0; i < size(); ++i)
790
2/2
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 3198 times.
3204 if((*this)[i] != other[i])
791 6 return false;
792 80 return true;
793 }
794
795 } // namespace json
796 } // namespace boost
797
798 //----------------------------------------------------------
799 //
800 // std::hash specialization
801 //
802 //----------------------------------------------------------
803
804 std::size_t
805 12 std::hash<::boost::json::array>::operator()(
806 ::boost::json::array const& ja) const noexcept
807 {
808 12 return ::boost::hash< ::boost::json::array >()( ja );
809 }
810
811 //----------------------------------------------------------
812
813 #endif
814