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