Skip to content

Commit f879c1b

Browse files
committed
Merge bitcoin/bitcoin#29275: refactor: Fix prevector iterator concept issues
fad74bb refactor: Mark prevector iterator with std::contiguous_iterator_tag (MarcoFalke) fab8a01 refactor: Fix binary operator+ for prevector iterators (MarcoFalke) fa44a60 refactor: Fix constness for prevector iterators (MarcoFalke) facaa66 refactor: Add missing default constructor to prevector iterators (MarcoFalke) Pull request description: Currently prevector iterators have many issues: * Forward iterators (and stronger) must be default constructible (https://eel.is/c++draft/forward.iterators#1.2). Otherwise, some functions can not be instantiated, like `std::minmax_element`. * Various `const` issues with random access iterators. For example, a `const iterator` is different from a `const_iterator`, because the first one holds a mutable reference and must also return it without `const`. Also, `operator+` must be callable regardless of the iterator object's `const`-ness. * When adding an offset to random access iterators, both `x+n` and `n+x` must be specified, see https://eel.is/c++draft/random.access.iterators#tab:randomaccessiterator Fix all issues. Also, upgrade the `std::random_access_iterator_tag` (C++17) to `std::contiguous_iterator_tag` (C++20) ACKs for top commit: TheCharlatan: ACK fad74bb stickies-v: ACK fad74bb willcl-ark: ACK fad74bb Tree-SHA512: b1ca778a31602af94b323b8feaf993833ec78be09f1d438a68335485a4ba97f52125fdd977ffb9541b89f8d45be0105076aa07b5726936133519aae832556e0b
2 parents aa9231f + fad74bb commit f879c1b

File tree

1 file changed

+21
-16
lines changed

1 file changed

+21
-16
lines changed

src/prevector.h

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,28 @@ class prevector {
4747
typedef const value_type* const_pointer;
4848

4949
class iterator {
50-
T* ptr;
50+
T* ptr{};
5151
public:
5252
typedef Diff difference_type;
5353
typedef T value_type;
5454
typedef T* pointer;
5555
typedef T& reference;
56-
typedef std::random_access_iterator_tag iterator_category;
56+
using element_type = T;
57+
using iterator_category = std::contiguous_iterator_tag;
58+
iterator() = default;
5759
iterator(T* ptr_) : ptr(ptr_) {}
5860
T& operator*() const { return *ptr; }
5961
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+
T& operator[](size_type pos) const { return ptr[pos]; }
6263
iterator& operator++() { ptr++; return *this; }
6364
iterator& operator--() { ptr--; return *this; }
6465
iterator operator++(int) { iterator copy(*this); ++(*this); return copy; }
6566
iterator operator--(int) { iterator copy(*this); --(*this); return copy; }
6667
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) const { return iterator(ptr + n); }
69+
iterator friend operator+(size_type n, iterator x) { return x + n; }
6870
iterator& operator+=(size_type n) { ptr += n; return *this; }
69-
iterator operator-(size_type n) { return iterator(ptr - n); }
71+
iterator operator-(size_type n) const { return iterator(ptr - n); }
7072
iterator& operator-=(size_type n) { ptr -= n; return *this; }
7173
bool operator==(iterator x) const { return ptr == x.ptr; }
7274
bool operator!=(iterator x) const { return ptr != x.ptr; }
@@ -77,18 +79,17 @@ class prevector {
7779
};
7880

7981
class reverse_iterator {
80-
T* ptr;
82+
T* ptr{};
8183
public:
8284
typedef Diff difference_type;
8385
typedef T value_type;
8486
typedef T* pointer;
8587
typedef T& reference;
8688
typedef std::bidirectional_iterator_tag iterator_category;
89+
reverse_iterator() = default;
8790
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; }
91+
T& operator*() const { return *ptr; }
92+
T* operator->() const { return ptr; }
9293
reverse_iterator& operator--() { ptr++; return *this; }
9394
reverse_iterator& operator++() { ptr--; return *this; }
9495
reverse_iterator operator++(int) { reverse_iterator copy(*this); ++(*this); return copy; }
@@ -98,13 +99,15 @@ class prevector {
9899
};
99100

100101
class const_iterator {
101-
const T* ptr;
102+
const T* ptr{};
102103
public:
103104
typedef Diff difference_type;
104105
typedef const T value_type;
105106
typedef const T* pointer;
106107
typedef const T& reference;
107-
typedef std::random_access_iterator_tag iterator_category;
108+
using element_type = const T;
109+
using iterator_category = std::contiguous_iterator_tag;
110+
const_iterator() = default;
108111
const_iterator(const T* ptr_) : ptr(ptr_) {}
109112
const_iterator(iterator x) : ptr(&(*x)) {}
110113
const T& operator*() const { return *ptr; }
@@ -115,9 +118,10 @@ class prevector {
115118
const_iterator operator++(int) { const_iterator copy(*this); ++(*this); return copy; }
116119
const_iterator operator--(int) { const_iterator copy(*this); --(*this); return copy; }
117120
difference_type friend operator-(const_iterator a, const_iterator b) { return (&(*a) - &(*b)); }
118-
const_iterator operator+(size_type n) { return const_iterator(ptr + n); }
121+
const_iterator operator+(size_type n) const { return const_iterator(ptr + n); }
122+
const_iterator friend operator+(size_type n, const_iterator x) { return x + n; }
119123
const_iterator& operator+=(size_type n) { ptr += n; return *this; }
120-
const_iterator operator-(size_type n) { return const_iterator(ptr - n); }
124+
const_iterator operator-(size_type n) const { return const_iterator(ptr - n); }
121125
const_iterator& operator-=(size_type n) { ptr -= n; return *this; }
122126
bool operator==(const_iterator x) const { return ptr == x.ptr; }
123127
bool operator!=(const_iterator x) const { return ptr != x.ptr; }
@@ -128,13 +132,14 @@ class prevector {
128132
};
129133

130134
class const_reverse_iterator {
131-
const T* ptr;
135+
const T* ptr{};
132136
public:
133137
typedef Diff difference_type;
134138
typedef const T value_type;
135139
typedef const T* pointer;
136140
typedef const T& reference;
137141
typedef std::bidirectional_iterator_tag iterator_category;
142+
const_reverse_iterator() = default;
138143
const_reverse_iterator(const T* ptr_) : ptr(ptr_) {}
139144
const_reverse_iterator(reverse_iterator x) : ptr(&(*x)) {}
140145
const T& operator*() const { return *ptr; }

0 commit comments

Comments
 (0)