Coverage Report

Created: 2025-06-13 06:26

/src/boost/boost/json/array.hpp
Line
Count
Source (jump to first uncovered line)
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_ARRAY_HPP
11
#define BOOST_JSON_ARRAY_HPP
12
13
#include <boost/json/detail/config.hpp>
14
#include <boost/json/detail/array.hpp>
15
#include <boost/json/kind.hpp>
16
#include <boost/json/pilfer.hpp>
17
#include <boost/json/storage_ptr.hpp>
18
#include <boost/system/result.hpp>
19
#include <cstdlib>
20
#include <initializer_list>
21
#include <iterator>
22
23
namespace boost {
24
namespace json {
25
26
#ifndef BOOST_JSON_DOCS
27
class value;
28
class value_ref;
29
#endif
30
31
/** A dynamically sized array of JSON values
32
33
    This is the type used to represent a JSON array as
34
    a modifiable container. The interface and performance
35
    characteristics are modeled after `std::vector<value>`.
36
\n
37
    Elements are stored contiguously, which means that
38
    they can be accessed not only through iterators, but
39
    also using offsets to regular pointers to elements. A
40
    pointer to an element of an @ref array may be passed to
41
    any function that expects a pointer to @ref value.
42
\n
43
    The storage of the array is handled automatically, being
44
    expanded and contracted as needed. Arrays usually occupy
45
    more space than array language constructs, because more
46
    memory is allocated to handle future growth. This way an
47
    array does not need to reallocate each time an element
48
    is inserted, but only when the additional memory is used
49
    up. The total amount of allocated memory can be queried
50
    using the @ref capacity function. Extra memory can be
51
    relinquished by calling @ref shrink_to_fit.
52
    \n
53
54
    Reallocations are usually costly operations in terms of
55
    performance. The @ref reserve function can be used to
56
    eliminate reallocations if the number of elements is
57
    known beforehand.
58
\n
59
    The complexity (efficiency) of common operations on
60
    arrays is as follows:
61
62
    @li Random access - constant *O(1)*.
63
    @li Insertion or removal of elements at the
64
        end - amortized constant *O(1)*.
65
    @li Insertion or removal of elements - linear in
66
        the distance to the end of the array *O(n)*.
67
68
    @par Allocators
69
70
    All elements stored in the container, and their
71
    children if any, will use the same memory resource
72
    that was used to construct the container.
73
74
    @par Thread Safety
75
76
    Non-const member functions may not be called
77
    concurrently with any other member functions.
78
79
    @par Satisfies
80
        <a href="https://en.cppreference.com/w/cpp/named_req/ContiguousContainer"><em>ContiguousContainer</em></a>,
81
        <a href="https://en.cppreference.com/w/cpp/named_req/ReversibleContainer"><em>ReversibleContainer</em></a>, and
82
        <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>.
83
*/
84
class array
85
{
86
    struct table;
87
    class revert_construct;
88
    class revert_insert;
89
    friend class value;
90
91
    storage_ptr sp_;        // must come first
92
    kind k_ = kind::array;  // must come second
93
    table* t_;
94
95
    BOOST_JSON_DECL
96
    static table empty_;
97
98
    inline
99
    static
100
    void
101
    relocate(
102
        value* dest,
103
        value* src,
104
        std::size_t n) noexcept;
105
106
    inline
107
    void
108
    destroy(
109
        value* first,
110
        value* last) noexcept;
111
112
    BOOST_JSON_DECL
113
    void
114
    destroy() noexcept;
115
116
    BOOST_JSON_DECL
117
    explicit
118
    array(detail::unchecked_array&& ua);
119
120
public:
121
    /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
122
    using allocator_type = container::pmr::polymorphic_allocator<value>;
123
124
    /// The type used to represent unsigned integers
125
    using size_type = std::size_t;
126
127
    /// The type of each element
128
    using value_type = value;
129
130
    /// The type used to represent signed integers
131
    using difference_type = std::ptrdiff_t;
132
133
    /// A reference to an element
134
    using reference = value&;
135
136
    /// A const reference to an element
137
    using const_reference = value const&;
138
139
    /// A pointer to an element
140
    using pointer = value*;
141
142
    /// A const pointer to an element
143
    using const_pointer = value const*;
144
145
    /// A random access iterator to an element
146
    using iterator = value*;
147
148
    /// A random access const iterator to an element
149
    using const_iterator = value const*;
150
151
    /// A reverse random access iterator to an element
152
    using reverse_iterator =
153
        std::reverse_iterator<iterator>;
154
155
    /// A reverse random access const iterator to an element
156
    using const_reverse_iterator =
157
        std::reverse_iterator<const_iterator>;
158
159
    //------------------------------------------------------
160
161
    /** Destructor.
162
163
        The destructor for each element is called if needed,
164
        any used memory is deallocated, and shared ownership
165
        of the `boost::container::pmr::memory_resource` is released.
166
167
        @par Complexity
168
        Constant, or linear in @ref size().
169
170
        @par Exception Safety
171
        No-throw guarantee.
172
    */
173
    BOOST_JSON_DECL
174
    ~array() noexcept;
175
176
    //------------------------------------------------------
177
178
    /** Constructor.
179
180
        The constructed array is empty with zero
181
        capacity, using the [default memory resource].
182
183
        @par Complexity
184
        Constant.
185
186
        @par Exception Safety
187
        No-throw guarantee.
188
189
        [default memory resource]: json/allocators/storage_ptr.html#json.allocators.storage_ptr.default_memory_resource
190
    */
191
    array() noexcept
192
        : t_(&empty_)
193
    {
194
    }
195
196
    /** Constructor.
197
198
        The constructed array is empty with zero
199
        capacity, using the specified memory resource.
200
201
        @par Complexity
202
        Constant.
203
204
        @par Exception Safety
205
        No-throw guarantee.
206
207
        @param sp A pointer to the `boost::container::pmr::memory_resource`
208
        to use. The container will acquire shared
209
        ownership of the memory resource.
210
    */
211
    explicit
212
    array(storage_ptr sp) noexcept
213
0
        : sp_(std::move(sp))
214
0
        , k_(kind::array)
215
0
        , t_(&empty_)
216
0
    {
217
0
    }
218
219
    /** Constructor.
220
221
        The array is constructed with `count`
222
        copies of the value `v`, using the
223
        specified memory resource.
224
225
        @par Complexity
226
        Linear in `count`
227
228
        @par Exception Safety
229
        Strong guarantee.
230
        Calls to `memory_resource::allocate` may throw.
231
232
        @param count The number of copies to insert.
233
234
        @param v The value to be inserted.
235
236
        @param sp A pointer to the `boost::container::pmr::memory_resource`
237
        to use. The container will acquire shared
238
        ownership of the memory resource.
239
    */
240
    BOOST_JSON_DECL
241
    array(
242
        std::size_t count,
243
        value const& v,
244
        storage_ptr sp = {});
245
246
    /** Constructor.
247
248
        The array is constructed with `count` null values,
249
        using the specified memory resource.
250
251
        @par Complexity
252
        Linear in `count`
253
254
        @par Exception Safety
255
        Strong guarantee.
256
        Calls to `memory_resource::allocate` may throw.
257
258
        @param count The number of nulls to insert.
259
260
        @param sp A pointer to the `boost::container::pmr::memory_resource`
261
        to use. The container will acquire shared
262
        ownership of the memory resource.
263
    */
264
    BOOST_JSON_DECL
265
    array(
266
        std::size_t count,
267
        storage_ptr sp = {});
268
269
    /** Constructor.
270
271
        The array is constructed with the elements
272
        in the range `{first, last)`, preserving order,
273
        using the specified memory resource.
274
275
        @par Constraints
276
277
        @code
278
        std::is_constructible_v<value, std::iterator_traits<InputIt>::reference>
279
        @endcode
280
281
        @par Complexity
282
        Linear in `std::distance(first, last)`
283
284
        @par Exception Safety
285
        Strong guarantee.
286
        Calls to `memory_resource::allocate` may throw.
287
288
        @param first An input iterator pointing to the
289
        first element to insert, or pointing to the end
290
        of the range.
291
292
        @param last An input iterator pointing to the end
293
        of the range.
294
295
        @param sp A pointer to the `boost::container::pmr::memory_resource`
296
        to use. The container will acquire shared
297
        ownership of the memory resource.
298
299
        @tparam InputIt a type satisfying the requirements
300
        of __InputIterator__.
301
    */
302
    template<
303
        class InputIt
304
    #ifndef BOOST_JSON_DOCS
305
        ,class = typename std::enable_if<
306
            std::is_constructible<value,
307
                typename std::iterator_traits<
308
                    InputIt>::reference>::value>::type
309
    #endif
310
    >
311
    array(
312
        InputIt first, InputIt last,
313
        storage_ptr sp = {});
314
315
    /** Copy constructor.
316
317
        The array is constructed with a copy of the
318
        contents of `other`, using `other`'s memory resource.
319
320
        @par Complexity
321
        Linear in `other.size()`.
322
323
        @par Exception Safety
324
        Strong guarantee.
325
        Calls to `memory_resource::allocate` may throw.
326
327
        @param other The array to copy
328
    */
329
    BOOST_JSON_DECL
330
    array(array const& other);
331
332
    /** Copy constructor.
333
334
        The array is constructed with a copy of the
335
        contents of `other`, using the specified memory resource.
336
337
        @par Complexity
338
        Linear in `other.size()`.
339
340
        @par Exception Safety
341
        Strong guarantee.
342
        Calls to `memory_resource::allocate` may throw.
343
344
        @param other The array to copy
345
346
        @param sp A pointer to the `boost::container::pmr::memory_resource`
347
        to use. The container will acquire shared
348
        ownership of the memory resource.
349
    */
350
    BOOST_JSON_DECL
351
    array(
352
        array const& other,
353
        storage_ptr sp);
354
355
    /** Pilfer constructor.
356
357
        The array is constructed by acquiring ownership
358
        of the contents of `other` using pilfer semantics.
359
        This is more efficient than move construction, when
360
        it is known that the moved-from object will be
361
        immediately destroyed afterwards.
362
363
        @par Complexity
364
        Constant.
365
366
        @par Exception Safety
367
        No-throw guarantee.
368
369
        @param other The value to pilfer. After pilfer
370
        construction, `other` is not in a usable state
371
        and may only be destroyed.
372
373
        @see @ref pilfer,
374
            <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
375
                Valueless Variants Considered Harmful</a>
376
    */
377
    array(pilfered<array> other) noexcept
378
0
        : sp_(std::move(other.get().sp_))
379
0
        , t_(detail::exchange(
380
0
            other.get().t_, &empty_))
381
0
    {
382
0
    }
383
384
    /** Move constructor.
385
386
        The array is constructed by acquiring ownership of
387
        the contents of `other` and shared ownership of
388
        `other`'s memory resource.
389
390
        @note
391
392
        After construction, the moved-from array behaves
393
        as if newly constructed with its current storage
394
        pointer.
395
396
        @par Complexity
397
        Constant.
398
399
        @par Exception Safety
400
        No-throw guarantee.
401
402
        @param other The container to move
403
    */
404
    array(array&& other) noexcept
405
0
        : sp_(other.sp_)
406
0
        , t_(detail::exchange(
407
0
            other.t_, &empty_))
408
0
    {
409
0
    }
410
411
    /** Move constructor.
412
413
        The array is constructed with the contents of
414
        `other` by move semantics, using the specified
415
        memory resource:
416
417
        @li If `*other.storage() == *sp`, ownership of
418
        the underlying memory is transferred in constant
419
        time, with no possibility of exceptions.
420
        After construction, the moved-from array behaves
421
        as if newly constructed with its current storage
422
        pointer.
423
424
        @li If `*other.storage() != *sp`, an
425
        element-wise copy is performed, which may throw.
426
        In this case, the moved-from array is not
427
        changed.
428
429
        @par Complexity
430
        At most, linear in `other.size()`.
431
432
        @par Exception Safety
433
        Strong guarantee.
434
        Calls to `memory_resource::allocate` may throw.
435
436
        @param other The container to move
437
438
        @param sp A pointer to the `boost::container::pmr::memory_resource`
439
        to use. The container will acquire shared
440
        ownership of the memory resource.
441
    */
442
    BOOST_JSON_DECL
443
    array(
444
        array&& other,
445
        storage_ptr sp);
446
447
    /** Constructor.
448
449
        The array is constructed with a copy of the values
450
        in the initializer-list in order, using the
451
        specified memory resource.
452
453
        @par Complexity
454
        Linear in `init.size()`.
455
456
        @par Exception Safety
457
        Strong guarantee.
458
        Calls to `memory_resource::allocate` may throw.
459
460
        @param init The initializer list to insert
461
462
        @param sp A pointer to the `boost::container::pmr::memory_resource`
463
        to use. The container will acquire shared
464
        ownership of the memory resource.
465
    */
466
    BOOST_JSON_DECL
467
    array(
468
        std::initializer_list<value_ref> init,
469
        storage_ptr sp = {});
470
471
    //------------------------------------------------------
472
473
    /** Copy assignment.
474
475
        The contents of the array are replaced with an
476
        element-wise copy of `other`.
477
478
        @par Complexity
479
        Linear in @ref size() plus `other.size()`.
480
481
        @par Exception Safety
482
        Strong guarantee.
483
        Calls to `memory_resource::allocate` may throw.
484
485
        @param other The array to copy.
486
    */
487
    BOOST_JSON_DECL
488
    array&
489
    operator=(array const& other);
490
491
    /** Move assignment.
492
493
        The contents of the array are replaced with the
494
        contents of `other` using move semantics:
495
496
        @li If `*other.storage() == *sp`, ownership of
497
        the underlying memory is transferred in constant
498
        time, with no possibility of exceptions.
499
        After assignment, the moved-from array behaves
500
        as if newly constructed with its current storage
501
        pointer.
502
503
        @li If `*other.storage() != *sp`, an
504
        element-wise copy is performed, which may throw.
505
        In this case, the moved-from array is not
506
        changed.
507
508
        @par Complexity
509
        Constant, or linear in
510
        `this->size()` plus `other.size()`.
511
512
        @par Exception Safety
513
        Strong guarantee.
514
        Calls to `memory_resource::allocate` may throw.
515
516
        @param other The array to move.
517
    */
518
    BOOST_JSON_DECL
519
    array&
520
    operator=(array&& other);
521
522
    /** Assignment.
523
524
        The contents of the array are replaced with a
525
        copy of the values in the initializer-list.
526
527
        @par Complexity
528
        Linear in `this->size()` plus `init.size()`.
529
530
        @par Exception Safety
531
        Strong guarantee.
532
        Calls to `memory_resource::allocate` may throw.
533
534
        @param init The initializer list to copy.
535
    */
536
    BOOST_JSON_DECL
537
    array&
538
    operator=(
539
        std::initializer_list<value_ref> init);
540
541
    //------------------------------------------------------
542
543
    /** Return the associated memory resource.
544
545
        This function returns the `boost::container::pmr::memory_resource` used
546
        by the container.
547
548
        @par Complexity
549
        Constant.
550
551
        @par Exception Safety
552
        No-throw guarantee.
553
    */
554
    storage_ptr const&
555
    storage() const noexcept
556
0
    {
557
0
        return sp_;
558
0
    }
559
560
    /** Return the associated allocator.
561
562
        This function returns an instance of @ref allocator_type constructed
563
        from the associated `boost::container::pmr::memory_resource`.
564
565
        @par Complexity
566
        Constant.
567
568
        @par Exception Safety
569
        No-throw guarantee.
570
    */
571
    allocator_type
572
    get_allocator() const noexcept
573
    {
574
        return sp_.get();
575
    }
576
577
    //------------------------------------------------------
578
    //
579
    // Element access
580
    //
581
    //------------------------------------------------------
582
583
    /** Access an element, with bounds checking.
584
585
        Returns `boost::system::result` containing a reference to the element
586
        specified at location `pos`, if `pos` is within the range of the
587
        container. Otherwise the result contains an `error_code`.
588
589
        @par Exception Safety
590
        No-throw guarantee.
591
592
        @param pos A zero-based index.
593
594
        @par Complexity
595
        Constant.
596
    */
597
    /** @{ */
598
    BOOST_JSON_DECL
599
    system::result<value&>
600
    try_at(std::size_t pos) noexcept;
601
602
    BOOST_JSON_DECL
603
    system::result<value const&>
604
    try_at(std::size_t pos) const noexcept;
605
    /** @} */
606
607
    /** Access an element, with bounds checking.
608
609
        Returns a reference to the element specified at
610
        location `pos`, with bounds checking. If `pos` is
611
        not within the range of the container, an exception
612
        of type `boost::system::system_error` is thrown.
613
614
        @par Complexity
615
        Constant.
616
617
        @param pos A zero-based index.
618
619
        @param loc `source_location` to use in thrown exception; the source
620
            location of the call site by default.
621
622
        @throw `boost::system::system_error` `pos >= size()`.
623
    */
624
    /** @{ */
625
    inline
626
    value&
627
    at(
628
        std::size_t pos,
629
        source_location const& loc = BOOST_CURRENT_LOCATION) &;
630
631
    inline
632
    value&&
633
    at(
634
        std::size_t pos,
635
        source_location const& loc = BOOST_CURRENT_LOCATION) &&;
636
637
    BOOST_JSON_DECL
638
    value const&
639
    at(
640
        std::size_t pos,
641
        source_location const& loc = BOOST_CURRENT_LOCATION) const&;
642
    /** @} */
643
644
    /** Access an element.
645
646
        Returns a reference to the element specified at
647
        location `pos`. No bounds checking is performed.
648
649
        @par Precondition
650
        `pos < size()`
651
652
        @par Complexity
653
        Constant.
654
655
        @param pos A zero-based index
656
    */
657
    /** @{ */
658
    inline
659
    value&
660
    operator[](std::size_t pos) & noexcept;
661
662
    inline
663
    value&&
664
    operator[](std::size_t pos) && noexcept;
665
666
    inline
667
    value const&
668
    operator[](std::size_t pos) const& noexcept;
669
    /** @} */
670
671
    /** Access the first element.
672
673
        Returns a reference to the first element.
674
675
        @par Precondition
676
        `not empty()`
677
678
        @par Complexity
679
        Constant.
680
    */
681
    /** @{ */
682
    inline
683
    value&
684
    front() & noexcept;
685
686
    inline
687
    value&&
688
    front() && noexcept;
689
690
    inline
691
    value const&
692
    front() const& noexcept;
693
    /** @} */
694
695
    /** Access the last element.
696
697
        Returns a reference to the last element.
698
699
        @par Precondition
700
        `not empty()`
701
702
        @par Complexity
703
        Constant.
704
    */
705
    /** @{ */
706
    inline
707
    value&
708
    back() & noexcept;
709
710
    inline
711
    value&&
712
    back() && noexcept;
713
714
    inline
715
    value const&
716
    back() const& noexcept;
717
    /** @} */
718
719
    /** Access the underlying array directly.
720
721
        Returns a pointer to the underlying array serving
722
        as element storage. The value returned is such that
723
        the range `{data(), data() + size())` is always a
724
        valid range, even if the container is empty.
725
726
        @par Complexity
727
        Constant.
728
729
        @par Exception Safety
730
        No-throw guarantee.
731
732
        @note
733
734
        If `size() == 0`, the function may or may not return
735
        a null pointer.
736
    */
737
    inline
738
    value*
739
    data() noexcept;
740
741
    /** Access the underlying array directly.
742
743
        Returns a pointer to the underlying array serving
744
        as element storage. The value returned is such that
745
        the range `{data(), data() + size())` is always a
746
        valid range, even if the container is empty.
747
748
        @par Complexity
749
        Constant.
750
751
        @par Exception Safety
752
        No-throw guarantee.
753
754
        @note
755
756
        If `size() == 0`, the function may or may not return
757
        a null pointer.
758
    */
759
    inline
760
    value const*
761
    data() const noexcept;
762
763
    /** Return a pointer to an element, or nullptr if the index is invalid
764
765
        This function returns a pointer to the element
766
        at index `pos` when the index is less then the size
767
        of the container. Otherwise it returns null.
768
769
        @par Example
770
        @code
771
        if( auto p = arr.if_contains( 1 ) )
772
            std::cout << *p;
773
        @endcode
774
775
        @par Complexity
776
        Constant.
777
778
        @par Exception Safety
779
        No-throw guarantee.
780
781
        @param pos The index of the element to return.
782
    */
783
    inline
784
    value const*
785
    if_contains(std::size_t pos) const noexcept;
786
787
    /** Return a pointer to an element, or nullptr if the index is invalid
788
789
        This function returns a pointer to the element
790
        at index `pos` when the index is less then the size
791
        of the container. Otherwise it returns null.
792
793
        @par Example
794
        @code
795
        if( auto p = arr.if_contains( 1 ) )
796
            std::cout << *p;
797
        @endcode
798
799
        @par Complexity
800
        Constant.
801
802
        @par Exception Safety
803
        No-throw guarantee.
804
805
        @param pos The index of the element to return.
806
    */
807
    inline
808
    value*
809
    if_contains(std::size_t pos) noexcept;
810
811
    //------------------------------------------------------
812
    //
813
    // Iterators
814
    //
815
    //------------------------------------------------------
816
817
    /** Return an iterator to the first element.
818
819
        If the container is empty, @ref end() is returned.
820
821
        @par Complexity
822
        Constant.
823
824
        @par Exception Safety
825
        No-throw guarantee.
826
    */
827
    inline
828
    iterator
829
    begin() noexcept;
830
831
    /** Return a const iterator to the first element.
832
833
        If the container is empty, @ref end() is returned.
834
835
        @par Complexity
836
        Constant.
837
838
        @par Exception Safety
839
        No-throw guarantee.
840
    */
841
    inline
842
    const_iterator
843
    begin() const noexcept;
844
845
    /** Return a const iterator to the first element.
846
847
        If the container is empty, @ref cend() is returned.
848
849
        @par Complexity
850
        Constant.
851
852
        @par Exception Safety
853
        No-throw guarantee.
854
    */
855
    inline
856
    const_iterator
857
    cbegin() const noexcept;
858
859
    /** Return an iterator to the element following the last element.
860
861
        The element acts as a placeholder; attempting
862
        to access it results in undefined behavior.
863
864
        @par Complexity
865
        Constant.
866
867
        @par Exception Safety
868
        No-throw guarantee.
869
    */
870
    inline
871
    iterator
872
    end() noexcept;
873
874
    /** Return a const iterator to the element following the last element.
875
876
        The element acts as a placeholder; attempting
877
        to access it results in undefined behavior.
878
879
        @par Complexity
880
        Constant.
881
882
        @par Exception Safety
883
        No-throw guarantee.
884
    */
885
    inline
886
    const_iterator
887
    end() const noexcept;
888
889
    /** Return a const iterator to the element following the last element.
890
891
        The element acts as a placeholder; attempting
892
        to access it results in undefined behavior.
893
894
        @par Complexity
895
        Constant.
896
897
        @par Exception Safety
898
        No-throw guarantee.
899
    */
900
    inline
901
    const_iterator
902
    cend() const noexcept;
903
904
    /** Return a reverse iterator to the first element of the reversed container.
905
906
        The pointed-to element corresponds to the
907
        last element of the non-reversed container.
908
        If the container is empty, @ref rend() is returned.
909
910
        @par Complexity
911
        Constant.
912
913
        @par Exception Safety
914
        No-throw guarantee.
915
    */
916
    inline
917
    reverse_iterator
918
    rbegin() noexcept;
919
920
    /** Return a const reverse iterator to the first element of the reversed container.
921
922
        The pointed-to element corresponds to the
923
        last element of the non-reversed container.
924
        If the container is empty, @ref rend() is returned.
925
926
        @par Complexity
927
        Constant.
928
929
        @par Exception Safety
930
        No-throw guarantee.
931
    */
932
    inline
933
    const_reverse_iterator
934
    rbegin() const noexcept;
935
936
    /** Return a const reverse iterator to the first element of the reversed container.
937
938
        The pointed-to element corresponds to the
939
        last element of the non-reversed container.
940
        If the container is empty, @ref crend() is returned.
941
942
        @par Complexity
943
        Constant.
944
945
        @par Exception Safety
946
        No-throw guarantee.
947
    */
948
    inline
949
    const_reverse_iterator
950
    crbegin() const noexcept;
951
952
    /** Return a reverse iterator to the element following the last element of the reversed container.
953
954
        The pointed-to element corresponds to the element
955
        preceding the first element of the non-reversed container.
956
        The element acts as a placeholder; attempting
957
        to access it results in undefined behavior.
958
959
        @par Complexity
960
        Constant.
961
962
        @par Exception Safety
963
        No-throw guarantee.
964
    */
965
    inline
966
    reverse_iterator
967
    rend() noexcept;
968
969
    /** Return a const reverse iterator to the element following the last element of the reversed container.
970
971
        The pointed-to element corresponds to the element
972
        preceding the first element of the non-reversed container.
973
        The element acts as a placeholder; attempting
974
        to access it results in undefined behavior.
975
976
        @par Complexity
977
        Constant.
978
979
        @par Exception Safety
980
        No-throw guarantee.
981
    */
982
    inline
983
    const_reverse_iterator
984
    rend() const noexcept;
985
986
    /** Return a const reverse iterator to the element following the last element of the reversed container.
987
988
        The pointed-to element corresponds to the element
989
        preceding the first element of the non-reversed container.
990
        The element acts as a placeholder; attempting
991
        to access it results in undefined behavior.
992
993
        @par Complexity
994
        Constant.
995
996
        @par Exception Safety
997
        No-throw guarantee.
998
    */
999
    inline
1000
    const_reverse_iterator
1001
    crend() const noexcept;
1002
1003
    //------------------------------------------------------
1004
    //
1005
    // Capacity
1006
    //
1007
    //------------------------------------------------------
1008
1009
    /** Return the number of elements in the array.
1010
1011
        This returns the number of elements in the array.
1012
        The value returned may be different from the number
1013
        returned from @ref capacity.
1014
1015
        @par Complexity
1016
        Constant.
1017
1018
        @par Exception Safety
1019
        No-throw guarantee.
1020
    */
1021
    inline
1022
    std::size_t
1023
    size() const noexcept;
1024
1025
    /** Return the maximum number of elements any array can hold.
1026
1027
        The maximum is an implementation-defined number.
1028
        This value is a theoretical limit; at runtime,
1029
        the actual maximum size may be less due to
1030
        resource limits.
1031
1032
        @par Complexity
1033
        Constant.
1034
1035
        @par Exception Safety
1036
        No-throw guarantee.
1037
    */
1038
    static
1039
    inline
1040
    constexpr
1041
    std::size_t
1042
    max_size() noexcept;
1043
1044
    /** Return the number of elements that can be held in currently allocated memory.
1045
1046
        This number may be larger than the value returned
1047
        by @ref size().
1048
1049
        @par Complexity
1050
        Constant.
1051
1052
        @par Exception Safety
1053
        No-throw guarantee.
1054
    */
1055
    inline
1056
    std::size_t
1057
    capacity() const noexcept;
1058
1059
    /** Check if the array has no elements.
1060
1061
        Returns `true` if there are no elements in the
1062
        array, i.e. @ref size() returns 0.
1063
1064
        @par Complexity
1065
        Constant.
1066
1067
        @par Exception Safety
1068
        No-throw guarantee.
1069
    */
1070
    inline
1071
    bool
1072
    empty() const noexcept;
1073
1074
    /** Increase the capacity to at least a certain amount.
1075
1076
        This increases the @ref capacity() to a value
1077
        that is greater than or equal to `new_capacity`.
1078
        If `new_capacity > capacity()`, new memory is
1079
        allocated. Otherwise, the call has no effect.
1080
        The number of elements and therefore the
1081
        @ref size() of the container is not changed.
1082
    \n
1083
        If new memory is allocated, all iterators
1084
        including any past-the-end iterators, and all
1085
        references to the elements are invalidated.
1086
        Otherwise, no iterators or references are
1087
        invalidated.
1088
1089
        @par Complexity
1090
        At most, linear in @ref size().
1091
1092
        @par Exception Safety
1093
        Strong guarantee.
1094
        Calls to `memory_resource::allocate` may throw.
1095
1096
        @param new_capacity The new capacity of the array.
1097
1098
        @throw `boost::system::system_error` `new_capacity > max_size()`.
1099
    */
1100
    inline
1101
    void
1102
    reserve(std::size_t new_capacity);
1103
1104
    /** Request the removal of unused capacity.
1105
1106
        This performs a non-binding request to reduce the
1107
        capacity to the current size. The request may or
1108
        may not be fulfilled. If reallocation occurs, all
1109
        iterators including any past-the-end iterators,
1110
        and all references to the elements are invalidated.
1111
        Otherwise, no iterators or references are
1112
        invalidated.
1113
1114
        @par Complexity
1115
        At most, linear in @ref size().
1116
1117
        @par Exception Safety
1118
        No-throw guarantee.
1119
    */
1120
    BOOST_JSON_DECL
1121
    void
1122
    shrink_to_fit() noexcept;
1123
1124
    //------------------------------------------------------
1125
    //
1126
    // Modifiers
1127
    //
1128
    //------------------------------------------------------
1129
1130
    /** Clear the contents.
1131
1132
        Erases all elements from the container. After this
1133
        call, @ref size() returns zero but @ref capacity()
1134
        is unchanged. All references, pointers, or iterators
1135
        referring to contained elements are invalidated. Any
1136
        past-the-end iterators are also invalidated.
1137
1138
        @par Complexity
1139
        Linear in @ref size().
1140
1141
        @par Exception Safety
1142
        No-throw guarantee.
1143
    */
1144
    BOOST_JSON_DECL
1145
    void
1146
    clear() noexcept;
1147
1148
    /** Insert elements before the specified location.
1149
1150
        This inserts a copy of `v` before `pos`.
1151
        If `capacity() < size() + 1`, a reallocation
1152
        occurs first, and all iterators and references
1153
        are invalidated.
1154
        Otherwise, only the iterators and references from
1155
        the insertion point forward are invalidated. All
1156
        past-the-end iterators are also invalidated.
1157
1158
        @par Complexity
1159
        Constant plus linear in `std::distance(pos, end())`.
1160
1161
        @par Exception Safety
1162
        Strong guarantee.
1163
        Calls to `memory_resource::allocate` may throw.
1164
1165
        @param pos Iterator before which the content will
1166
        be inserted. This may be the @ref end() iterator.
1167
1168
        @param v The value to insert. A copy will be made
1169
        using container's associated `boost::container::pmr::memory_resource`.
1170
1171
        @return An iterator to the inserted value
1172
    */
1173
    BOOST_JSON_DECL
1174
    iterator
1175
    insert(
1176
        const_iterator pos,
1177
        value const& v);
1178
1179
    /** Insert elements before the specified location.
1180
1181
        This inserts `v` before `pos` via move-construction.
1182
        If `capacity() < size() + 1`, a reallocation occurs
1183
        first, and all iterators and references are
1184
        invalidated.
1185
        Otherwise, only the iterators and references from
1186
        the insertion point forward are invalidated. All
1187
        past-the-end iterators are also invalidated.
1188
1189
        @par Complexity
1190
        Constant plus linear in `std::distance(pos, end())`.
1191
1192
        @par Exception Safety
1193
        Strong guarantee.
1194
        Calls to `memory_resource::allocate` may throw.
1195
1196
        @param pos Iterator before which the content will
1197
        be inserted. This may be the @ref end() iterator.
1198
1199
        @param v The value to insert. Ownership of the
1200
        value will be transferred via move construction,
1201
        using the container's
1202
        associated `boost::container::pmr::memory_resource`.
1203
1204
        @return An iterator to the inserted value
1205
    */
1206
    BOOST_JSON_DECL
1207
    iterator
1208
    insert(
1209
        const_iterator pos,
1210
        value&& v);
1211
1212
    /** Insert elements before the specified location.
1213
1214
        This inserts `count` copies of `v` before `pos`.
1215
        If `capacity() < size() + count`, a reallocation
1216
        occurs first, and all iterators and references are
1217
        invalidated.
1218
        Otherwise, only the iterators and references from
1219
        the insertion point forward are invalidated. All
1220
        past-the-end iterators are also invalidated.
1221
1222
        @par Complexity
1223
        Linear in `count + std::distance(pos, end())`.
1224
1225
        @par Exception Safety
1226
        Strong guarantee.
1227
        Calls to `memory_resource::allocate` may throw.
1228
1229
        @param pos Iterator before which the content will
1230
        be inserted. This may be the @ref end() iterator.
1231
1232
        @param count The number of copies to insert.
1233
1234
        @param v The value to insert. Copies will be made
1235
        using the container's
1236
        associated `boost::container::pmr::memory_resource`.
1237
1238
        @return An iterator to the first inserted value,
1239
        or `pos` if `count == 0`.
1240
    */
1241
    BOOST_JSON_DECL
1242
    iterator
1243
    insert(
1244
        const_iterator pos,
1245
        std::size_t count,
1246
        value const& v);
1247
1248
    /** Insert elements before the specified location.
1249
1250
        The elements in the range `{first, last)` are
1251
        inserted in order.
1252
        If `capacity() < size() + std::distance(first, last)`,
1253
        a reallocation occurs first, and all iterators and
1254
        references are invalidated.
1255
        Otherwise, only the iterators and references from
1256
        the insertion point forward are invalidated. All
1257
        past-the-end iterators are also invalidated.
1258
1259
        @par Precondition
1260
        `first` and `last` are not iterators into `*this`.
1261
1262
        @par Constraints
1263
        @code
1264
        not std::is_convertible_v<InputIt, value>
1265
        @endcode
1266
1267
        @par Mandates
1268
        @code
1269
        std::is_constructible_v<value, std::iterator_traits<InputIt>::reference>
1270
        @endcode
1271
1272
        @par Complexity
1273
        Linear in `std::distance(first, last) + std::distance(pos, end())`.
1274
1275
        @par Exception Safety
1276
        Strong guarantee.
1277
        Calls to `memory_resource::allocate` may throw.
1278
1279
        @return An iterator to the first inserted value, or
1280
        `pos` if `first == last`.
1281
1282
        @param pos Iterator before which the content will
1283
        be inserted. This may be the @ref end() iterator.
1284
1285
        @param first An input iterator pointing to the first
1286
        element to insert, or pointing to the end of the range.
1287
1288
        @param last An input iterator pointing to the end
1289
        of the range.
1290
1291
        @tparam InputIt a type satisfying the requirements
1292
        of __InputIterator__.
1293
    */
1294
    template<
1295
        class InputIt
1296
    #ifndef BOOST_JSON_DOCS
1297
        ,class = typename std::enable_if<
1298
            std::is_constructible<value,
1299
                typename std::iterator_traits<
1300
                    InputIt>::reference>::value>::type
1301
    #endif
1302
    >
1303
    iterator
1304
    insert(
1305
        const_iterator pos,
1306
        InputIt first, InputIt last);
1307
1308
    /** Insert elements before the specified location.
1309
1310
        The elements in the initializer list `init` are
1311
        inserted in order.
1312
        If `capacity() < size() + init.size()`,
1313
        a reallocation occurs first, and all iterators and
1314
        references are invalidated.
1315
        Otherwise, only the iterators and references from
1316
        the insertion point forward are invalidated. All
1317
        past-the-end iterators are also invalidated.
1318
1319
        @par Complexity
1320
        Linear in `init.size() + std::distance(pos, end())`.
1321
1322
        @par Exception Safety
1323
        Strong guarantee.
1324
        Calls to `memory_resource::allocate` may throw.
1325
1326
        @param pos Iterator before which the content will
1327
        be inserted. This may be the @ref end() iterator.
1328
1329
        @param init The initializer list to insert
1330
1331
        @return An iterator to the first inserted value, or
1332
        `pos` if `init.size() == 0`.
1333
    */
1334
    BOOST_JSON_DECL
1335
    iterator
1336
    insert(
1337
        const_iterator pos,
1338
        std::initializer_list<value_ref> init);
1339
1340
    /** Insert a constructed element in-place.
1341
1342
        Inserts a new element into the container directly before
1343
        `pos`. The element is constructed using placement-new
1344
        with the parameter `std::forward<Arg>(arg)`.
1345
        If `capacity() < size() + 1`,
1346
        a reallocation occurs first, and all iterators and
1347
        references are invalidated.
1348
        Otherwise, only the iterators and references from
1349
        the insertion point forward are invalidated. All
1350
        past-the-end iterators are also invalidated.
1351
1352
        @par Complexity
1353
        Constant plus linear in `std::distance(pos, end())`.
1354
1355
        @par Exception Safety
1356
        Strong guarantee.
1357
        Calls to `memory_resource::allocate` may throw.
1358
1359
        @param pos Iterator before which the element will
1360
        be inserted. This may be the @ref end() iterator.
1361
1362
        @param arg The argument to forward to the @ref value
1363
        constructor.
1364
1365
        @return An iterator to the inserted element
1366
    */
1367
    template<class Arg>
1368
    iterator
1369
    emplace(
1370
        const_iterator pos,
1371
        Arg&& arg);
1372
1373
    /** Erase elements from the container.
1374
1375
        The element at `pos` is removed.
1376
1377
        @par Complexity
1378
        Constant plus linear in `std::distance(pos, end())`
1379
1380
        @par Exception Safety
1381
        No-throw guarantee.
1382
1383
        @param pos Iterator to the element to remove
1384
1385
        @return Iterator following the last removed element.
1386
        If the iterator `pos` refers to the last element,
1387
        the @ref end() iterator is returned.
1388
    */
1389
    BOOST_JSON_DECL
1390
    iterator
1391
    erase(const_iterator pos) noexcept;
1392
1393
    /** Erase elements from the container.
1394
1395
        The elements in the range `{first, last)` are removed.
1396
1397
        @par Complexity
1398
        Linear in `std::distance(first, end())`
1399
1400
        @par Exception Safety
1401
        No-throw guarantee.
1402
1403
        @param first An iterator pointing to the first
1404
        element to erase, or pointing to the end of the range.
1405
1406
        @param last An iterator pointing to one past the
1407
        last element to erase, or pointing to the end of the
1408
        range.
1409
1410
        @return Iterator following the last removed element.
1411
        If the iterator `last` refers to the last element,
1412
        the @ref end() iterator is returned.
1413
    */
1414
    BOOST_JSON_DECL
1415
    iterator
1416
    erase(
1417
        const_iterator first,
1418
        const_iterator last) noexcept;
1419
1420
    /** Add an element to the end.
1421
1422
        This appends a copy of `v` to the container's
1423
        elements.
1424
        If `capacity() < size() + 1`, a reallocation
1425
        occurs first, and all iterators and references
1426
        are invalidated. Any past-the-end iterators are
1427
        always invalidated.
1428
1429
        @par Complexity
1430
        Amortized constant.
1431
1432
        @par Exception Safety
1433
        Strong guarantee.
1434
        Calls to `memory_resource::allocate` may throw.
1435
1436
        @param v The value to insert. A copy will be made using the container's
1437
        associated `boost::container::pmr::memory_resource`.
1438
    */
1439
    BOOST_JSON_DECL
1440
    void
1441
    push_back(value const& v);
1442
1443
    /** Add an element to the end.
1444
1445
        This appends `v` to the container's elements via
1446
        move-construction.
1447
        If `capacity() < size() + 1`, a reallocation
1448
        occurs first, and all iterators and references
1449
        are invalidated. Any past-the-end iterators are
1450
        always invalidated.
1451
1452
        @par Complexity
1453
        Amortized constant.
1454
1455
        @par Exception Safety
1456
        Strong guarantee.
1457
        Calls to `memory_resource::allocate` may throw.
1458
1459
        @param v The value to insert. Ownership of the value will be
1460
        transferred via move construction, using the container's
1461
        associated `boost::container::pmr::memory_resource`.
1462
    */
1463
    BOOST_JSON_DECL
1464
    void
1465
    push_back(value&& v);
1466
1467
    /** Append a constructed element in-place.
1468
1469
        Appends a new element to the end of the container's
1470
        list of elements.
1471
        The element is constructed using placement-new
1472
        with the parameter `std::forward<Arg>(arg)`.
1473
        If `capacity() < size() + 1`,
1474
        a reallocation occurs first, and all iterators and
1475
        references are invalidated.
1476
        Otherwise, only the iterators and references from
1477
        the insertion point forward are invalidated. All
1478
        past-the-end iterators are also invalidated.
1479
1480
        @par Complexity
1481
        Amortized constant.
1482
1483
        @par Exception Safety
1484
        Strong guarantee.
1485
        Calls to `memory_resource::allocate` may throw.
1486
1487
        @param arg The argument to forward to the @ref value
1488
        constructor.
1489
1490
        @return A reference to the inserted element
1491
    */
1492
    template<class Arg>
1493
    value&
1494
    emplace_back(Arg&& arg);
1495
1496
    /** Remove the last element
1497
1498
        The last element of the container is erased.
1499
1500
        @par Precondition
1501
        `not empty()`
1502
1503
        @par Exception Safety
1504
        No-throw guarantee.
1505
    */
1506
    BOOST_JSON_DECL
1507
    void
1508
    pop_back() noexcept;
1509
1510
    /** Change the number of elements stored.
1511
1512
        Resizes the container to contain `count` elements.
1513
        If `capacity() < size() + count`, a reallocation
1514
        occurs first, and all iterators and references
1515
        are invalidated. Any past-the-end iterators are
1516
        always invalidated.
1517
1518
        @li If `size() > count`, the container is reduced
1519
        to its first `count` elements.
1520
1521
        @li If `size() < count`, additional null values
1522
        are appended.
1523
1524
        @par Complexity
1525
        Linear in `abs(size() - count)`, plus the cost of
1526
        reallocation if @ref capacity() is less than `count`.
1527
1528
        @par Exception Safety
1529
        Strong guarantee.
1530
        Calls to `memory_resource::allocate` may throw.
1531
1532
        @param count The new size of the container.
1533
    */
1534
    BOOST_JSON_DECL
1535
    void
1536
    resize(std::size_t count);
1537
1538
    /** Change the number of elements stored.
1539
1540
        Resizes the container to contain `count` elements.
1541
        If `capacity() < size() + count`, a reallocation
1542
        occurs first, and all iterators and references
1543
        are invalidated. Any past-the-end iterators are
1544
        always invalidated.
1545
1546
        @li If `size() > count`, the container is reduced
1547
        to its first `count` elements.
1548
1549
        @li If `size() < count`, additional copies of `v`
1550
        are appended.
1551
1552
        @par Complexity
1553
        Linear in `abs(size() - count)`, plus the cost of
1554
        reallocation if @ref capacity() is less than `count`.
1555
1556
        @par Exception Safety
1557
        Strong guarantee.
1558
        Calls to `memory_resource::allocate` may throw.
1559
1560
        @param count The new size of the container.
1561
1562
        @param v The @ref value to copy into the new elements.
1563
    */
1564
    BOOST_JSON_DECL
1565
    void
1566
    resize(
1567
        std::size_t count,
1568
        value const& v);
1569
1570
    /** Swap the contents.
1571
1572
        Exchanges the contents of this array with another
1573
        array. Ownership of the respective
1574
        `boost::container::pmr::memory_resource` objects is not transferred.
1575
1576
        @li If `*other.storage() == *this->storage()`,
1577
        ownership of the underlying memory is swapped in
1578
        constant time, with no possibility of exceptions.
1579
        All iterators and references remain valid.
1580
1581
        @li If `*other.storage() != *this->storage()`,
1582
        the contents are logically swapped by making copies,
1583
        which can throw. In this case all iterators and
1584
        references are invalidated.
1585
1586
        @par Complexity
1587
        Constant or linear in @ref size() plus `other.size()`.
1588
1589
        @par Exception Safety
1590
        Strong guarantee.
1591
        Calls to `memory_resource::allocate` may throw.
1592
1593
        @param other The value to swap with.
1594
        If `this == &other`, this function call has no effect.
1595
    */
1596
    BOOST_JSON_DECL
1597
    void
1598
    swap(array& other);
1599
1600
    /** Exchange the given values.
1601
1602
        Exchanges the contents of the array `lhs` with another array `rhs`.
1603
        Ownership of the respective `boost::container::pmr::memory_resource`
1604
        objects is not transferred.
1605
1606
        @li If `*lhs.storage() == *rhs.storage()`,
1607
        ownership of the underlying memory is swapped in
1608
        constant time, with no possibility of exceptions.
1609
        All iterators and references remain valid.
1610
1611
        @li If `*lhs.storage() != *rhs.storage()`,
1612
        the contents are logically swapped by making a copy,
1613
        which can throw. In this case all iterators and
1614
        references are invalidated.
1615
1616
        @par Effects
1617
        @code
1618
        lhs.swap( rhs );
1619
        @endcode
1620
1621
        @par Complexity
1622
        Constant or linear in `lhs.size() + rhs.size()`.
1623
1624
        @par Exception Safety
1625
        Strong guarantee.
1626
        Calls to `memory_resource::allocate` may throw.
1627
1628
        @param lhs The array to exchange.
1629
1630
        @param rhs The array to exchange.
1631
        If `&lhs == &rhs`, this function call has no effect.
1632
1633
        @see @ref array::swap
1634
    */
1635
    friend
1636
    void
1637
    swap(array& lhs, array& rhs)
1638
    {
1639
        lhs.swap(rhs);
1640
    }
1641
1642
    /** Return `true` if two arrays are equal.
1643
1644
        Arrays are equal when their sizes are
1645
        the same, and they are element-for-element
1646
        equal in order.
1647
1648
        @par Effects
1649
        `return std::equal( lhs.begin(), lhs.end(), rhs.begin(), rhs.end() );`
1650
1651
        @par Complexity
1652
        Constant or linear in `lhs.size()`.
1653
1654
        @par Exception Safety
1655
        No-throw guarantee.
1656
    */
1657
    // inline friend speeds up overload resolution
1658
    friend
1659
    bool
1660
    operator==(
1661
        array const& lhs,
1662
        array const& rhs) noexcept
1663
0
    {
1664
0
        return lhs.equal(rhs);
1665
0
    }
1666
1667
    /** Return `true` if two arrays are not equal.
1668
1669
        Arrays are equal when their sizes are
1670
        the same, and they are element-for-element
1671
        equal in order.
1672
1673
        @par Effects
1674
        `return ! std::equal( lhs.begin(), lhs.end(), rhs.begin(), rhs.end() );`
1675
1676
        @par Complexity
1677
        Constant or linear in `lhs.size()`.
1678
1679
        @par Exception Safety
1680
        No-throw guarantee.
1681
    */
1682
    // inline friend speeds up overload resolution
1683
    friend
1684
    bool
1685
    operator!=(
1686
        array const& lhs,
1687
        array const& rhs) noexcept
1688
    {
1689
        return ! (lhs == rhs);
1690
    }
1691
1692
    /** Serialize @ref array to an output stream.
1693
1694
        This function serializes an `array` as JSON into the output stream.
1695
1696
        @return Reference to `os`.
1697
1698
        @par Complexity
1699
        Constant or linear in the size of `arr`.
1700
1701
        @par Exception Safety
1702
        Strong guarantee.
1703
        Calls to `memory_resource::allocate` may throw.
1704
1705
        @param os The output stream to serialize to.
1706
1707
        @param arr The value to serialize.
1708
    */
1709
    BOOST_JSON_DECL
1710
    friend
1711
    std::ostream&
1712
    operator<<(
1713
        std::ostream& os,
1714
        array const& arr);
1715
1716
private:
1717
    template<class It>
1718
    using iter_cat = typename
1719
        std::iterator_traits<It>::iterator_category;
1720
1721
    template<class InputIt>
1722
    array(
1723
        InputIt first, InputIt last,
1724
        storage_ptr sp,
1725
        std::input_iterator_tag);
1726
1727
    template<class InputIt>
1728
    array(
1729
        InputIt first, InputIt last,
1730
        storage_ptr sp,
1731
        std::forward_iterator_tag);
1732
1733
    inline
1734
    std::size_t
1735
    growth(std::size_t new_size) const;
1736
1737
    BOOST_JSON_DECL
1738
    void
1739
    reserve_impl(
1740
        std::size_t new_capacity);
1741
1742
    BOOST_JSON_DECL
1743
    value&
1744
    push_back(
1745
        pilfered<value> pv);
1746
1747
    BOOST_JSON_DECL
1748
    iterator
1749
    insert(
1750
        const_iterator pos,
1751
        pilfered<value> pv);
1752
1753
    template<class InputIt>
1754
    iterator
1755
    insert(
1756
        const_iterator pos,
1757
        InputIt first, InputIt last,
1758
        std::input_iterator_tag);
1759
1760
    template<class InputIt>
1761
    iterator
1762
    insert(
1763
        const_iterator pos,
1764
        InputIt first, InputIt last,
1765
        std::forward_iterator_tag);
1766
1767
    BOOST_JSON_DECL
1768
    bool
1769
    equal(array const& other) const noexcept;
1770
};
1771
1772
} // namespace json
1773
} // namespace boost
1774
1775
// std::hash specialization
1776
#ifndef BOOST_JSON_DOCS
1777
namespace std {
1778
template <>
1779
struct hash< ::boost::json::array > {
1780
    BOOST_JSON_DECL
1781
    std::size_t
1782
    operator()(::boost::json::array const& ja) const noexcept;
1783
};
1784
} // std
1785
#endif
1786
1787
// Must be included here for this file to stand alone
1788
#include <boost/json/value.hpp>
1789
1790
// includes are at the bottom of <boost/json/value.hpp>
1791
1792
#endif