Bitcoin Core  24.99.0
P2P Digital Currency
prevector.h
Go to the documentation of this file.
1 // Copyright (c) 2015-2020 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 <assert.h>
9 #include <cstdlib>
10 #include <stdint.h>
11 #include <string.h>
12 
13 #include <algorithm>
14 #include <cstddef>
15 #include <type_traits>
16 #include <utility>
17 
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  typedef Size size_type;
42  typedef Diff difference_type;
43  typedef T value_type;
45  typedef const value_type& const_reference;
46  typedef value_type* pointer;
47  typedef const value_type* const_pointer;
48 
49  class iterator {
50  T* ptr;
51  public:
52  typedef Diff difference_type;
53  typedef T value_type;
54  typedef T* pointer;
55  typedef T& reference;
56  typedef std::random_access_iterator_tag iterator_category;
57  iterator(T* ptr_) : ptr(ptr_) {}
58  T& operator*() const { return *ptr; }
59  T* operator->() const { return ptr; }
60  T& operator[](size_type pos) { return ptr[pos]; }
61  const T& operator[](size_type pos) const { return ptr[pos]; }
62  iterator& operator++() { ptr++; return *this; }
63  iterator& operator--() { ptr--; return *this; }
64  iterator operator++(int) { iterator copy(*this); ++(*this); return copy; }
65  iterator operator--(int) { iterator copy(*this); --(*this); return copy; }
66  difference_type friend operator-(iterator a, iterator b) { return (&(*a) - &(*b)); }
67  iterator operator+(size_type n) { return iterator(ptr + n); }
68  iterator& operator+=(size_type n) { ptr += n; return *this; }
69  iterator operator-(size_type n) { return iterator(ptr - n); }
70  iterator& operator-=(size_type n) { ptr -= n; return *this; }
71  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  bool operator<(iterator x) const { return ptr < x.ptr; }
77  };
78 
80  T* ptr;
81  public:
82  typedef Diff difference_type;
83  typedef T value_type;
84  typedef T* pointer;
85  typedef T& reference;
86  typedef std::bidirectional_iterator_tag iterator_category;
87  reverse_iterator(T* ptr_) : ptr(ptr_) {}
88  T& operator*() { return *ptr; }
89  const T& operator*() const { return *ptr; }
90  T* operator->() { return ptr; }
91  const T* operator->() const { return ptr; }
92  reverse_iterator& operator--() { ptr++; return *this; }
93  reverse_iterator& operator++() { ptr--; return *this; }
94  reverse_iterator operator++(int) { reverse_iterator copy(*this); ++(*this); return copy; }
95  reverse_iterator operator--(int) { reverse_iterator copy(*this); --(*this); return copy; }
96  bool operator==(reverse_iterator x) const { return ptr == x.ptr; }
97  bool operator!=(reverse_iterator x) const { return ptr != x.ptr; }
98  };
99 
101  const T* ptr;
102  public:
103  typedef Diff difference_type;
104  typedef const T value_type;
105  typedef const T* pointer;
106  typedef const T& reference;
107  typedef std::random_access_iterator_tag iterator_category;
108  const_iterator(const T* ptr_) : ptr(ptr_) {}
109  const_iterator(iterator x) : ptr(&(*x)) {}
110  const T& operator*() const { return *ptr; }
111  const T* operator->() const { return ptr; }
112  const T& operator[](size_type pos) const { return ptr[pos]; }
113  const_iterator& operator++() { ptr++; return *this; }
114  const_iterator& operator--() { ptr--; return *this; }
115  const_iterator operator++(int) { const_iterator copy(*this); ++(*this); return copy; }
116  const_iterator operator--(int) { const_iterator copy(*this); --(*this); return copy; }
117  difference_type friend operator-(const_iterator a, const_iterator b) { return (&(*a) - &(*b)); }
119  const_iterator& operator+=(size_type n) { ptr += n; return *this; }
121  const_iterator& operator-=(size_type n) { ptr -= n; return *this; }
122  bool operator==(const_iterator x) const { return ptr == x.ptr; }
123  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  bool operator>(const_iterator x) const { return ptr > x.ptr; }
127  bool operator<(const_iterator x) const { return ptr < x.ptr; }
128  };
129 
131  const T* ptr;
132  public:
133  typedef Diff difference_type;
134  typedef const T value_type;
135  typedef const T* pointer;
136  typedef const T& reference;
137  typedef std::bidirectional_iterator_tag iterator_category;
138  const_reverse_iterator(const T* ptr_) : ptr(ptr_) {}
140  const T& operator*() const { return *ptr; }
141  const T* operator->() const { return ptr; }
142  const_reverse_iterator& operator--() { ptr++; return *this; }
143  const_reverse_iterator& operator++() { ptr--; return *this; }
144  const_reverse_iterator operator++(int) { const_reverse_iterator copy(*this); ++(*this); return copy; }
145  const_reverse_iterator operator--(int) { const_reverse_iterator copy(*this); --(*this); return copy; }
146  bool operator==(const_reverse_iterator x) const { return ptr == x.ptr; }
147  bool operator!=(const_reverse_iterator x) const { return ptr != x.ptr; }
148  };
149 
150 private:
151 #pragma pack(push, 1)
153  char direct[sizeof(T) * N];
154  struct {
155  char* indirect;
158  };
159 #pragma pack(pop)
160  alignas(char*) direct_or_indirect _union = {};
162 
163  static_assert(alignof(char*) % alignof(size_type) == 0 && sizeof(char*) % alignof(size_type) == 0, "size_type cannot have more restrictive alignment requirement than pointer");
164  static_assert(alignof(char*) % alignof(T) == 0, "value_type T cannot have more restrictive alignment requirement than pointer");
165 
166  T* direct_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.direct) + pos; }
167  const T* direct_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.direct) + pos; }
168  T* indirect_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.indirect_contents.indirect) + pos; }
169  const T* indirect_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.indirect_contents.indirect) + pos; }
170  bool is_direct() const { return _size <= N; }
171 
172  void change_capacity(size_type new_capacity) {
173  if (new_capacity <= N) {
174  if (!is_direct()) {
175  T* indirect = indirect_ptr(0);
176  T* src = indirect;
177  T* dst = direct_ptr(0);
178  memcpy(dst, src, size() * sizeof(T));
179  free(indirect);
180  _size -= N + 1;
181  }
182  } else {
183  if (!is_direct()) {
184  /* FIXME: Because malloc/realloc here won't call new_handler if allocation fails, assert
185  success. These should instead use an allocator or new/delete so that handlers
186  are called as necessary, but performance would be slightly degraded by doing so. */
187  _union.indirect_contents.indirect = static_cast<char*>(realloc(_union.indirect_contents.indirect, ((size_t)sizeof(T)) * new_capacity));
189  _union.indirect_contents.capacity = new_capacity;
190  } else {
191  char* new_indirect = static_cast<char*>(malloc(((size_t)sizeof(T)) * new_capacity));
192  assert(new_indirect);
193  T* src = direct_ptr(0);
194  T* dst = reinterpret_cast<T*>(new_indirect);
195  memcpy(dst, src, size() * sizeof(T));
196  _union.indirect_contents.indirect = new_indirect;
197  _union.indirect_contents.capacity = new_capacity;
198  _size += N + 1;
199  }
200  }
201  }
202 
203  T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
204  const T* item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
205 
206  void fill(T* dst, ptrdiff_t count, const T& value = T{}) {
207  std::fill_n(dst, count, value);
208  }
209 
210  template<typename InputIterator>
211  void fill(T* dst, InputIterator first, InputIterator last) {
212  while (first != last) {
213  new(static_cast<void*>(dst)) T(*first);
214  ++dst;
215  ++first;
216  }
217  }
218 
219 public:
220  void assign(size_type n, const T& val) {
221  clear();
222  if (capacity() < n) {
223  change_capacity(n);
224  }
225  _size += n;
226  fill(item_ptr(0), n, val);
227  }
228 
229  template<typename InputIterator>
230  void assign(InputIterator first, InputIterator last) {
231  size_type n = last - first;
232  clear();
233  if (capacity() < n) {
234  change_capacity(n);
235  }
236  _size += n;
237  fill(item_ptr(0), first, last);
238  }
239 
241 
242  explicit prevector(size_type n) {
243  resize(n);
244  }
245 
246  explicit prevector(size_type n, const T& val) {
247  change_capacity(n);
248  _size += n;
249  fill(item_ptr(0), n, val);
250  }
251 
252  template<typename InputIterator>
253  prevector(InputIterator first, InputIterator last) {
254  size_type n = last - first;
255  change_capacity(n);
256  _size += n;
257  fill(item_ptr(0), first, last);
258  }
259 
261  size_type n = other.size();
262  change_capacity(n);
263  _size += n;
264  fill(item_ptr(0), other.begin(), other.end());
265  }
266 
268  swap(other);
269  }
270 
272  if (&other == this) {
273  return *this;
274  }
275  assign(other.begin(), other.end());
276  return *this;
277  }
278 
280  swap(other);
281  return *this;
282  }
283 
284  size_type size() const {
285  return is_direct() ? _size : _size - N - 1;
286  }
287 
288  bool empty() const {
289  return size() == 0;
290  }
291 
292  iterator begin() { return iterator(item_ptr(0)); }
293  const_iterator begin() const { return const_iterator(item_ptr(0)); }
294  iterator end() { return iterator(item_ptr(size())); }
296 
301 
302  size_t capacity() const {
303  if (is_direct()) {
304  return N;
305  } else {
307  }
308  }
309 
311  return *item_ptr(pos);
312  }
313 
314  const T& operator[](size_type pos) const {
315  return *item_ptr(pos);
316  }
317 
318  void resize(size_type new_size) {
319  size_type cur_size = size();
320  if (cur_size == new_size) {
321  return;
322  }
323  if (cur_size > new_size) {
324  erase(item_ptr(new_size), end());
325  return;
326  }
327  if (new_size > capacity()) {
328  change_capacity(new_size);
329  }
330  ptrdiff_t increase = new_size - cur_size;
331  fill(item_ptr(cur_size), increase);
332  _size += increase;
333  }
334 
335  void reserve(size_type new_capacity) {
336  if (new_capacity > capacity()) {
337  change_capacity(new_capacity);
338  }
339  }
340 
341  void shrink_to_fit() {
343  }
344 
345  void clear() {
346  resize(0);
347  }
348 
349  iterator insert(iterator pos, const T& value) {
350  size_type p = pos - begin();
351  size_type new_size = size() + 1;
352  if (capacity() < new_size) {
353  change_capacity(new_size + (new_size >> 1));
354  }
355  T* ptr = item_ptr(p);
356  memmove(ptr + 1, ptr, (size() - p) * sizeof(T));
357  _size++;
358  new(static_cast<void*>(ptr)) T(value);
359  return iterator(ptr);
360  }
361 
362  void insert(iterator pos, size_type count, const T& value) {
363  size_type p = pos - begin();
364  size_type new_size = size() + count;
365  if (capacity() < new_size) {
366  change_capacity(new_size + (new_size >> 1));
367  }
368  T* ptr = item_ptr(p);
369  memmove(ptr + count, ptr, (size() - p) * sizeof(T));
370  _size += count;
371  fill(item_ptr(p), count, value);
372  }
373 
374  template<typename InputIterator>
375  void insert(iterator pos, InputIterator first, InputIterator last) {
376  size_type p = pos - begin();
377  difference_type count = last - first;
378  size_type new_size = size() + count;
379  if (capacity() < new_size) {
380  change_capacity(new_size + (new_size >> 1));
381  }
382  T* ptr = item_ptr(p);
383  memmove(ptr + count, ptr, (size() - p) * sizeof(T));
384  _size += count;
385  fill(ptr, first, last);
386  }
387 
388  inline void resize_uninitialized(size_type new_size) {
389  // resize_uninitialized changes the size of the prevector but does not initialize it.
390  // If size < new_size, the added elements must be initialized explicitly.
391  if (capacity() < new_size) {
392  change_capacity(new_size);
393  _size += new_size - size();
394  return;
395  }
396  if (new_size < size()) {
397  erase(item_ptr(new_size), end());
398  } else {
399  _size += new_size - size();
400  }
401  }
402 
404  return erase(pos, pos + 1);
405  }
406 
408  // Erase is not allowed to the change the object's capacity. That means
409  // that when starting with an indirectly allocated prevector with
410  // size and capacity > N, the result may be a still indirectly allocated
411  // prevector with size <= N and capacity > N. A shrink_to_fit() call is
412  // necessary to switch to the (more efficient) directly allocated
413  // representation (with capacity N and size <= N).
414  iterator p = first;
415  char* endp = (char*)&(*end());
416  _size -= last - p;
417  memmove(&(*first), &(*last), endp - ((char*)(&(*last))));
418  return first;
419  }
420 
421  template<typename... Args>
422  void emplace_back(Args&&... args) {
423  size_type new_size = size() + 1;
424  if (capacity() < new_size) {
425  change_capacity(new_size + (new_size >> 1));
426  }
427  new(item_ptr(size())) T(std::forward<Args>(args)...);
428  _size++;
429  }
430 
431  void push_back(const T& value) {
432  emplace_back(value);
433  }
434 
435  void pop_back() {
436  erase(end() - 1, end());
437  }
438 
439  T& front() {
440  return *item_ptr(0);
441  }
442 
443  const T& front() const {
444  return *item_ptr(0);
445  }
446 
447  T& back() {
448  return *item_ptr(size() - 1);
449  }
450 
451  const T& back() const {
452  return *item_ptr(size() - 1);
453  }
454 
455  void swap(prevector<N, T, Size, Diff>& other) noexcept
456  {
457  std::swap(_union, other._union);
458  std::swap(_size, other._size);
459  }
460 
462  if (!is_direct()) {
465  }
466  }
467 
468  bool operator==(const prevector<N, T, Size, Diff>& other) const {
469  if (other.size() != size()) {
470  return false;
471  }
472  const_iterator b1 = begin();
473  const_iterator b2 = other.begin();
474  const_iterator e1 = end();
475  while (b1 != e1) {
476  if ((*b1) != (*b2)) {
477  return false;
478  }
479  ++b1;
480  ++b2;
481  }
482  return true;
483  }
484 
485  bool operator!=(const prevector<N, T, Size, Diff>& other) const {
486  return !(*this == other);
487  }
488 
489  bool operator<(const prevector<N, T, Size, Diff>& other) const {
490  if (size() < other.size()) {
491  return true;
492  }
493  if (size() > other.size()) {
494  return false;
495  }
496  const_iterator b1 = begin();
497  const_iterator b2 = other.begin();
498  const_iterator e1 = end();
499  while (b1 != e1) {
500  if ((*b1) < (*b2)) {
501  return true;
502  }
503  if ((*b2) < (*b1)) {
504  return false;
505  }
506  ++b1;
507  ++b2;
508  }
509  return false;
510  }
511 
512  size_t allocated_memory() const {
513  if (is_direct()) {
514  return 0;
515  } else {
516  return ((size_t)(sizeof(T))) * _union.indirect_contents.capacity;
517  }
518  }
519 
521  return item_ptr(0);
522  }
523 
524  const value_type* data() const {
525  return item_ptr(0);
526  }
527 };
528 
529 #endif // BITCOIN_PREVECTOR_H
bool operator==(const_iterator x) const
Definition: prevector.h:122
bool operator<(const_iterator x) const
Definition: prevector.h:127
std::random_access_iterator_tag iterator_category
Definition: prevector.h:107
const_iterator operator--(int)
Definition: prevector.h:116
bool operator<=(const_iterator x) const
Definition: prevector.h:125
const_iterator & operator++()
Definition: prevector.h:113
const_iterator operator++(int)
Definition: prevector.h:115
const_iterator & operator--()
Definition: prevector.h:114
const_iterator(const T *ptr_)
Definition: prevector.h:108
difference_type friend operator-(const_iterator a, const_iterator b)
Definition: prevector.h:117
bool operator!=(const_iterator x) const
Definition: prevector.h:123
const_iterator operator+(size_type n)
Definition: prevector.h:118
const_iterator & operator-=(size_type n)
Definition: prevector.h:121
bool operator>=(const_iterator x) const
Definition: prevector.h:124
const_iterator operator-(size_type n)
Definition: prevector.h:120
const T & operator*() const
Definition: prevector.h:110
const T & operator[](size_type pos) const
Definition: prevector.h:112
const_iterator & operator+=(size_type n)
Definition: prevector.h:119
const T * operator->() const
Definition: prevector.h:111
bool operator>(const_iterator x) const
Definition: prevector.h:126
const_iterator(iterator x)
Definition: prevector.h:109
const_reverse_iterator & operator++()
Definition: prevector.h:143
const_reverse_iterator(const T *ptr_)
Definition: prevector.h:138
const_reverse_iterator & operator--()
Definition: prevector.h:142
const T * operator->() const
Definition: prevector.h:141
const_reverse_iterator operator--(int)
Definition: prevector.h:145
const_reverse_iterator operator++(int)
Definition: prevector.h:144
std::bidirectional_iterator_tag iterator_category
Definition: prevector.h:137
const_reverse_iterator(reverse_iterator x)
Definition: prevector.h:139
bool operator!=(const_reverse_iterator x) const
Definition: prevector.h:147
bool operator==(const_reverse_iterator x) const
Definition: prevector.h:146
bool operator<(iterator x) const
Definition: prevector.h:76
const T & operator[](size_type pos) const
Definition: prevector.h:61
bool operator==(iterator x) const
Definition: prevector.h:71
T * operator->() const
Definition: prevector.h:59
difference_type friend operator-(iterator a, iterator b)
Definition: prevector.h:66
bool operator!=(iterator x) const
Definition: prevector.h:72
iterator operator-(size_type n)
Definition: prevector.h:69
iterator operator--(int)
Definition: prevector.h:65
iterator & operator--()
Definition: prevector.h:63
bool operator<=(iterator x) const
Definition: prevector.h:74
iterator & operator++()
Definition: prevector.h:62
T & operator*() const
Definition: prevector.h:58
bool operator>=(iterator x) const
Definition: prevector.h:73
iterator & operator-=(size_type n)
Definition: prevector.h:70
iterator & operator+=(size_type n)
Definition: prevector.h:68
iterator operator++(int)
Definition: prevector.h:64
bool operator>(iterator x) const
Definition: prevector.h:75
std::random_access_iterator_tag iterator_category
Definition: prevector.h:56
T & operator[](size_type pos)
Definition: prevector.h:60
iterator operator+(size_type n)
Definition: prevector.h:67
iterator(T *ptr_)
Definition: prevector.h:57
std::bidirectional_iterator_tag iterator_category
Definition: prevector.h:86
reverse_iterator operator++(int)
Definition: prevector.h:94
const T * operator->() const
Definition: prevector.h:91
reverse_iterator & operator++()
Definition: prevector.h:93
const T & operator*() const
Definition: prevector.h:89
bool operator!=(reverse_iterator x) const
Definition: prevector.h:97
reverse_iterator & operator--()
Definition: prevector.h:92
bool operator==(reverse_iterator x) const
Definition: prevector.h:96
reverse_iterator operator--(int)
Definition: prevector.h:95
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
Definition: prevector.h:37
bool empty() const
Definition: prevector.h:288
T & operator[](size_type pos)
Definition: prevector.h:310
prevector(prevector< N, T, Size, Diff > &&other)
Definition: prevector.h:267
prevector(size_type n)
Definition: prevector.h:242
void change_capacity(size_type new_capacity)
Definition: prevector.h:172
void fill(T *dst, ptrdiff_t count, const T &value=T{})
Definition: prevector.h:206
void pop_back()
Definition: prevector.h:435
iterator erase(iterator first, iterator last)
Definition: prevector.h:407
prevector(InputIterator first, InputIterator last)
Definition: prevector.h:253
T * direct_ptr(difference_type pos)
Definition: prevector.h:166
const T & operator[](size_type pos) const
Definition: prevector.h:314
void swap(prevector< N, T, Size, Diff > &other) noexcept
Definition: prevector.h:455
prevector & operator=(const prevector< N, T, Size, Diff > &other)
Definition: prevector.h:271
Diff difference_type
Definition: prevector.h:42
const value_type & const_reference
Definition: prevector.h:45
size_type _size
Definition: prevector.h:161
void shrink_to_fit()
Definition: prevector.h:341
void clear()
Definition: prevector.h:345
value_type & reference
Definition: prevector.h:44
const T * indirect_ptr(difference_type pos) const
Definition: prevector.h:169
~prevector()
Definition: prevector.h:461
const T * item_ptr(difference_type pos) const
Definition: prevector.h:204
T * item_ptr(difference_type pos)
Definition: prevector.h:203
const T & back() const
Definition: prevector.h:451
size_type size() const
Definition: prevector.h:284
reverse_iterator rend()
Definition: prevector.h:299
const T * direct_ptr(difference_type pos) const
Definition: prevector.h:167
const T & front() const
Definition: prevector.h:443
bool operator==(const prevector< N, T, Size, Diff > &other) const
Definition: prevector.h:468
iterator erase(iterator pos)
Definition: prevector.h:403
prevector(size_type n, const T &val)
Definition: prevector.h:246
void fill(T *dst, InputIterator first, InputIterator last)
Definition: prevector.h:211
Size size_type
Definition: prevector.h:38
size_t capacity() const
Definition: prevector.h:302
const_iterator end() const
Definition: prevector.h:295
direct_or_indirect _union
Definition: prevector.h:160
void assign(InputIterator first, InputIterator last)
Definition: prevector.h:230
void emplace_back(Args &&... args)
Definition: prevector.h:422
bool is_direct() const
Definition: prevector.h:170
value_type * data()
Definition: prevector.h:520
T & back()
Definition: prevector.h:447
void insert(iterator pos, InputIterator first, InputIterator last)
Definition: prevector.h:375
bool operator<(const prevector< N, T, Size, Diff > &other) const
Definition: prevector.h:489
iterator begin()
Definition: prevector.h:292
T value_type
Definition: prevector.h:43
iterator end()
Definition: prevector.h:294
const value_type * data() const
Definition: prevector.h:524
bool operator!=(const prevector< N, T, Size, Diff > &other) const
Definition: prevector.h:485
void reserve(size_type new_capacity)
Definition: prevector.h:335
prevector(const prevector< N, T, Size, Diff > &other)
Definition: prevector.h:260
void resize_uninitialized(size_type new_size)
Definition: prevector.h:388
const_reverse_iterator rbegin() const
Definition: prevector.h:298
T & front()
Definition: prevector.h:439
void resize(size_type new_size)
Definition: prevector.h:318
size_t allocated_memory() const
Definition: prevector.h:512
iterator insert(iterator pos, const T &value)
Definition: prevector.h:349
value_type * pointer
Definition: prevector.h:46
reverse_iterator rbegin()
Definition: prevector.h:297
const_reverse_iterator rend() const
Definition: prevector.h:300
const value_type * const_pointer
Definition: prevector.h:47
T * indirect_ptr(difference_type pos)
Definition: prevector.h:168
void assign(size_type n, const T &val)
Definition: prevector.h:220
prevector & operator=(prevector< N, T, Size, Diff > &&other)
Definition: prevector.h:279
void insert(iterator pos, size_type count, const T &value)
Definition: prevector.h:362
void push_back(const T &value)
Definition: prevector.h:431
const_iterator begin() const
Definition: prevector.h:293
ArgsManager args
static int count
Definition: tests.c:33
struct prevector::direct_or_indirect::@2 indirect_contents
char direct[sizeof(T) *N]
Definition: prevector.h:153
assert(!tx.IsCoinBase())