Coverage Report

Created: 2025-12-17 17:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/prevector.h
Line
Count
Source
1
// Copyright (c) 2015-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#ifndef BITCOIN_PREVECTOR_H
6
#define BITCOIN_PREVECTOR_H
7
8
#include <algorithm>
9
#include <cassert>
10
#include <cstddef>
11
#include <cstdint>
12
#include <cstdlib>
13
#include <cstring>
14
#include <iterator>
15
#include <type_traits>
16
#include <utility>
17
18
/** Implements a drop-in replacement for std::vector<T> which stores up to N
19
 *  elements directly (without heap allocation). The types Size and Diff are
20
 *  used to store element counts, and can be any unsigned + signed type.
21
 *
22
 *  Storage layout is either:
23
 *  - Direct allocation:
24
 *    - Size _size: the number of used elements (between 0 and N)
25
 *    - T direct[N]: an array of N elements of type T
26
 *      (only the first _size are initialized).
27
 *  - Indirect allocation:
28
 *    - Size _size: the number of used elements plus N + 1
29
 *    - Size capacity: the number of allocated elements
30
 *    - T* indirect: a pointer to an array of capacity elements of type T
31
 *      (only the first _size are initialized).
32
 *
33
 *  The data type T must be movable by memmove/realloc(). Once we switch to C++,
34
 *  move constructors can be used instead.
35
 */
