@@ -31,6 +31,37 @@ _LIBCPP_PUSH_MACROS
31
31
32
32
_LIBCPP_BEGIN_NAMESPACE_STD
33
33
34
+ template <class _Iterator , size_t _Size>
35
+ struct __static_bounded_iter_storage {
36
+ _LIBCPP_HIDE_FROM_ABI
37
+ _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __static_bounded_iter_storage (_Iterator __current, _Iterator __begin)
38
+ : __current_(__current), __begin_(__begin) {}
39
+
40
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator& __current () _NOEXCEPT { return __current_; }
41
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __current () const _NOEXCEPT { return __current_; }
42
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __begin () const _NOEXCEPT { return __begin_; }
43
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __end () const _NOEXCEPT { return __begin_ + _Size; }
44
+
45
+ private:
46
+ _Iterator __current_; // current iterator
47
+ _Iterator __begin_; // start of the valid range, which is [__begin_, __begin_ + _Size)
48
+ };
49
+
50
+ template <class _Iterator , size_t _Size>
51
+ struct __static_bounded_iter_storage <_Iterator, 0 > {
52
+ _LIBCPP_HIDE_FROM_ABI
53
+ _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __static_bounded_iter_storage (_Iterator __current, _Iterator /* __begin */ )
54
+ : __current_(__current) {}
55
+
56
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator& __current () _NOEXCEPT { return __current_; }
57
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __current () const _NOEXCEPT { return __current_; }
58
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __begin () const _NOEXCEPT { return __current_; }
59
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __end () const _NOEXCEPT { return __current_ + _Size; }
60
+
61
+ private:
62
+ _Iterator __current_; // current iterator
63
+ };
64
+
34
65
// This is an iterator wrapper for contiguous iterators that points within a range
35
66
// whose size is known at compile-time. This is very similar to `__bounded_iter`,
36
67
// except that we don't have to store the end of the range in physical memory since
@@ -60,8 +91,7 @@ struct __static_bounded_iter {
60
91
template <class _OtherIterator , __enable_if_t <is_convertible<_OtherIterator, _Iterator>::value, int > = 0 >
61
92
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
62
93
__static_bounded_iter (__static_bounded_iter<_OtherIterator, _Size> const & __other) _NOEXCEPT
63
- : __current_(__other.__current_),
64
- __begin_ (__other.__begin_) {}
94
+ : __storage_(__other.__storage_.__current(), __other.__storage_.__begin()) {}
65
95
66
96
// Assign a bounded iterator to another one, rebinding the bounds of the iterator as well.
67
97
_LIBCPP_HIDE_FROM_ABI __static_bounded_iter& operator =(__static_bounded_iter const &) = default ;
@@ -72,7 +102,7 @@ struct __static_bounded_iter {
72
102
// by the provided [begin, begin + _Size] range.
73
103
_LIBCPP_HIDE_FROM_ABI
74
104
_LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __static_bounded_iter (_Iterator __current, _Iterator __begin)
75
- : __current_ (__current), __begin_( __begin) {
105
+ : __storage_ (__current, __begin) {
76
106
_LIBCPP_ASSERT_INTERNAL (
77
107
__begin <= __current, " __static_bounded_iter(current, begin): current and begin are inconsistent" );
78
108
_LIBCPP_ASSERT_INTERNAL (
@@ -86,32 +116,33 @@ struct __static_bounded_iter {
86
116
// Dereference and indexing operations.
87
117
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator *() const _NOEXCEPT {
88
118
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
89
- __current_ != __end (), " __static_bounded_iter::operator*: Attempt to dereference an iterator at the end" );
90
- return *__current_ ;
119
+ __current () != __end (), " __static_bounded_iter::operator*: Attempt to dereference an iterator at the end" );
120
+ return *__current () ;
91
121
}
92
122
93
123
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator ->() const _NOEXCEPT {
94
124
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
95
- __current_ != __end (), " __static_bounded_iter::operator->: Attempt to dereference an iterator at the end" );
96
- return std::__to_address (__current_ );
125
+ __current () != __end (), " __static_bounded_iter::operator->: Attempt to dereference an iterator at the end" );
126
+ return std::__to_address (__current () );
97
127
}
98
128
99
129
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator [](difference_type __n) const _NOEXCEPT {
100
130
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
101
- __n >= __begin_ - __current_, " __static_bounded_iter::operator[]: Attempt to index an iterator past the start" );
131
+ __n >= __begin () - __current (),
132
+ " __static_bounded_iter::operator[]: Attempt to index an iterator past the start" );
102
133
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
103
- __n < __end () - __current_ ,
134
+ __n < __end () - __current () ,
104
135
" __static_bounded_iter::operator[]: Attempt to index an iterator at or past the end" );
105
- return __current_ [__n];
136
+ return __current () [__n];
106
137
}
107
138
108
139
// Arithmetic operations.
109
140
//
110
141
// These operations check that the iterator remains within `[begin, end]`.
111
142
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator ++() _NOEXCEPT {
112
143
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
113
- __current_ != __end (), " __static_bounded_iter::operator++: Attempt to advance an iterator past the end" );
114
- ++__current_ ;
144
+ __current () != __end (), " __static_bounded_iter::operator++: Attempt to advance an iterator past the end" );
145
+ ++__current () ;
115
146
return *this ;
116
147
}
117
148
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter operator ++(int ) _NOEXCEPT {
@@ -122,8 +153,8 @@ struct __static_bounded_iter {
122
153
123
154
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator --() _NOEXCEPT {
124
155
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
125
- __current_ != __begin_ , " __static_bounded_iter::operator--: Attempt to rewind an iterator past the start" );
126
- --__current_ ;
156
+ __current () != __begin () , " __static_bounded_iter::operator--: Attempt to rewind an iterator past the start" );
157
+ --__current () ;
127
158
return *this ;
128
159
}
129
160
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter operator --(int ) _NOEXCEPT {
@@ -134,11 +165,11 @@ struct __static_bounded_iter {
134
165
135
166
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator +=(difference_type __n) _NOEXCEPT {
136
167
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
137
- __n >= __begin_ - __current_ ,
168
+ __n >= __begin () - __current () ,
138
169
" __static_bounded_iter::operator+=: Attempt to rewind an iterator past the start" );
139
170
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
140
- __n <= __end () - __current_ , " __static_bounded_iter::operator+=: Attempt to advance an iterator past the end" );
141
- __current_ += __n;
171
+ __n <= __end () - __current () , " __static_bounded_iter::operator+=: Attempt to advance an iterator past the end" );
172
+ __current () += __n;
142
173
return *this ;
143
174
}
144
175
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __static_bounded_iter
@@ -156,11 +187,11 @@ struct __static_bounded_iter {
156
187
157
188
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator -=(difference_type __n) _NOEXCEPT {
158
189
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
159
- __n <= __current_ - __begin_ ,
190
+ __n <= __current () - __begin () ,
160
191
" __static_bounded_iter::operator-=: Attempt to rewind an iterator past the start" );
161
192
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
162
- __n >= __current_ - __end (), " __static_bounded_iter::operator-=: Attempt to advance an iterator past the end" );
163
- __current_ -= __n;
193
+ __n >= __current () - __end (), " __static_bounded_iter::operator-=: Attempt to advance an iterator past the end" );
194
+ __current () -= __n;
164
195
return *this ;
165
196
}
166
197
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __static_bounded_iter
@@ -171,7 +202,7 @@ struct __static_bounded_iter {
171
202
}
172
203
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend difference_type
173
204
operator -(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
174
- return __x.__current_ - __y.__current_ ;
205
+ return __x.__current () - __y.__current () ;
175
206
}
176
207
177
208
// Comparison operations.
@@ -182,42 +213,42 @@ struct __static_bounded_iter {
182
213
// if they have different validity ranges.
183
214
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
184
215
operator ==(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
185
- return __x.__current_ == __y.__current_ ;
216
+ return __x.__current () == __y.__current () ;
186
217
}
187
218
188
219
#if _LIBCPP_STD_VER <= 17
189
220
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
190
221
operator !=(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
191
- return __x.__current_ != __y.__current_ ;
222
+ return __x.__current () != __y.__current () ;
192
223
}
193
224
194
225
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
195
226
operator <(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
196
- return __x.__current_ < __y.__current_ ;
227
+ return __x.__current () < __y.__current () ;
197
228
}
198
229
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
199
230
operator >(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
200
- return __x.__current_ > __y.__current_ ;
231
+ return __x.__current () > __y.__current () ;
201
232
}
202
233
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
203
234
operator <=(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
204
- return __x.__current_ <= __y.__current_ ;
235
+ return __x.__current () <= __y.__current () ;
205
236
}
206
237
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
207
238
operator >=(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
208
- return __x.__current_ >= __y.__current_ ;
239
+ return __x.__current () >= __y.__current () ;
209
240
}
210
241
211
242
#else
212
243
_LIBCPP_HIDE_FROM_ABI constexpr friend strong_ordering
213
244
operator <=>(__static_bounded_iter const & __x, __static_bounded_iter const & __y) noexcept {
214
245
if constexpr (three_way_comparable<_Iterator, strong_ordering>) {
215
- return __x.__current_ <=> __y.__current_ ;
246
+ return __x.__current () <=> __y.__current () ;
216
247
} else {
217
- if (__x.__current_ < __y.__current_ )
248
+ if (__x.__current () < __y.__current () )
218
249
return strong_ordering::less;
219
250
220
- if (__x.__current_ == __y.__current_ )
251
+ if (__x.__current () == __y.__current () )
221
252
return strong_ordering::equal;
222
253
223
254
return strong_ordering::greater;
@@ -230,10 +261,12 @@ struct __static_bounded_iter {
230
261
friend struct pointer_traits ;
231
262
template <class , size_t , class >
232
263
friend struct __static_bounded_iter ;
233
- _Iterator __current_; // current iterator
234
- _Iterator __begin_; // start of the valid range, which is [__begin_, __begin_ + _Size)
264
+ __static_bounded_iter_storage<_Iterator, _Size> __storage_;
235
265
236
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __end () const _NOEXCEPT { return __begin_ + _Size; }
266
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator& __current () _NOEXCEPT { return __storage_.__current (); }
267
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __current () const _NOEXCEPT { return __storage_.__current (); }
268
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __begin () const _NOEXCEPT { return __storage_.__begin (); }
269
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __end () const _NOEXCEPT { return __storage_.__end (); }
237
270
};
238
271
239
272
template <size_t _Size, class _It >
@@ -254,7 +287,7 @@ struct pointer_traits<__static_bounded_iter<_Iterator, _Size> > {
254
287
using difference_type = typename pointer_traits<_Iterator>::difference_type;
255
288
256
289
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address (pointer __it) _NOEXCEPT {
257
- return std::__to_address (__it.__current_ );
290
+ return std::__to_address (__it.__current () );
258
291
}
259
292
};
260
293
0 commit comments