Bitcoin Core  26.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 <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  : _union(std::move(other._union)), _size(other._size)
269  {
270  other._size = 0;
271  }
272 
274  if (&other == this) {
275  return *this;
276  }
277  assign(other.begin(), other.end());
278  return *this;
279  }
280 
282  if (!is_direct()) {
284  }
285  _union = std::move(other._union);
286  _size = other._size;
287  other._size = 0;
288  return *this;
289  }
290 
291  size_type size() const {
292  return is_direct() ? _size : _size - N - 1;
293  }
294 
295  bool empty() const {
296  return size() == 0;
297  }
298 
299  iterator begin() { return iterator(item_ptr(0)); }
300  const_iterator begin() const { return const_iterator(item_ptr(0)); }
301  iterator end() { return iterator(item_ptr(size())); }
302  const_iterator end() const { return const_iterator(item_ptr(size())); }
303 
304  reverse_iterator rbegin() { return reverse_iterator(item_ptr(size() - 1)); }
305  const_reverse_iterator rbegin() const { return const_reverse_iterator(item_ptr(size() - 1)); }
306  reverse_iterator rend() { return reverse_iterator(item_ptr(-1)); }
307  const_reverse_iterator rend() const { return const_reverse_iterator(item_ptr(-1)); }
308 
309  size_t capacity() const {
310  if (is_direct()) {
311  return N;
312  } else {
314  }
315  }
316 
318  return *item_ptr(pos);
319  }
320 
321  const T& operator[](size_type pos) const {
322  return *item_ptr(pos);
323  }
324 
325  void resize(size_type new_size) {
326  size_type cur_size = size();
327  if (cur_size == new_size) {
328  return;
329  }
330  if (cur_size > new_size) {
331  erase(item_ptr(new_size), end());
332  return;
333  }
334  if (new_size > capacity()) {
335  change_capacity(new_size);
336  }
337  ptrdiff_t increase = new_size - cur_size;
338  fill(item_ptr(cur_size), increase);
339  _size += increase;
340  }
341 
342  void reserve(size_type new_capacity) {
343  if (new_capacity > capacity()) {
344  change_capacity(new_capacity);
345  }
346  }
347 
348  void shrink_to_fit() {
350  }
351 
352  void clear() {
353  resize(0);
354  }
355 
356  iterator insert(iterator pos, const T& value) {
357  size_type p = pos - begin();
358  size_type new_size = size() + 1;
359  if (capacity() < new_size) {
360  change_capacity(new_size + (new_size >> 1));
361  }
362  T* ptr = item_ptr(p);
363  memmove(ptr + 1, ptr, (size() - p) * sizeof(T));
364  _size++;
365  new(static_cast<void*>(ptr)) T(value);
366  return iterator(ptr);
367  }
368 
369  void insert(iterator pos, size_type count, const T& value) {
370  size_type p = pos - begin();
371  size_type new_size = size() + count;
372  if (capacity() < new_size) {
373  change_capacity(new_size + (new_size >> 1));
374  }
375  T* ptr = item_ptr(p);
376  memmove(ptr + count, ptr, (size() - p) * sizeof(T));
377  _size += count;
378  fill(item_ptr(p), count, value);
379  }
380 
381  template<typename InputIterator>
382  void insert(iterator pos, InputIterator first, InputIterator last) {
383  size_type p = pos - begin();
384  difference_type count = last - first;
385  size_type new_size = size() + count;
386  if (capacity() < new_size) {
387  change_capacity(new_size + (new_size >> 1));
388  }
389  T* ptr = item_ptr(p);
390  memmove(ptr + count, ptr, (size() - p) * sizeof(T));
391  _size += count;
392  fill(ptr, first, last);
393  }
394 
395  inline void resize_uninitialized(size_type new_size) {
396  // resize_uninitialized changes the size of the prevector but does not initialize it.
397  // If size < new_size, the added elements must be initialized explicitly.
398  if (capacity() < new_size) {
399  change_capacity(new_size);
400  _size += new_size - size();
401  return;
402  }
403  if (new_size < size()) {
404  erase(item_ptr(new_size), end());
405  } else {
406  _size += new_size - size();
407  }
408  }
409 
410  iterator erase(iterator pos) {
411  return erase(pos, pos + 1);
412  }
413 
414  iterator erase(iterator first, iterator last) {
415  // Erase is not allowed to the change the object's capacity. That means
416  // that when starting with an indirectly allocated prevector with
417  // size and capacity > N, the result may be a still indirectly allocated
418  // prevector with size <= N and capacity > N. A shrink_to_fit() call is
419  // necessary to switch to the (more efficient) directly allocated
420  // representation (with capacity N and size <= N).
421  iterator p = first;
422  char* endp = (char*)&(*end());
423  _size -= last - p;
424  memmove(&(*first), &(*last), endp - ((char*)(&(*last))));
425  return first;
426  }
427 
428  template<typename... Args>
429  void emplace_back(Args&&... args) {
430  size_type new_size = size() + 1;
431  if (capacity() < new_size) {
432  change_capacity(new_size + (new_size >> 1));
433  }
434  new(item_ptr(size())) T(std::forward<Args>(args)...);
435  _size++;
436  }
437 
438  void push_back(const T& value) {
439  emplace_back(value);
440  }
441 
442  void pop_back() {
443  erase(end() - 1, end());
444  }
445 
446  T& front() {
447  return *item_ptr(0);
448  }
449 
450  const T& front() const {
451  return *item_ptr(0);
452  }
453 
454  T& back() {
455  return *item_ptr(size() - 1);
456  }
457 
458  const T& back() const {
459  return *item_ptr(size() - 1);
460  }
461 
462  void swap(prevector<N, T, Size, Diff>& other) noexcept
463  {
464  std::swap(_union, other._union);
465  std::swap(_size, other._size);
466  }
467 
469  if (!is_direct()) {
472  }
473  }
474 
475  bool operator==(const prevector<N, T, Size, Diff>& other) const {
476  if (other.size() != size()) {
477  return false;
478  }
479  const_iterator b1 = begin();
480  const_iterator b2 = other.begin();
481  const_iterator e1 = end();
482  while (b1 != e1) {
483  if ((*b1) != (*b2)) {
484  return false;
485  }
486  ++b1;
487  ++b2;
488  }
489  return true;
490  }
491 
492  bool operator!=(const prevector<N, T, Size, Diff>& other) const {
493  return !(*this == other);
494  }
495 
496  bool operator<(const prevector<N, T, Size, Diff>& other) const {
497  if (size() < other.size()) {
498  return true;
499  }
500  if (size() > other.size()) {
501  return false;
502  }
503  const_iterator b1 = begin();
504  const_iterator b2 = other.begin();
505  const_iterator e1 = end();
506  while (b1 != e1) {
507  if ((*b1) < (*b2)) {
508  return true;
509  }
510  if ((*b2) < (*b1)) {
511  return false;
512  }
513  ++b1;
514  ++b2;
515  }
516  return false;
517  }
518 
519  size_t allocated_memory() const {
520  if (is_direct()) {
521  return 0;
522  } else {
523  return ((size_t)(sizeof(T))) * _union.indirect_contents.capacity;
524  }
525  }
526 
528  return item_ptr(0);
529  }
530 
531  const value_type* data() const {
532  return item_ptr(0);
533  }
534 };
535 
536 #endif // BITCOIN_PREVECTOR_H
bool operator!=(const prevector< N, T, Size, Diff > &other) const
Definition: prevector.h:492
T * direct_ptr(difference_type pos)
Definition: prevector.h:166
struct prevector::direct_or_indirect::@2 indirect_contents
std::bidirectional_iterator_tag iterator_category
Definition: prevector.h:86
prevector & operator=(const prevector< N, T, Size, Diff > &other)
Definition: prevector.h:273
const value_type & const_reference
Definition: prevector.h:45
const_iterator operator--(int)
Definition: prevector.h:116
void resize(size_type new_size)
Definition: prevector.h:325
const T * operator->() const
Definition: prevector.h:91
const T & operator[](size_type pos) const
Definition: prevector.h:61
const value_type * const_pointer
Definition: prevector.h:47
void assign(size_type n, const T &val)
Definition: prevector.h:220
T * indirect_ptr(difference_type pos)
Definition: prevector.h:168
iterator operator+(size_type n)
Definition: prevector.h:67
bool operator<=(const_iterator x) const
Definition: prevector.h:125
prevector & operator=(prevector< N, T, Size, Diff > &&other) noexcept
Definition: prevector.h:281
iterator operator-(size_type n)
Definition: prevector.h:69
T & back()
Definition: prevector.h:454
assert(!tx.IsCoinBase())
void assign(InputIterator first, InputIterator last)
Definition: prevector.h:230
void shrink_to_fit()
Definition: prevector.h:348
void pop_back()
Definition: prevector.h:442
T * operator->() const
Definition: prevector.h:59
reverse_iterator operator++(int)
Definition: prevector.h:94
iterator insert(iterator pos, const T &value)
Definition: prevector.h:356
void clear()
Definition: prevector.h:352
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:112
bool operator!=(iterator x) const
Definition: prevector.h:72
const_iterator & operator-=(size_type n)
Definition: prevector.h:121
const_reverse_iterator & operator--()
Definition: prevector.h:142
const_iterator & operator++()
Definition: prevector.h:113
iterator operator++(int)
Definition: prevector.h:64
void insert(iterator pos, InputIterator first, InputIterator last)
Definition: prevector.h:382
const_reverse_iterator operator--(int)
Definition: prevector.h:145
void fill(T *dst, InputIterator first, InputIterator last)
Definition: prevector.h:211
const T & back() const
Definition: prevector.h:458
const T * operator->() const
Definition: prevector.h:141
iterator operator--(int)
Definition: prevector.h:65
const value_type * data() const
Definition: prevector.h:531
const T * direct_ptr(difference_type pos) const
Definition: prevector.h:167
size_t allocated_memory() const
Definition: prevector.h:519
prevector(prevector< N, T, Size, Diff > &&other) noexcept
Definition: prevector.h:267
void swap(prevector< N, T, Size, Diff > &other) noexcept
Definition: prevector.h:462
bool operator==(const prevector< N, T, Size, Diff > &other) const
Definition: prevector.h:475
void resize_uninitialized(size_type new_size)
Definition: prevector.h:395
size_t capacity() const
Definition: prevector.h:309
const_reverse_iterator & operator++()
Definition: prevector.h:143
bool is_direct() const
Definition: prevector.h:170
~prevector()
Definition: prevector.h:468
iterator(T *ptr_)
Definition: prevector.h:57
T & operator[](size_type pos)
Definition: prevector.h:60
bool operator==(const_reverse_iterator x) const
Definition: prevector.h:146
bool operator>=(iterator x) const
Definition: prevector.h:73
value_type * data()
Definition: prevector.h:527
prevector(const prevector< N, T, Size, Diff > &other)
Definition: prevector.h:260
direct_or_indirect _union
Definition: prevector.h:160
const_reverse_iterator operator++(int)
Definition: prevector.h:144
bool operator>=(const_iterator x) const
Definition: prevector.h:124
void fill(T *dst, ptrdiff_t count, const T &value=T{})
Definition: prevector.h:206
T value_type
Definition: prevector.h:43
const T * item_ptr(difference_type pos) const
Definition: prevector.h:204
iterator end()
Definition: prevector.h:301
Diff difference_type
Definition: prevector.h:42
void push_back(const T &value)
Definition: prevector.h:438
T & front()
Definition: prevector.h:446
value_type * pointer
Definition: prevector.h:46
ArgsManager & args
Definition: bitcoind.cpp:269
const T & operator*() const
Definition: prevector.h:110
const_reverse_iterator rend() const
Definition: prevector.h:307
const_reverse_iterator rbegin() const
Definition: prevector.h:305
T & operator[](size_type pos)
Definition: prevector.h:317
bool operator<=(iterator x) const
Definition: prevector.h:74
void insert(iterator pos, size_type count, const T &value)
Definition: prevector.h:369
const_iterator operator+(size_type n)
Definition: prevector.h:118
prevector(size_type n)
Definition: prevector.h:242
reverse_iterator rend()
Definition: prevector.h:306
const_reverse_iterator(reverse_iterator x)
Definition: prevector.h:139
bool operator>(const_iterator x) const
Definition: prevector.h:126
bool operator==(iterator x) const
Definition: prevector.h:71
reverse_iterator rbegin()
Definition: prevector.h:304
char direct[sizeof(T) *N]
Definition: prevector.h:153
iterator & operator+=(size_type n)
Definition: prevector.h:68
iterator erase(iterator pos)
Definition: prevector.h:410
bool operator<(iterator x) const
Definition: prevector.h:76
const_reverse_iterator(const T *ptr_)
Definition: prevector.h:138
const T & operator[](size_type pos) const
Definition: prevector.h:321
const_iterator(iterator x)
Definition: prevector.h:109
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:58
bool operator!=(const_reverse_iterator x) const
Definition: prevector.h:147
const_iterator & operator--()
Definition: prevector.h:114
bool operator==(reverse_iterator x) const
Definition: prevector.h:96
const_iterator operator-(size_type n)
Definition: prevector.h:120
void reserve(size_type new_capacity)
Definition: prevector.h:342
const T * operator->() const
Definition: prevector.h:111
void change_capacity(size_type new_capacity)
Definition: prevector.h:172
const T & front() const
Definition: prevector.h:450
prevector(InputIterator first, InputIterator last)
Definition: prevector.h:253
T * item_ptr(difference_type pos)
Definition: prevector.h:203
bool empty() const
Definition: prevector.h:295
bool operator>(iterator x) const
Definition: prevector.h:75
reverse_iterator & operator--()
Definition: prevector.h:92
std::random_access_iterator_tag iterator_category
Definition: prevector.h:56
const T & operator*() const
Definition: prevector.h:89
std::bidirectional_iterator_tag iterator_category
Definition: prevector.h:137
const_iterator operator++(int)
Definition: prevector.h:115
static int count
iterator begin()
Definition: prevector.h:299
std::random_access_iterator_tag iterator_category
Definition: prevector.h:107
size_type size() const
Definition: prevector.h:291
iterator erase(iterator first, iterator last)
Definition: prevector.h:414
bool operator!=(const_iterator x) const
Definition: prevector.h:123
iterator & operator++()
Definition: prevector.h:62
size_type _size
Definition: prevector.h:161
difference_type friend operator-(iterator a, iterator b)
Definition: prevector.h:66
const T * indirect_ptr(difference_type pos) const
Definition: prevector.h:169
bool operator<(const_iterator x) const
Definition: prevector.h:127
prevector(size_type n, const T &val)
Definition: prevector.h:246
const_iterator end() const
Definition: prevector.h:302
iterator & operator-=(size_type n)
Definition: prevector.h:70
const_iterator begin() const
Definition: prevector.h:300
iterator & operator--()
Definition: prevector.h:63
bool operator==(const_iterator x) const
Definition: prevector.h:122
bool operator!=(reverse_iterator x) const
Definition: prevector.h:97
const_iterator & operator+=(size_type n)
Definition: prevector.h:119
const_iterator(const T *ptr_)
Definition: prevector.h:108
value_type & reference
Definition: prevector.h:44
void emplace_back(Args &&... args)
Definition: prevector.h:429
difference_type friend operator-(const_iterator a, const_iterator b)
Definition: prevector.h:117