36
template<unsigned int N, typename T, typename Size = uint32_t, typename Diff = int32_t>
37
class prevector {
38
    static_assert(std::is_trivially_copyable_v<T>);
39
40
public:
41
    static constexpr unsigned int STATIC_SIZE{N};
42
43
    typedef Size size_type;
44
    typedef Diff difference_type;
45
    typedef T value_type;
46
    typedef value_type& reference;
47
    typedef const value_type& const_reference;
48
    typedef value_type* pointer;
49
    typedef const value_type* const_pointer;
50
51
    class iterator {
52
        T* ptr{};
53
    public:
54
        typedef Diff difference_type;
55
        typedef T* pointer;
56
        typedef T& reference;
57
        using element_type = T;
58
        using iterator_category = std::contiguous_iterator_tag;
59
        iterator() = default;
60
0
        iterator(T* ptr_) : ptr(ptr_) {}
Unexecuted instantiation: _ZN9prevectorILj16EhjiE8iteratorC2EPh
Unexecuted instantiation: _ZN9prevectorILj36EhjiE8iteratorC2EPh
Unexecuted instantiation: _ZN9prevectorILj8EijiE8iteratorC2EPi
Unexecuted instantiation: _ZN9prevectorILj33EhjiE8iteratorC2EPh
Unexecuted instantiation: _ZN9prevectorILj35EhjiE8iteratorC2EPh
61
0
        T& operator*() const { return *ptr; }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE8iteratordeEv
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE8iteratordeEv
Unexecuted instantiation: _ZNK9prevectorILj8EijiE8iteratordeEv
Unexecuted instantiation: _ZNK9prevectorILj33EhjiE8iteratordeEv
Unexecuted instantiation: _ZNK9prevectorILj35EhjiE8iteratordeEv
62
0
        T* operator->() const { return ptr; }
Unexecuted instantiation: _ZNK9prevectorILj33EhjiE8iteratorptEv
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE8iteratorptEv
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE8iteratorptEv
Unexecuted instantiation: _ZNK9prevectorILj35EhjiE8iteratorptEv
63
        T& operator[](size_type pos) const { return ptr[pos]; }
64
0
        iterator& operator++() { ptr++; return *this; }
65
        iterator& operator--() { ptr--; return *this; }
66
        iterator operator++(int) { iterator copy(*this); ++(*this); return copy; }
67
        iterator operator--(int) { iterator copy(*this); --(*this); return copy; }
68
0
        difference_type friend operator-(iterator a, iterator b) { return (&(*a) - &(*b)); }
Unexecuted instantiation: _ZmiN9prevectorILj36EhjiE8iteratorES1_
Unexecuted instantiation: _ZmiN9prevectorILj16EhjiE8iteratorES1_
Unexecuted instantiation: _ZmiN9prevectorILj8EijiE8iteratorES1_
Unexecuted instantiation: _ZmiN9prevectorILj33EhjiE8iteratorES1_
Unexecuted instantiation: _ZmiN9prevectorILj35EhjiE8iteratorES1_
69
0
        iterator operator+(size_type n) const { return iterator(ptr + n); }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE8iteratorplEj
Unexecuted instantiation: _ZNK9prevectorILj8EijiE8iteratorplEj
Unexecuted instantiation: _ZNK9prevectorILj33EhjiE8iteratorplEj
70
        iterator friend operator+(size_type n, iterator x) { return x + n; }
71
        iterator& operator+=(size_type n) { ptr += n; return *this; }
72
0
        iterator operator-(size_type n) const { return iterator(ptr - n); }
73
        iterator& operator-=(size_type n) { ptr -= n; return *this; }
74
0
        bool operator==(iterator x) const { return ptr == x.ptr; }
75
0
        auto operator<=>(iterator x) const { return ptr <=> x.ptr; }
Unexecuted instantiation: _ZNK9prevectorILj33EhjiE8iteratorssES1_
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE8iteratorssES1_
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE8iteratorssES1_
Unexecuted instantiation: _ZNK9prevectorILj35EhjiE8iteratorssES1_
76
    };
77
78
    class const_iterator {
79
        const T* ptr{};
80
    public:
81
        typedef Diff difference_type;
82
        typedef const T* pointer;
83
        typedef const T& reference;
84
        using element_type = const T;
85
        using iterator_category = std::contiguous_iterator_tag;
86
        const_iterator() = default;
87
0
        const_iterator(const T* ptr_) : ptr(ptr_) {}
Unexecuted instantiation: _ZN9prevectorILj16EhjiE14const_iteratorC2EPKh
Unexecuted instantiation: _ZN9prevectorILj36EhjiE14const_iteratorC2EPKh
Unexecuted instantiation: _ZN9prevectorILj8EijiE14const_iteratorC2EPKi
88
0
        const_iterator(iterator x) : ptr(&(*x)) {}
89
0
        const T& operator*() const { return *ptr; }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE14const_iteratordeEv
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE14const_iteratordeEv
Unexecuted instantiation: _ZNK9prevectorILj8EijiE14const_iteratordeEv
90
0
        const T* operator->() const { return ptr; }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE14const_iteratorptEv
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE14const_iteratorptEv
91
0
        const T& operator[](size_type pos) const { return ptr[pos]; }
Unexecuted instantiation: _ZNK9prevectorILj8EijiE14const_iteratorixEj
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE14const_iteratorixEj
92
0
        const_iterator& operator++() { ptr++; return *this; }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE14const_iteratorppEv
Unexecuted instantiation: _ZN9prevectorILj16EhjiE14const_iteratorppEv
Unexecuted instantiation: _ZN9prevectorILj8EijiE14const_iteratorppEv
93
0
        const_iterator& operator--() { ptr--; return *this; }
Unexecuted instantiation: _ZN9prevectorILj8EijiE14const_iteratormmEv
Unexecuted instantiation: _ZN9prevectorILj36EhjiE14const_iteratormmEv
94
0
        const_iterator operator++(int) { const_iterator copy(*this); ++(*this); return copy; }
95
        const_iterator operator--(int) { const_iterator copy(*this); --(*this); return copy; }
96
0
        difference_type friend operator-(const_iterator a, const_iterator b) { return (&(*a) - &(*b)); }
Unexecuted instantiation: _ZmiN9prevectorILj16EhjiE14const_iteratorES1_
Unexecuted instantiation: _ZmiN9prevectorILj36EhjiE14const_iteratorES1_
Unexecuted instantiation: _ZmiN9prevectorILj8EijiE14const_iteratorES1_
97
0
        const_iterator operator+(size_type n) const { return const_iterator(ptr + n); }
Unexecuted instantiation: _ZNK9prevectorILj8EijiE14const_iteratorplEj
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE14const_iteratorplEj
98
        const_iterator friend operator+(size_type n, const_iterator x) { return x + n; }
99
0
        const_iterator& operator+=(size_type n) { ptr += n; return *this; }
100
0
        const_iterator operator-(size_type n) const { return const_iterator(ptr - n); }
Unexecuted instantiation: _ZNK9prevectorILj8EijiE14const_iteratormiEj
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE14const_iteratormiEj
101
        const_iterator& operator-=(size_type n) { ptr -= n; return *this; }
102
0
        bool operator==(const_iterator x) const { return ptr == x.ptr; }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE14const_iteratoreqES1_
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE14const_iteratoreqES1_
Unexecuted instantiation: _ZNK9prevectorILj8EijiE14const_iteratoreqES1_
103
0
        auto operator<=>(const_iterator x) const { return ptr <=> x.ptr; }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE14const_iteratorssES1_
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE14const_iteratorssES1_
Unexecuted instantiation: _ZNK9prevectorILj8EijiE14const_iteratorssES1_
104
    };
105
106
private:
107
#pragma pack(push, 1)
108
    union direct_or_indirect {
109
        char direct[sizeof(T) * N];
110
        struct {
111
            char* indirect;
112
            size_type capacity;
113
        } indirect_contents;
114
    };
115
#pragma pack(pop)
116
    alignas(char*) direct_or_indirect _union = {};
117
    size_type _size = 0;
118
119
    static_assert(alignof(char*) % alignof(size_type) == 0 && sizeof(char*) % alignof(size_type) == 0, "size_type cannot have more restrictive alignment requirement than pointer");
120
    static_assert(alignof(char*) % alignof(T) == 0, "value_type T cannot have more restrictive alignment requirement than pointer");
121
122
0
    T* direct_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.direct) + pos; }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE10direct_ptrEi
