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