@@ -31,6 +31,37 @@ _LIBCPP_PUSH_MACROS
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
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+
3465// This is an iterator wrapper for contiguous iterators that points within a range
3566// whose size is known at compile-time. This is very similar to `__bounded_iter`,
3667// 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 {
6091 template <class _OtherIterator , __enable_if_t <is_convertible<_OtherIterator, _Iterator>::value, int > = 0 >
6192 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
6293 __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()) {}
6595
6696 // Assign a bounded iterator to another one, rebinding the bounds of the iterator as well.
6797 _LIBCPP_HIDE_FROM_ABI __static_bounded_iter& operator =(__static_bounded_iter const &) = default ;
@@ -72,7 +102,7 @@ struct __static_bounded_iter {
72102 // by the provided [begin, begin + _Size] range.
73103 _LIBCPP_HIDE_FROM_ABI
74104 _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __static_bounded_iter (_Iterator __current, _Iterator __begin)
75- : __current_ (__current), __begin_( __begin) {
105+ : __storage_ (__current, __begin) {
76106 _LIBCPP_ASSERT_INTERNAL (
77107 __begin <= __current, " __static_bounded_iter(current, begin): current and begin are inconsistent" );
78108 _LIBCPP_ASSERT_INTERNAL (
@@ -86,32 +116,33 @@ struct __static_bounded_iter {
86116 // Dereference and indexing operations.
87117 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator *() const _NOEXCEPT {
88118 _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 () ;
91121 }
92122
93123 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator ->() const _NOEXCEPT {
94124 _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 () );
97127 }
98128
99129 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator [](difference_type __n) const _NOEXCEPT {
100130 _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" );
102133 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
103- __n < __end () - __current_ ,
134+ __n < __end () - __current () ,
104135 " __static_bounded_iter::operator[]: Attempt to index an iterator at or past the end" );
105- return __current_ [__n];
136+ return __current () [__n];
106137 }
107138
108139 // Arithmetic operations.
109140 //
110141 // These operations check that the iterator remains within `[begin, end]`.
111142 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator ++() _NOEXCEPT {
112143 _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 () ;
115146 return *this ;
116147 }
117148 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter operator ++(int ) _NOEXCEPT {
@@ -122,8 +153,8 @@ struct __static_bounded_iter {
122153
123154 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator --() _NOEXCEPT {
124155 _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 () ;
127158 return *this ;
128159 }
129160 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter operator --(int ) _NOEXCEPT {
@@ -134,11 +165,11 @@ struct __static_bounded_iter {
134165
135166 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator +=(difference_type __n) _NOEXCEPT {
136167 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
137- __n >= __begin_ - __current_ ,
168+ __n >= __begin () - __current () ,
138169 " __static_bounded_iter::operator+=: Attempt to rewind an iterator past the start" );
139170 _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;
142173 return *this ;
143174 }
144175 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __static_bounded_iter
@@ -156,11 +187,11 @@ struct __static_bounded_iter {
156187
157188 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator -=(difference_type __n) _NOEXCEPT {
158189 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
159- __n <= __current_ - __begin_ ,
190+ __n <= __current () - __begin () ,
160191 " __static_bounded_iter::operator-=: Attempt to rewind an iterator past the start" );
161192 _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;
164195 return *this ;
165196 }
166197 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __static_bounded_iter
@@ -171,7 +202,7 @@ struct __static_bounded_iter {
171202 }
172203 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend difference_type
173204 operator -(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
174- return __x.__current_ - __y.__current_ ;
205+ return __x.__current () - __y.__current () ;
175206 }
176207
177208 // Comparison operations.
@@ -182,42 +213,42 @@ struct __static_bounded_iter {
182213 // if they have different validity ranges.
183214 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
184215 operator ==(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
185- return __x.__current_ == __y.__current_ ;
216+ return __x.__current () == __y.__current () ;
186217 }
187218
188219#if _LIBCPP_STD_VER <= 17
189220 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
190221 operator !=(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
191- return __x.__current_ != __y.__current_ ;
222+ return __x.__current () != __y.__current () ;
192223 }
193224
194225 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
195226 operator <(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
196- return __x.__current_ < __y.__current_ ;
227+ return __x.__current () < __y.__current () ;
197228 }
198229 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
199230 operator >(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
200- return __x.__current_ > __y.__current_ ;
231+ return __x.__current () > __y.__current () ;
201232 }
202233 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
203234 operator <=(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
204- return __x.__current_ <= __y.__current_ ;
235+ return __x.__current () <= __y.__current () ;
205236 }
206237 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
207238 operator >=(__static_bounded_iter const & __x, __static_bounded_iter const & __y) _NOEXCEPT {
208- return __x.__current_ >= __y.__current_ ;
239+ return __x.__current () >= __y.__current () ;
209240 }
210241
211242#else
212243 _LIBCPP_HIDE_FROM_ABI constexpr friend strong_ordering
213244 operator <=>(__static_bounded_iter const & __x, __static_bounded_iter const & __y) noexcept {
214245 if constexpr (three_way_comparable<_Iterator, strong_ordering>) {
215- return __x.__current_ <=> __y.__current_ ;
246+ return __x.__current () <=> __y.__current () ;
216247 } else {
217- if (__x.__current_ < __y.__current_ )
248+ if (__x.__current () < __y.__current () )
218249 return strong_ordering::less;
219250
220- if (__x.__current_ == __y.__current_ )
251+ if (__x.__current () == __y.__current () )
221252 return strong_ordering::equal;
222253
223254 return strong_ordering::greater;
@@ -230,10 +261,12 @@ struct __static_bounded_iter {
230261 friend struct pointer_traits ;
231262 template <class , size_t , class >
232263 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_;
235265
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 (); }
237270};
238271
239272template <size_t _Size, class _It >
@@ -254,7 +287,7 @@ struct pointer_traits<__static_bounded_iter<_Iterator, _Size> > {
254287 using difference_type = typename pointer_traits<_Iterator>::difference_type;
255288
256289 _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 () );
258291 }
259292};
260293
0 commit comments