Unexecuted instantiation: _ZN9prevectorILj33EhjiE10direct_ptrEi
Unexecuted instantiation: _ZN9prevectorILj16EhjiE10direct_ptrEi
Unexecuted instantiation: _ZN9prevectorILj8EijiE10direct_ptrEi
Unexecuted instantiation: _ZN9prevectorILj35EhjiE10direct_ptrEi
123
0
    const T* direct_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.direct) + pos; }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE10direct_ptrEi
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE10direct_ptrEi
Unexecuted instantiation: _ZNK9prevectorILj8EijiE10direct_ptrEi
Unexecuted instantiation: _ZNK9prevectorILj33EhjiE10direct_ptrEi
124
0
    T* indirect_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.indirect_contents.indirect) + pos; }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE12indirect_ptrEi
Unexecuted instantiation: _ZN9prevectorILj33EhjiE12indirect_ptrEi
Unexecuted instantiation: _ZN9prevectorILj16EhjiE12indirect_ptrEi
Unexecuted instantiation: _ZN9prevectorILj8EijiE12indirect_ptrEi
Unexecuted instantiation: _ZN9prevectorILj35EhjiE12indirect_ptrEi
125
0
    const T* indirect_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.indirect_contents.indirect) + pos; }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE12indirect_ptrEi
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE12indirect_ptrEi
Unexecuted instantiation: _ZNK9prevectorILj8EijiE12indirect_ptrEi
Unexecuted instantiation: _ZNK9prevectorILj33EhjiE12indirect_ptrEi
126
0
    bool is_direct() const { return _size <= N; }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE9is_directEv
