LCOV - code coverage report
Current view: top level - src - prevector.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 231 232 99.6 %
Date: 2026-10-19 02:26:17 Functions: 52 55 94.5 %

          Line data    Source code
       1             : // Copyright (c) 2015 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 PIVX_PREVECTOR_H
       6             : #define PIVX_PREVECTOR_H
       7             : 
       8             : #include <assert.h>
       9             : #include <stdlib.h>
      10             : #include <stdint.h>
      11             : #include <string.h>
      12             : 
      13             : #include <algorithm>
      14             : #include <cstddef>
      15             : #include <iterator>
      16             : #include <type_traits>
      17             : 
      18             : #pragma pack(push, 1)
      19             : /** Implements a drop-in replacement for std::vector<T> which stores up to N
      20             :  *  elements directly (without heap allocation). The types Size and Diff are
      21             :  *  used to store element counts, and can be any unsigned + signed type.
      22             :  *
      23             :  *  Storage layout is either:
      24             :  *  - Direct allocation:
      25             :  *    - Size _size: the number of used elements (between 0 and N)
      26             :  *    - T direct[N]: an array of N elements of type T
      27             :  *      (only the first _size are initialized).
      28             :  *  - Indirect allocation:
      29             :  *    - Size _size: the number of used elements plus N + 1
      30             :  *    - Size capacity: the number of allocated elements
      31             :  *    - T* indirect: a pointer to an array of capacity elements of type T
      32             :  *      (only the first _size are initialized).
      33             :  *
      34             :  *  The data type T must be movable by memmove/realloc(). Once we switch to C++,
      35             :  *  move constructors can be used instead.
      36             :  */
      37             : template<unsigned int N, typename T, typename Size = uint32_t, typename Diff = int32_t>
      38             : class prevector {
      39             : public:
      40             :     typedef Size size_type;
      41             :     typedef Diff difference_type;
      42             :     typedef T value_type;
      43             :     typedef value_type& reference;
      44             :     typedef const value_type& const_reference;
      45             :     typedef value_type* pointer;
      46             :     typedef const value_type* const_pointer;
      47             : 
      48             :     class iterator {
      49             :         T* ptr;
      50             :     public:
      51             :         typedef Diff difference_type;
      52             :         typedef T value_type;
      53             :         typedef T* pointer;
      54             :         typedef T& reference;
      55             :         typedef std::random_access_iterator_tag iterator_category;
      56   218518320 :         iterator(T* ptr_) : ptr(ptr_) {}
      57     5183212 :         T& operator*() const { return *ptr; }
      58             :         T* operator->() const { return ptr; }
      59     2794300 :         T& operator[](size_type pos) { return ptr[pos]; }
      60             :         const T& operator[](size_type pos) const { return ptr[pos]; }
      61   143718816 :         iterator& operator++() { ptr++; return *this; }
      62             :         iterator& operator--() { ptr--; return *this; }
      63             :         iterator operator++(int) { iterator copy(*this); ++(*this); return copy; }
      64             :         iterator operator--(int) { iterator copy(*this); --(*this); return copy; }
      65    92690659 :         difference_type friend operator-(iterator a, iterator b) { return (&(*a) - &(*b)); }
      66    34357133 :         iterator operator+(size_type n) { return iterator(ptr + n); }
      67             :         iterator& operator+=(size_type n) { ptr += n; return *this; }
      68     2794300 :         iterator operator-(size_type n) { return iterator(ptr - n); }
      69             :         iterator& operator-=(size_type n) { ptr -= n; return *this; }
      70             :         bool operator==(iterator x) const { return ptr == x.ptr; }
      71   179295804 :         bool operator!=(iterator x) const { return ptr != x.ptr; }
      72             :         bool operator>=(iterator x) const { return ptr >= x.ptr; }
      73             :         bool operator<=(iterator x) const { return ptr <= x.ptr; }
      74             :         bool operator>(iterator x) const { return ptr > x.ptr; }
      75             :         bool operator<(iterator x) const { return ptr < x.ptr; }
      76             :     };
      77             : 
      78             :     class reverse_iterator {
      79             :         T* ptr;
      80             :     public:
      81             :         typedef Diff difference_type;
      82             :         typedef T value_type;
      83             :         typedef T* pointer;
      84             :         typedef T& reference;
      85             :         typedef std::bidirectional_iterator_tag iterator_category;
      86             :         reverse_iterator(T* ptr_) : ptr(ptr_) {}
      87             :         T& operator*() { return *ptr; }
      88             :         const T& operator*() const { return *ptr; }
      89             :         T* operator->() { return ptr; }
      90             :         const T* operator->() const { return ptr; }
      91             :         reverse_iterator& operator--() { ptr++; return *this; }
      92             :         reverse_iterator& operator++() { ptr--; return *this; }
      93             :         reverse_iterator operator++(int) { reverse_iterator copy(*this); ++(*this); return copy; }
      94             :         reverse_iterator operator--(int) { reverse_iterator copy(*this); --(*this); return copy; }
      95             :         bool operator==(reverse_iterator x) const { return ptr == x.ptr; }
      96             :         bool operator!=(reverse_iterator x) const { return ptr != x.ptr; }
      97             :     };
      98             : 
      99             :     class const_iterator {
     100             :         const T* ptr;
     101             :     public:
     102             :         typedef Diff difference_type;
     103             :         typedef const T value_type;
     104             :         typedef const T* pointer;
     105             :         typedef const T& reference;
     106             :         typedef std::random_access_iterator_tag iterator_category;
     107   548234979 :         const_iterator(const T* ptr_) : ptr(ptr_) {}
     108    34286504 :         const_iterator(iterator x) : ptr(&(*x)) {}
     109  2539633986 :         const T& operator*() const { return *ptr; }
     110             :         const T* operator->() const { return ptr; }
     111     1928183 :         const T& operator[](size_type pos) const { return ptr[pos]; }
     112  2792588311 :         const_iterator& operator++() { ptr++; return *this; }
     113           0 :         const_iterator& operator--() { ptr--; return *this; }
     114   108580062 :         const_iterator operator++(int) { const_iterator copy(*this); ++(*this); return copy; }
     115             :         const_iterator operator--(int) { const_iterator copy(*this); --(*this); return copy; }
     116   104148770 :         difference_type friend operator-(const_iterator a, const_iterator b) { return (&(*a) - &(*b)); }
     117    17342597 :         const_iterator operator+(size_type n) { return const_iterator(ptr + n); }
     118    39858648 :         const_iterator& operator+=(size_type n) { ptr += n; return *this; }
     119         438 :         const_iterator operator-(size_type n) { return const_iterator(ptr - n); }
     120             :         const_iterator& operator-=(size_type n) { ptr -= n; return *this; }
     121        8591 :         bool operator==(const_iterator x) const { return ptr == x.ptr; }
     122  2126323259 :         bool operator!=(const_iterator x) const { return ptr != x.ptr; }
     123   117947381 :         bool operator>=(const_iterator x) const { return ptr >= x.ptr; }
     124             :         bool operator<=(const_iterator x) const { return ptr <= x.ptr; }
     125             :         bool operator>(const_iterator x) const { return ptr > x.ptr; }
     126    77882383 :         bool operator<(const_iterator x) const { return ptr < x.ptr; }
     127             :     };
     128             : 
     129             :     class const_reverse_iterator {
     130             :         const T* ptr;
     131             :     public:
     132             :         typedef Diff difference_type;
     133             :         typedef const T value_type;
     134             :         typedef const T* pointer;
     135             :         typedef const T& reference;
     136             :         typedef std::bidirectional_iterator_tag iterator_category;
     137             :         const_reverse_iterator(const T* ptr_) : ptr(ptr_) {}
     138             :         const_reverse_iterator(reverse_iterator x) : ptr(&(*x)) {}
     139             :         const T& operator*() const { return *ptr; }
     140             :         const T* operator->() const { return ptr; }
     141             :         const_reverse_iterator& operator--() { ptr++; return *this; }
     142             :         const_reverse_iterator& operator++() { ptr--; return *this; }
     143             :         const_reverse_iterator operator++(int) { const_reverse_iterator copy(*this); ++(*this); return copy; }
     144             :         const_reverse_iterator operator--(int) { const_reverse_iterator copy(*this); --(*this); return copy; }
     145             :         bool operator==(const_reverse_iterator x) const { return ptr == x.ptr; }
     146             :         bool operator!=(const_reverse_iterator x) const { return ptr != x.ptr; }
     147             :     };
     148             : 
     149             : private:
     150             :     size_type _size = 0;
     151             :     union direct_or_indirect {
     152             :         char direct[sizeof(T) * N];
     153             :         struct {
     154             :             size_type capacity;
     155             :             char* indirect;
     156             :         };
     157             :     } _union = {};
     158             : 
     159   519869086 :     T* direct_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.direct) + pos; }
     160   446111746 :     const T* direct_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.direct) + pos; }
     161   719469933 :     T* indirect_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.indirect) + pos; }
     162   112973217 :     const T* indirect_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.indirect) + pos; }
     163  3471345722 :     bool is_direct() const { return _size <= N; }
     164             : 
     165   143843667 :     void change_capacity(size_type new_capacity) {
     166   143843667 :         if (new_capacity <= N) {
     167   122134130 :             if (!is_direct()) {
     168       18605 :                 T* indirect = indirect_ptr(0);
     169       18605 :                 T* src = indirect;
     170       18605 :                 T* dst = direct_ptr(0);
     171       18605 :                 memcpy(dst, src, size() * sizeof(T));
     172       18605 :                 free(indirect);
     173       18605 :                 _size -= N + 1;
     174             :             }
     175             :         } else {
     176    21709590 :             if (!is_direct()) {
     177             :                 /* FIXME: Because malloc/realloc here won't call new_handler if allocation fails, assert
     178             :                     success. These should instead use an allocator or new/delete so that handlers
     179             :                     are called as necessary, but performance would be slightly degraded by doing so. */
     180       14077 :                 _union.indirect = static_cast<char*>(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity));
     181       14077 :                 assert(_union.indirect);
     182       14077 :                 _union.capacity = new_capacity;
     183             :             } else {
     184    21695515 :                 char* new_indirect = static_cast<char*>(malloc(((size_t)sizeof(T)) * new_capacity));
     185    21695515 :                 assert(new_indirect);
     186    21695515 :                 T* src = direct_ptr(0);
     187    21695515 :                 T* dst = reinterpret_cast<T*>(new_indirect);
     188    21695515 :                 memcpy(dst, src, size() * sizeof(T));
     189    21695515 :                 _union.indirect = new_indirect;
     190    21695515 :                 _union.capacity = new_capacity;
     191    21695515 :                 _size += N + 1;
     192             :             }
     193             :         }
     194   143843667 :     }
     195             : 
     196  1211969272 :     T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
     197   571811564 :     const T* item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
     198             : 
     199     7764758 :     void fill(T* dst, ptrdiff_t count, const T& value = T{}) {
     200     7768342 :         std::fill_n(dst, count, value);
     201             :     }
     202             : 
     203             :     template<typename InputIterator>
     204    74344528 :     void fill(T* dst, InputIterator first, InputIterator last) {
     205  2269846124 :         while (first != last) {
     206  2192519328 :             new(static_cast<void*>(dst)) T(*first);
     207  2190127179 :             ++dst;
     208  2266867233 :             ++first;
     209             :         }
     210             :     }
     211             : 
     212             : public:
     213       24039 :     void assign(size_type n, const T& val) {
     214       24039 :         clear();
     215       24039 :         if (capacity() < n) {
     216       13129 :             change_capacity(n);
     217             :         }
     218       24039 :         _size += n;
     219       48078 :         fill(item_ptr(0), n, val);
     220       24039 :     }
     221             : 
     222             :     template<typename InputIterator>
     223     7666864 :     void assign(InputIterator first, InputIterator last) {
     224     7666864 :         size_type n = last - first;
     225     7666864 :         clear();
     226     7666864 :         if (capacity() < n) {
     227      336860 :             change_capacity(n);
     228             :         }
     229     7666864 :         _size += n;
     230    10058894 :         fill(item_ptr(0), first, last);
     231     7666864 :     }
     232             : 
     233    91511994 :     prevector() {}
     234             : 
     235             :     explicit prevector(size_type n) {
     236             :         resize(n);
     237             :     }
     238             : 
     239     3830646 :     explicit prevector(size_type n, const T& val = T()) {
     240     3830646 :         change_capacity(n);
     241     3830646 :         _size += n;
     242     7661302 :         fill(item_ptr(0), n, val);
     243     3830646 :     }
     244             : 
     245             :     template<typename InputIterator>
     246     6195500 :     prevector(InputIterator first, InputIterator last) {
     247     6195500 :         size_type n = last - first;
     248     6195500 :         change_capacity(n);
     249     6195500 :         _size += n;
     250     6195615 :         fill(item_ptr(0), first, last);
     251     6195500 :     }
     252             : 
     253    61068993 :     prevector(const prevector<N, T, Size, Diff>& other) {
     254    61068993 :         size_type n = other.size();
     255    61068993 :         change_capacity(n);
     256    61068993 :         _size += n;
     257    61068993 :         fill(item_ptr(0), other.begin(),  other.end());
     258    61068993 :     }
     259             : 
     260     2553800 :     prevector(prevector<N, T, Size, Diff>&& other) {
     261     2553800 :         swap(other);
     262             :     }
     263             : 
     264     7092924 :     prevector& operator=(const prevector<N, T, Size, Diff>& other) {
     265     7092924 :         if (&other == this) {
     266             :             return *this;
     267             :         }
     268    14160166 :         assign(other.begin(), other.end());
     269     7080078 :         return *this;
     270             :     }
     271             : 
     272    20798418 :     prevector& operator=(prevector<N, T, Size, Diff>&& other) {
     273    20798418 :         swap(other);
     274             :         return *this;
     275             :     }
     276             : 
     277  1315880013 :     size_type size() const {
     278   555815367 :         return is_direct() ? _size : _size - N - 1;
     279             :     }
     280             : 
     281   145715752 :     bool empty() const {
     282   145715752 :         return size() == 0;
     283             :     }
     284             : 
     285    56141572 :     iterator begin() { return iterator(item_ptr(0)); }
     286   163515230 :     const_iterator begin() const { return const_iterator(item_ptr(0)); }
     287   166029134 :     iterator end() { return iterator(item_ptr(size())); }
     288   582805363 :     const_iterator end() const { return const_iterator(item_ptr(size())); }
     289             : 
     290             :     reverse_iterator rbegin() { return reverse_iterator(item_ptr(size() - 1)); }
     291             :     const_reverse_iterator rbegin() const { return const_reverse_iterator(item_ptr(size() - 1)); }
     292             :     reverse_iterator rend() { return reverse_iterator(item_ptr(-1)); }
     293             :     const_reverse_iterator rend() const { return const_reverse_iterator(item_ptr(-1)); }
     294             : 
     295    73453478 :     size_t capacity() const {
     296    12092052 :         if (is_direct()) {
     297             :             return N;
     298             :         } else {
     299     5777880 :             return _union.capacity;
     300             :         }
     301             :     }
     302             : 
     303    26567155 :     T& operator[](size_type pos) {
     304    44559226 :         return *item_ptr(pos);
     305             :     }
     306             : 
     307   106596753 :     const T& operator[](size_type pos) const {
     308   167988680 :         return *item_ptr(pos);
     309             :     }
     310             : 
     311    79124075 :     void resize(size_type new_size) {
     312    79124075 :         size_type cur_size = size();
     313    79124075 :         if (cur_size == new_size) {
     314             :             return;
     315             :         }
     316     5349919 :         if (cur_size > new_size) {
     317     2889936 :             erase(item_ptr(new_size), end());
     318     1444966 :             return;
     319             :         }
     320     3908217 :         if (new_size > capacity()) {
     321         762 :             change_capacity(new_size);
     322             :         }
     323     3904953 :         ptrdiff_t increase = new_size - cur_size;
     324     7815228 :         fill(item_ptr(cur_size), increase);
     325     3904953 :         _size += increase;
     326             :     }
     327             : 
     328       15182 :     void reserve(size_type new_capacity) {
     329       17109 :         if (new_capacity > capacity()) {
     330         257 :             change_capacity(new_capacity);
     331             :         }
     332             :     }
     333             : 
     334    62872345 :     void shrink_to_fit() {
     335    62872345 :         change_capacity(size());
     336             :     }
     337             : 
     338    75208294 :     void clear() {
     339    75208294 :         resize(0);
     340             :     }
     341             : 
     342    12581495 :     iterator insert(iterator pos, const T& value) {
     343    12581495 :         size_type p = pos - begin();
     344    12581495 :         size_type new_size = size() + 1;
     345    12581495 :         if (capacity() < new_size) {
     346        1160 :             change_capacity(new_size + (new_size >> 1));
     347             :         }
     348    25162990 :         T* ptr = item_ptr(p);
     349    12581495 :         memmove(ptr + 1, ptr, (size() - p) * sizeof(T));
     350    12581495 :         _size++;
     351    12581495 :         new(static_cast<void*>(ptr)) T(value);
     352    12581495 :         return iterator(ptr);
     353             :     }
     354             : 
     355        8704 :     void insert(iterator pos, size_type count, const T& value) {
     356        8704 :         size_type p = pos - begin();
     357        8704 :         size_type new_size = size() + count;
     358        8704 :         if (capacity() < new_size) {
     359         448 :             change_capacity(new_size + (new_size >> 1));
     360             :         }
     361       17408 :         T* ptr = item_ptr(p);
     362        8704 :         memmove(ptr + count, ptr, (size() - p) * sizeof(T));
     363        8704 :         _size += count;
     364       17408 :         fill(item_ptr(p), count, value);
     365        8704 :     }
     366             : 
     367             :     template<typename InputIterator>
     368    44916618 :     void insert(iterator pos, InputIterator first, InputIterator last) {
     369    44916618 :         size_type p = pos - begin();
     370    44916618 :         difference_type count = last - first;
     371    44916618 :         size_type new_size = size() + count;
     372    44916618 :         if (capacity() < new_size) {
     373     8110352 :             change_capacity(new_size + (new_size >> 1));
     374             :         }
     375   134750156 :         memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T));
     376    44916618 :         _size += count;
     377   840906318 :         while (first != last) {
     378  1591976788 :             new(static_cast<void*>(item_ptr(p))) T(*first);
     379   795989899 :             ++p;
     380   840903986 :             ++first;
     381             :         }
     382    44916618 :     }
     383             : 
     384     4319745 :     inline void resize_uninitialized(size_type new_size) {
     385             :         // resize_uninitialized changes the size of the prevector but does not initialize it.
     386             :         // If size < new_size, the added elements must be initialized explicitly.
     387     4319745 :         if (capacity() < new_size) {
     388     1413076 :             change_capacity(new_size);
     389     1413076 :             _size += new_size - size();
     390     1413076 :             return;
     391             :         }
     392     2906667 :         if (new_size < size()) {
     393        6912 :             erase(item_ptr(new_size), end());
     394             :         } else {
     395     2903211 :             _size += new_size - size();
     396             :         }
     397             :     }
     398             : 
     399       15040 :     iterator erase(iterator pos) {
     400       15040 :         return erase(pos, pos + 1);
     401             :     }
     402             : 
     403     1478246 :     iterator erase(iterator first, iterator last) {
     404             :         // Erase is not allowed to the change the object's capacity. That means
     405             :         // that when starting with an indirectly allocated prevector with
     406             :         // size and capacity > N, the result may be a still indirectly allocated
     407             :         // prevector with size <= N and capacity > N. A shrink_to_fit() call is
     408             :         // necessary to switch to the (more efficient) directly allocated
     409             :         // representation (with capacity N and size <= N).
     410     1478246 :         iterator p = first;
     411     1478246 :         char* endp = (char*)&(*end());
     412             :         if (!std::is_trivially_destructible<T>::value) {
     413             :             while (p != last) {
     414             :                 (*p).~T();
     415             :                 _size--;
     416             :                 ++p;
     417             :             }
     418             :         } else {
     419     1478246 :             _size -= last - p;
     420             :         }
     421     1478246 :         memmove(&(*first), &(*last), endp - ((char*)(&(*last))));
     422     1478246 :         return first;
     423             :     }
     424             : 
     425             :     template<typename... Args>
     426       13760 :     void emplace_back(Args&&... args) {
     427       13760 :         size_type new_size = size() + 1;
     428       13760 :         if (capacity() < new_size) {
     429         227 :             change_capacity(new_size + (new_size >> 1));
     430             :         }
     431       19531 :         new(item_ptr(size())) T(std::forward<Args>(args)...);
     432       13760 :         _size++;
     433       13760 :     }
     434             : 
     435       13760 :     void push_back(const T& value) {
     436       13760 :         emplace_back(value);
     437             :     }
     438             : 
     439        3968 :     void pop_back() {
     440        3968 :         erase(end() - 1, end());
     441        3968 :     }
     442             : 
     443             :     T& front() {
     444             :         return *item_ptr(0);
     445             :     }
     446             : 
     447             :     const T& front() const {
     448             :         return *item_ptr(0);
     449             :     }
     450             : 
     451             :     T& back() {
     452             :         return *item_ptr(size() - 1);
     453             :     }
     454             : 
     455       57679 :     const T& back() const {
     456      115358 :         return *item_ptr(size() - 1);
     457             :     }
     458             : 
     459    21378302 :     void swap(prevector<N, T, Size, Diff>& other) {
     460    21377992 :         std::swap(_union, other._union);
     461    17817374 :         std::swap(_size, other._size);
     462             :     }
     463             : 
     464   171165309 :     ~prevector() {
     465             :         if (!std::is_trivially_destructible<T>::value) {
     466             :             clear();
     467             :         }
     468   170864844 :         if (!is_direct()) {
     469    21676445 :             free(_union.indirect);
     470             :             _union.indirect = nullptr;
     471             :         }
     472         128 :     }
     473             : 
     474     1270111 :     bool operator==(const prevector<N, T, Size, Diff>& other) const {
     475     1617864 :         if (other.size() != size()) {
     476             :             return false;
     477             :         }
     478     1265068 :         const_iterator b1 = begin();
     479     1265068 :         const_iterator b2 = other.begin();
     480     1265068 :         const_iterator e1 = end();
     481    20097711 :         while (b1 != e1) {
     482    18836624 :             if ((*b1) != (*b2)) {
     483             :                 return false;
     484             :             }
     485    18832649 :             ++b1;
     486    20097711 :             ++b2;
     487             :         }
     488             :         return true;
     489             :     }
     490             : 
     491       36418 :     bool operator!=(const prevector<N, T, Size, Diff>& other) const {
     492       36418 :         return !(*this == other);
     493             :     }
     494             : 
     495     1331822 :     bool operator<(const prevector<N, T, Size, Diff>& other) const {
     496     1538103 :         if (size() < other.size()) {
     497             :             return true;
     498             :         }
     499     1315408 :         if (size() > other.size()) {
     500             :             return false;
     501             :         }
     502     1275117 :         const_iterator b1 = begin();
     503     1275117 :         const_iterator b2 = other.begin();
     504     1275117 :         const_iterator e1 = end();
     505     4201933 :         while (b1 != e1) {
     506     3821799 :             if ((*b1) < (*b2)) {
     507             :                 return true;
     508             :             }
     509     3146400 :             if ((*b2) < (*b1)) {
     510             :                 return false;
     511             :             }
     512     2926818 :             ++b1;
     513     4201933 :             ++b2;
     514             :         }
     515             :         return false;
     516             :     }
     517             : 
     518    20095430 :     size_t allocated_memory() const {
     519    20095430 :         if (is_direct()) {
     520             :             return 0;
     521             :         } else {
     522      743440 :             return ((size_t)(sizeof(T))) * _union.capacity;
     523             :         }
     524             :     }
     525             : 
     526       13592 :     value_type* data() {
     527       13591 :         return item_ptr(0);
     528             :     }
     529             : 
     530    84170175 :     const value_type* data() const {
     531    84227654 :         return item_ptr(0);
     532             :     }
     533             : };
     534             : #pragma pack(pop)
     535             : 
     536             : #endif // PIVX_PREVECTOR_H

Generated by: LCOV version 1.14