Unexecuted instantiation: _ZNK9prevectorILj33EhjiE9is_directEv
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE9is_directEv
Unexecuted instantiation: _ZNK9prevectorILj8EijiE9is_directEv
Unexecuted instantiation: _ZNK9prevectorILj35EhjiE9is_directEv
127
128
0
    void change_capacity(size_type new_capacity) {
129
0
        if (new_capacity <= N) {
130
0
            if (!is_direct()) {
131
0
                T* indirect = indirect_ptr(0);
132
0
                T* src = indirect;
133
0
                T* dst = direct_ptr(0);
134
0
                memcpy(dst, src, size() * sizeof(T));
135
0
                free(indirect);
136
0
                _size -= N + 1;
137
0
            }
138
0
        } else {
139
0
            if (!is_direct()) {
140
                /* FIXME: Because malloc/realloc here won't call new_handler if allocation fails, assert
141
                    success. These should instead use an allocator or new/delete so that handlers
142
                    are called as necessary, but performance would be slightly degraded by doing so. */
143
0
                _union.indirect_contents.indirect = static_cast<char*>(realloc(_union.indirect_contents.indirect, ((size_t)sizeof(T)) * new_capacity));
144
0
                assert(_union.indirect_contents.indirect);
145
0
                _union.indirect_contents.capacity = new_capacity;
146
0
            } else {
147
0
                char* new_indirect = static_cast<char*>(malloc(((size_t)sizeof(T)) * new_capacity));
148
0
                assert(new_indirect);
149
0
                T* src = direct_ptr(0);
150
0
                T* dst = reinterpret_cast<T*>(new_indirect);
151
0
                memcpy(dst, src, size() * sizeof(T));
152
0
                _union.indirect_contents.indirect = new_indirect;
153
0
                _union.indirect_contents.capacity = new_capacity;
154
0
                _size += N + 1;
155
0
            }
156
0
        }
157
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE15change_capacityEj
Unexecuted instantiation: _ZN9prevectorILj16EhjiE15change_capacityEj
Unexecuted instantiation: _ZN9prevectorILj33EhjiE15change_capacityEj
Unexecuted instantiation: _ZN9prevectorILj8EijiE15change_capacityEj
Unexecuted instantiation: _ZN9prevectorILj35EhjiE15change_capacityEj
158
159
0
    T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE8item_ptrEi
Unexecuted instantiation: _ZN9prevectorILj33EhjiE8item_ptrEi
Unexecuted instantiation: _ZN9prevectorILj16EhjiE8item_ptrEi
Unexecuted instantiation: _ZN9prevectorILj8EijiE8item_ptrEi
Unexecuted instantiation: _ZN9prevectorILj35EhjiE8item_ptrEi
160
0
    const T* item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE8item_ptrEi
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE8item_ptrEi
Unexecuted instantiation: _ZNK9prevectorILj8EijiE8item_ptrEi
Unexecuted instantiation: _ZNK9prevectorILj33EhjiE8item_ptrEi
161
162
0
    void fill(T* dst, ptrdiff_t count, const T& value = T{}) {
163
0
        std::fill_n(dst, count, value);
164
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE4fillEPhlRKh
Unexecuted instantiation: _ZN9prevectorILj16EhjiE4fillEPhlRKh
Unexecuted instantiation: _ZN9prevectorILj33EhjiE4fillEPhlRKh
Unexecuted instantiation: _ZN9prevectorILj8EijiE4fillEPilRKi
165
166
    template <std::input_iterator InputIterator>
167
0
    void fill(T* dst, InputIterator first, InputIterator last) {
168
0
        while (first != last) {
169
0
            new(static_cast<void*>(dst)) T(*first);
170
0
            ++dst;
171
0
            ++first;
172
0
        }
173
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE4fillITkSt14input_iteratorPKhEEvPhT_S5_
Unexecuted instantiation: _ZN9prevectorILj36EhjiE4fillITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKhSt4spanIS4_Lm18446744073709551615EEEEEEvPhT_SA_
Unexecuted instantiation: _ZN9prevectorILj36EhjiE4fillITkSt14input_iteratorNS0_14const_iteratorEEEvPhT_S4_
Unexecuted instantiation: _ZN9prevectorILj16EhjiE4fillITkSt14input_iteratorNS0_14const_iteratorEEEvPhT_S4_
Unexecuted instantiation: _ZN9prevectorILj36EhjiE4fillITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKhSt6vectorIhSaIhEEEEEEvPhT_SB_
Unexecuted instantiation: _ZN9prevectorILj36EhjiE4fillITkSt14input_iteratorNS0_8iteratorEEEvPhT_S4_
Unexecuted instantiation: _ZN9prevectorILj8EijiE4fillITkSt14input_iteratorPiEEvS2_T_S3_
Unexecuted instantiation: _ZN9prevectorILj8EijiE4fillITkSt14input_iteratorNS0_14const_iteratorEEEvPiT_S4_
Unexecuted instantiation: _ZN9prevectorILj8EijiE4fillITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKiSt6vectorIiSaIiEEEEEEvPiT_SB_
Unexecuted instantiation: _ZN9prevectorILj33EhjiE4fillITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKhSt6vectorIhSaIhEEEEEEvPhT_SB_
Unexecuted instantiation: _ZN9prevectorILj36EhjiE4fillITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPhSt6vectorIhSaIhEEEEEEvS4_T_S9_
Unexecuted instantiation: _ZN9prevectorILj16EhjiE4fillITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKhSt4spanIS4_Lm18446744073709551615EEEEEEvPhT_SA_
Unexecuted instantiation: _ZN9prevectorILj16EhjiE4fillITkSt14input_iteratorPhEEvS2_T_S3_
Unexecuted instantiation: _ZN9prevectorILj16EhjiE4fillITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPhSt6vectorIhSaIhEEEEEEvS4_T_S9_
Unexecuted instantiation: _ZN9prevectorILj16EhjiE4fillITkSt14input_iteratorPKhEEvPhT_S5_
Unexecuted instantiation: _ZN9prevectorILj35EhjiE4fillITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKhSt4spanIS4_Lm18446744073709551615EEEEEEvPhT_SA_
Unexecuted instantiation: _ZN9prevectorILj35EhjiE4fillITkSt14input_iteratorPhEEvS2_T_S3_
Unexecuted instantiation: _ZN9prevectorILj35EhjiE4fillITkSt14input_iteratorPKhEEvPhT_S5_
174
175
public:
176
0
    void assign(size_type n, const T& val) {
177
0
        clear();
178
0
        if (capacity() < n) {
179
0
            change_capacity(n);
180
0
        }
181
0
        _size += n;
182
0
        fill(item_ptr(0), n, val);
183
0
    }
Unexecuted instantiation: _ZN9prevectorILj16EhjiE6assignEjRKh
Unexecuted instantiation: _ZN9prevectorILj8EijiE6assignEjRKi
184
185
    template <std::input_iterator InputIterator>
186
0
    void assign(InputIterator first, InputIterator last) {
187
0
        size_type n = last - first;
188
0
        clear();
189
0
        if (capacity() < n) {
190
0
            change_capacity(n);
191
0
        }
192
0
        _size += n;
193
0
        fill(item_ptr(0), first, last);
194
0
    }
Unexecuted instantiation: _ZN9prevectorILj16EhjiE6assignITkSt14input_iteratorNS0_14const_iteratorEEEvT_S3_
Unexecuted instantiation: _ZN9prevectorILj36EhjiE6assignITkSt14input_iteratorNS0_14const_iteratorEEEvT_S3_
Unexecuted instantiation: _ZN9prevectorILj8EijiE6assignITkSt14input_iteratorNS0_14const_iteratorEEEvT_S3_
Unexecuted instantiation: _ZN9prevectorILj33EhjiE6assignITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKhSt6vectorIhSaIhEEEEEEvT_SA_
Unexecuted instantiation: _ZN9prevectorILj16EhjiE6assignITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKhSt4spanIS4_Lm18446744073709551615EEEEEEvT_S9_
Unexecuted instantiation: _ZN9prevectorILj16EhjiE6assignITkSt14input_iteratorPhEEvT_S3_
Unexecuted instantiation: _ZN9prevectorILj16EhjiE6assignITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPhSt6vectorIhSaIhEEEEEEvT_S9_
Unexecuted instantiation: _ZN9prevectorILj16EhjiE6assignITkSt14input_iteratorPKhEEvT_S4_
195
196
0
    prevector() = default;
Unexecuted instantiation: _ZN9prevectorILj36EhjiEC2Ev
Unexecuted instantiation: _ZN9prevectorILj33EhjiEC2Ev
Unexecuted instantiation: _ZN9prevectorILj8EijiEC2Ev
197
198
    explicit prevector(size_type n) {
199
        resize(n);
200
    }
201
202
0
    explicit prevector(size_type n, const T& val) {
203
0
        change_capacity(n);
204
0
        _size += n;
205
0
        fill(item_ptr(0), n, val);
206
0
    }
Unexecuted instantiation: _ZN9prevectorILj33EhjiEC2EjRKh
Unexecuted instantiation: _ZN9prevectorILj16EhjiEC2EjRKh
207
208
    template <std::input_iterator InputIterator>
209
0
    prevector(InputIterator first, InputIterator last) {
210
0
        size_type n = last - first;
211
0
        change_capacity(n);
212
0
        _size += n;
213
0
        fill(item_ptr(0), first, last);
214
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiEC2ITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKhSt6vectorIhSaIhEEEEEET_SA_
Unexecuted instantiation: _ZN9prevectorILj8EijiEC2ITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKiSt6vectorIiSaIiEEEEEET_SA_
Unexecuted instantiation: _ZN9prevectorILj8EijiEC2ITkSt14input_iteratorNS0_14const_iteratorEEET_S3_
Unexecuted instantiation: _ZN9prevectorILj36EhjiEC2ITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPhSt6vectorIhSaIhEEEEEET_S9_
Unexecuted instantiation: _ZN9prevectorILj35EhjiEC2ITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKhSt4spanIS4_Lm18446744073709551615EEEEEET_S9_
Unexecuted instantiation: _ZN9prevectorILj36EhjiEC2ITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKhSt4spanIS4_Lm18446744073709551615EEEEEET_S9_
Unexecuted instantiation: _ZN9prevectorILj36EhjiEC2ITkSt14input_iteratorNS0_14const_iteratorEEET_S3_
215
216
0
    prevector(const prevector<N, T, Size, Diff>& other) {
217
0
        size_type n = other.size();
218
0
        change_capacity(n);
219
0
        _size += n;
220
0
        fill(item_ptr(0), other.begin(),  other.end());
221
0
    }
Unexecuted instantiation: _ZN9prevectorILj16EhjiEC2ERKS0_
Unexecuted instantiation: _ZN9prevectorILj36EhjiEC2ERKS0_
222
223
    prevector(prevector<N, T, Size, Diff>&& other) noexcept
224
0
        : _union(std::move(other._union)), _size(other._size)
225
0
    {
226
0
        other._size = 0;
227
0
    }
Unexecuted instantiation: _ZN9prevectorILj16EhjiEC2EOS0_
Unexecuted instantiation: _ZN9prevectorILj36EhjiEC2EOS0_
228
229
0
    prevector& operator=(const prevector<N, T, Size, Diff>& other) {
230
0
        if (&other == this) {
231
0
            return *this;
232
0
        }
233
0
        assign(other.begin(), other.end());
234
0
        return *this;
235
0
    }
Unexecuted instantiation: _ZN9prevectorILj16EhjiEaSERKS0_
Unexecuted instantiation: _ZN9prevectorILj36EhjiEaSERKS0_
Unexecuted instantiation: _ZN9prevectorILj8EijiEaSERKS0_
236
237
0
    prevector& operator=(prevector<N, T, Size, Diff>&& other) noexcept {
238
0
        if (!is_direct()) {
239
0
            free(_union.indirect_contents.indirect);
240
0
        }
241
0
        _union = std::move(other._union);
242
0
        _size = other._size;
243
0
        other._size = 0;
244
0
        return *this;
245
0
    }
Unexecuted instantiation: _ZN9prevectorILj16EhjiEaSEOS0_
Unexecuted instantiation: _ZN9prevectorILj36EhjiEaSEOS0_
Unexecuted instantiation: _ZN9prevectorILj8EijiEaSEOS0_
246
247
0
    size_type size() const {
248
0
        return is_direct() ? _size : _size - N - 1;
249
0
    }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE4sizeEv
Unexecuted instantiation: _ZNK9prevectorILj33EhjiE4sizeEv
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE4sizeEv
Unexecuted instantiation: _ZNK9prevectorILj8EijiE4sizeEv
Unexecuted instantiation: _ZNK9prevectorILj35EhjiE4sizeEv
250
251
0
    bool empty() const {
252
0
        return size() == 0;
253
0
    }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE5emptyEv
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE5emptyEv
Unexecuted instantiation: _ZNK9prevectorILj8EijiE5emptyEv
254
255
0
    iterator begin() { return iterator(item_ptr(0)); }
Unexecuted instantiation: _ZN9prevectorILj33EhjiE5beginEv
Unexecuted instantiation: _ZN9prevectorILj36EhjiE5beginEv
Unexecuted instantiation: _ZN9prevectorILj16EhjiE5beginEv
Unexecuted instantiation: _ZN9prevectorILj8EijiE5beginEv
Unexecuted instantiation: _ZN9prevectorILj35EhjiE5beginEv
256
0
    const_iterator begin() const { return const_iterator(item_ptr(0)); }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE5beginEv
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE5beginEv
Unexecuted instantiation: _ZNK9prevectorILj8EijiE5beginEv
257
0
    iterator end() { return iterator(item_ptr(size())); }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE3endEv
Unexecuted instantiation: _ZN9prevectorILj33EhjiE3endEv
Unexecuted instantiation: _ZN9prevectorILj16EhjiE3endEv
Unexecuted instantiation: _ZN9prevectorILj8EijiE3endEv
Unexecuted instantiation: _ZN9prevectorILj35EhjiE3endEv
258
0
    const_iterator end() const { return const_iterator(item_ptr(size())); }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE3endEv
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE3endEv
Unexecuted instantiation: _ZNK9prevectorILj8EijiE3endEv
259
260
0
    size_t capacity() const {
261
0
        if (is_direct()) {
262
0
            return N;
263
0
        } else {
264
0
            return _union.indirect_contents.capacity;
265
0
        }
266
0
    }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE8capacityEv
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE8capacityEv
Unexecuted instantiation: _ZNK9prevectorILj8EijiE8capacityEv
Unexecuted instantiation: _ZNK9prevectorILj33EhjiE8capacityEv
Unexecuted instantiation: _ZNK9prevectorILj35EhjiE8capacityEv
267
268
0
    T& operator[](size_type pos) {
269
0
        return *item_ptr(pos);
270
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiEixEj
Unexecuted instantiation: _ZN9prevectorILj8EijiEixEj
Unexecuted instantiation: _ZN9prevectorILj33EhjiEixEj
Unexecuted instantiation: _ZN9prevectorILj16EhjiEixEj
271
272
0
    const T& operator[](size_type pos) const {
273
0
        return *item_ptr(pos);
274
0
    }
Unexecuted instantiation: _ZNK9prevectorILj16EhjiEixEj
Unexecuted instantiation: _ZNK9prevectorILj36EhjiEixEj
Unexecuted instantiation: _ZNK9prevectorILj8EijiEixEj
275
276
0
    void resize(size_type new_size) {
277
0
        size_type cur_size = size();
278
0
        if (cur_size == new_size) {
279
0
            return;
280
0
        }
281
0
        if (cur_size > new_size) {
282
0
            erase(item_ptr(new_size), end());
283
0
            return;
284
0
        }
285
0
        if (new_size > capacity()) {
286
0
            change_capacity(new_size);
287
0
        }
288
0
        ptrdiff_t increase = new_size - cur_size;
289
0
        fill(item_ptr(cur_size), increase);
290
0
        _size += increase;
291
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE6resizeEj
Unexecuted instantiation: _ZN9prevectorILj16EhjiE6resizeEj
Unexecuted instantiation: _ZN9prevectorILj8EijiE6resizeEj
Unexecuted instantiation: _ZN9prevectorILj33EhjiE6resizeEj
292
293
0
    void reserve(size_type new_capacity) {
294
0
        if (new_capacity > capacity()) {
295
0
            change_capacity(new_capacity);
296
0
        }
297
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE7reserveEj
Unexecuted instantiation: _ZN9prevectorILj8EijiE7reserveEj
298
299
0
    void shrink_to_fit() {
300
0
        change_capacity(size());
301
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE13shrink_to_fitEv
Unexecuted instantiation: _ZN9prevectorILj8EijiE13shrink_to_fitEv
302
303
0
    void clear() {
304
0
        resize(0);
305
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE5clearEv
Unexecuted instantiation: _ZN9prevectorILj16EhjiE5clearEv
Unexecuted instantiation: _ZN9prevectorILj8EijiE5clearEv
Unexecuted instantiation: _ZN9prevectorILj33EhjiE5clearEv
306
307
0
    iterator insert(iterator pos, const T& value) {
308
0
        size_type p = pos - begin();
309
0
        size_type new_size = size() + 1;
310
0
        if (capacity() < new_size) {
311
0
            change_capacity(new_size + (new_size >> 1));
312
0
        }
313
0
        T* ptr = item_ptr(p);
314
0
        T* dst = ptr + 1;
315
0
        memmove(dst, ptr, (size() - p) * sizeof(T));
316
0
        _size++;
317
0
        new(static_cast<void*>(ptr)) T(value);
318
0
        return iterator(ptr);
319
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE6insertENS0_8iteratorERKh
Unexecuted instantiation: _ZN9prevectorILj8EijiE6insertENS0_8iteratorERKi
320
321
0
    void insert(iterator pos, size_type count, const T& value) {
322
0
        size_type p = pos - begin();
323
0
        size_type new_size = size() + count;
324
0
        if (capacity() < new_size) {
325
0
            change_capacity(new_size + (new_size >> 1));
326
0
        }
327
0
        T* ptr = item_ptr(p);
328
0
        T* dst = ptr + count;
329
0
        memmove(dst, ptr, (size() - p) * sizeof(T));
330
0
        _size += count;
331
0
        fill(item_ptr(p), count, value);
332
0
    }
Unexecuted instantiation: _ZN9prevectorILj8EijiE6insertENS0_8iteratorEjRKi
Unexecuted instantiation: _ZN9prevectorILj36EhjiE6insertENS0_8iteratorEjRKh
333
334
    template <std::input_iterator InputIterator>
335
0
    void insert(iterator pos, InputIterator first, InputIterator last) {
336
0
        size_type p = pos - begin();
337
0
        difference_type count = last - first;
338
0
        size_type new_size = size() + count;
339
0
        if (capacity() < new_size) {
340
0
            change_capacity(new_size + (new_size >> 1));
341
0
        }
342
0
        T* ptr = item_ptr(p);
343
0
        T* dst = ptr + count;
344
0
        memmove(dst, ptr, (size() - p) * sizeof(T));
345
0
        _size += count;
346
0
        fill(ptr, first, last);
347
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE6insertITkSt14input_iteratorPKhEEvNS0_8iteratorET_S5_
Unexecuted instantiation: _ZN9prevectorILj36EhjiE6insertITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPKhSt4spanIS4_Lm18446744073709551615EEEEEEvNS0_8iteratorET_SA_
Unexecuted instantiation: _ZN9prevectorILj36EhjiE6insertITkSt14input_iteratorNS0_8iteratorEEEvS2_T_S3_
Unexecuted instantiation: _ZN9prevectorILj8EijiE6insertITkSt14input_iteratorPiEEvNS0_8iteratorET_S4_
Unexecuted instantiation: _ZN9prevectorILj36EhjiE6insertITkSt14input_iteratorN9__gnu_cxx17__normal_iteratorIPhSt6vectorIhSaIhEEEEEEvNS0_8iteratorET_SA_
Unexecuted instantiation: _ZN9prevectorILj35EhjiE6insertITkSt14input_iteratorPhEEvNS0_8iteratorET_S4_
Unexecuted instantiation: _ZN9prevectorILj35EhjiE6insertITkSt14input_iteratorPKhEEvNS0_8iteratorET_S5_
Unexecuted instantiation: _ZN9prevectorILj36EhjiE6insertITkSt14input_iteratorNS0_14const_iteratorEEEvNS0_8iteratorET_S4_
348
349
0
    inline void resize_uninitialized(size_type new_size) {
350
        // resize_uninitialized changes the size of the prevector but does not initialize it.
351
        // If size < new_size, the added elements must be initialized explicitly.
352
0
        if (capacity() < new_size) {
353
0
            change_capacity(new_size);
354
0
            _size += new_size - size();
355
0
            return;
356
0
        }
357
0
        if (new_size < size()) {
358
0
            erase(item_ptr(new_size), end());
359
0
        } else {
360
0
            _size += new_size - size();
361
0
        }
362
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE20resize_uninitializedEj
Unexecuted instantiation: _ZN9prevectorILj8EijiE20resize_uninitializedEj
363
364
0
    iterator erase(iterator pos) {
365
0
        return erase(pos, pos + 1);
366
0
    }
Unexecuted instantiation: _ZN9prevectorILj8EijiE5eraseENS0_8iteratorE
Unexecuted instantiation: _ZN9prevectorILj33EhjiE5eraseENS0_8iteratorE
367
368
0
    iterator erase(iterator first, iterator last) {
369
        // Erase is not allowed to the change the object's capacity. That means
370
        // that when starting with an indirectly allocated prevector with
371
        // size and capacity > N, the result may be a still indirectly allocated
372
        // prevector with size <= N and capacity > N. A shrink_to_fit() call is
373
        // necessary to switch to the (more efficient) directly allocated
374
        // representation (with capacity N and size <= N).
375
0
        iterator p = first;
376
0
        char* endp = (char*)&(*end());
377
0
        _size -= last - p;
378
0
        memmove(&(*first), &(*last), endp - ((char*)(&(*last))));
379
0
        return first;
380
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE5eraseENS0_8iteratorES1_
Unexecuted instantiation: _ZN9prevectorILj16EhjiE5eraseENS0_8iteratorES1_
Unexecuted instantiation: _ZN9prevectorILj8EijiE5eraseENS0_8iteratorES1_
Unexecuted instantiation: _ZN9prevectorILj33EhjiE5eraseENS0_8iteratorES1_
381
382
    template<typename... Args>
383
0
    void emplace_back(Args&&... args) {
384
0
        size_type new_size = size() + 1;
385
0
        if (capacity() < new_size) {
386
0
            change_capacity(new_size + (new_size >> 1));
387
0
        }
388
0
        new(item_ptr(size())) T(std::forward<Args>(args)...);
389
0
        _size++;
390
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE12emplace_backIJRKhEEEvDpOT_
Unexecuted instantiation: _ZN9prevectorILj8EijiE12emplace_backIJRKiEEEvDpOT_
391
392
0
    void push_back(const T& value) {
393
0
        emplace_back(value);
394
0
    }
Unexecuted instantiation: _ZN9prevectorILj36EhjiE9push_backERKh
Unexecuted instantiation: _ZN9prevectorILj8EijiE9push_backERKi
395
396
0
    void pop_back() {
397
0
        erase(end() - 1, end());
398
0
    }
399
400
    T& front() {
401
        return *item_ptr(0);
402
    }
403
404
    const T& front() const {
405
        return *item_ptr(0);
406
    }
407
408
0
    T& back() {
409
0
        return *item_ptr(size() - 1);
410
0
    }
411
412
0
    const T& back() const {
413
0
        return *item_ptr(size() - 1);
414
0
    }
415
416
    void swap(prevector<N, T, Size, Diff>& other) noexcept
417
0
    {
418
0
        std::swap(_union, other._union);
419
0
        std::swap(_size, other._size);
420
0
    }
421
422
0
    ~prevector() {
423
0
        if (!is_direct()) {
424
0
            free(_union.indirect_contents.indirect);
425
0
            _union.indirect_contents.indirect = nullptr;
426
0
        }
427
0
    }
Unexecuted instantiation: _ZN9prevectorILj16EhjiED2Ev
Unexecuted instantiation: _ZN9prevectorILj36EhjiED2Ev
Unexecuted instantiation: _ZN9prevectorILj33EhjiED2Ev
Unexecuted instantiation: _ZN9prevectorILj8EijiED2Ev
Unexecuted instantiation: _ZN9prevectorILj35EhjiED2Ev
428
429
0
    bool operator==(const prevector<N, T, Size, Diff>& other) const {
430
0
        if (other.size() != size()) {
431
0
            return false;
432
0
        }
433
0
        const_iterator b1 = begin();
434
0
        const_iterator b2 = other.begin();
435
0
        const_iterator e1 = end();
436
0
        while (b1 != e1) {
437
0
            if ((*b1) != (*b2)) {
438
0
                return false;
439
0
            }
440
0
            ++b1;
441
0
            ++b2;
442
0
        }
443
0
        return true;
444
0
    }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiEeqERKS0_
Unexecuted instantiation: _ZNK9prevectorILj8EijiEeqERKS0_
Unexecuted instantiation: _ZNK9prevectorILj16EhjiEeqERKS0_
445
446
0
    bool operator<(const prevector<N, T, Size, Diff>& other) const {
447
0
        if (size() < other.size()) {
448
0
            return true;
449
0
        }
450
0
        if (size() > other.size()) {
451
0
            return false;
452
0
        }
453
0
        const_iterator b1 = begin();
454
0
        const_iterator b2 = other.begin();
455
0
        const_iterator e1 = end();
456
0
        while (b1 != e1) {
457
0
            if ((*b1) < (*b2)) {
458
0
                return true;
459
0
            }
460
0
            if ((*b2) < (*b1)) {
461
0
                return false;
462
0
            }
463
0
            ++b1;
464
0
            ++b2;
465
0
        }
466
0
        return false;
467
0
    }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiEltERKS0_
Unexecuted instantiation: _ZNK9prevectorILj16EhjiEltERKS0_
468
469
0
    size_t allocated_memory() const {
470
0
        if (is_direct()) {
471
0
            return 0;
472
0
        } else {
473
0
            return ((size_t)(sizeof(T))) * _union.indirect_contents.capacity;
474
0
        }
475
0
    }
476
477
0
    value_type* data() {
478
0
        return item_ptr(0);
479
0
    }
Unexecuted instantiation: _ZN9prevectorILj33EhjiE4dataEv
Unexecuted instantiation: _ZN9prevectorILj36EhjiE4dataEv
Unexecuted instantiation: _ZN9prevectorILj16EhjiE4dataEv
Unexecuted instantiation: _ZN9prevectorILj35EhjiE4dataEv
480
481
0
    const value_type* data() const {
482
0
        return item_ptr(0);
483
0
    }
Unexecuted instantiation: _ZNK9prevectorILj36EhjiE4dataEv
Unexecuted instantiation: _ZNK9prevectorILj16EhjiE4dataEv
Unexecuted instantiation: _ZNK9prevectorILj33EhjiE4dataEv
484
};
485
486
#endif // BITCOIN_PREVECTOR_H