diff --git a/libcxx/include/__iterator/static_bounded_iter.h b/libcxx/include/__iterator/static_bounded_iter.h index 92e879ccefcb0c..fd6bbe71f9c325 100644 --- a/libcxx/include/__iterator/static_bounded_iter.h +++ b/libcxx/include/__iterator/static_bounded_iter.h @@ -31,6 +31,37 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD +template +struct __static_bounded_iter_storage { + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __static_bounded_iter_storage(_Iterator __current, _Iterator __begin) + : __current_(__current), __begin_(__begin) {} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator& __current() _NOEXCEPT { return __current_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __current() const _NOEXCEPT { return __current_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __begin() const _NOEXCEPT { return __begin_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __end() const _NOEXCEPT { return __begin_ + _Size; } + +private: + _Iterator __current_; // current iterator + _Iterator __begin_; // start of the valid range, which is [__begin_, __begin_ + _Size) +}; + +template +struct __static_bounded_iter_storage<_Iterator, 0> { + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __static_bounded_iter_storage(_Iterator __current, _Iterator /* __begin */) + : __current_(__current) {} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator& __current() _NOEXCEPT { return __current_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __current() const _NOEXCEPT { return __current_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __begin() const _NOEXCEPT { return __current_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __end() const _NOEXCEPT { return __current_ + _Size; } + +private: + _Iterator __current_; // current iterator +}; + // This is an iterator wrapper for contiguous iterators that points within a range // whose size is known at compile-time. This is very similar to `__bounded_iter`, // 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 { template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __static_bounded_iter(__static_bounded_iter<_OtherIterator, _Size> const& __other) _NOEXCEPT - : __current_(__other.__current_), - __begin_(__other.__begin_) {} + : __storage_(__other.__storage_.__current(), __other.__storage_.__begin()) {} // Assign a bounded iterator to another one, rebinding the bounds of the iterator as well. _LIBCPP_HIDE_FROM_ABI __static_bounded_iter& operator=(__static_bounded_iter const&) = default; @@ -72,7 +102,7 @@ struct __static_bounded_iter { // by the provided [begin, begin + _Size] range. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __static_bounded_iter(_Iterator __current, _Iterator __begin) - : __current_(__current), __begin_(__begin) { + : __storage_(__current, __begin) { _LIBCPP_ASSERT_INTERNAL( __begin <= __current, "__static_bounded_iter(current, begin): current and begin are inconsistent"); _LIBCPP_ASSERT_INTERNAL( @@ -86,23 +116,24 @@ struct __static_bounded_iter { // Dereference and indexing operations. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( - __current_ != __end(), "__static_bounded_iter::operator*: Attempt to dereference an iterator at the end"); - return *__current_; + __current() != __end(), "__static_bounded_iter::operator*: Attempt to dereference an iterator at the end"); + return *__current(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( - __current_ != __end(), "__static_bounded_iter::operator->: Attempt to dereference an iterator at the end"); - return std::__to_address(__current_); + __current() != __end(), "__static_bounded_iter::operator->: Attempt to dereference an iterator at the end"); + return std::__to_address(__current()); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( - __n >= __begin_ - __current_, "__static_bounded_iter::operator[]: Attempt to index an iterator past the start"); + __n >= __begin() - __current(), + "__static_bounded_iter::operator[]: Attempt to index an iterator past the start"); _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( - __n < __end() - __current_, + __n < __end() - __current(), "__static_bounded_iter::operator[]: Attempt to index an iterator at or past the end"); - return __current_[__n]; + return __current()[__n]; } // Arithmetic operations. @@ -110,8 +141,8 @@ struct __static_bounded_iter { // These operations check that the iterator remains within `[begin, end]`. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator++() _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( - __current_ != __end(), "__static_bounded_iter::operator++: Attempt to advance an iterator past the end"); - ++__current_; + __current() != __end(), "__static_bounded_iter::operator++: Attempt to advance an iterator past the end"); + ++__current(); return *this; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter operator++(int) _NOEXCEPT { @@ -122,8 +153,8 @@ struct __static_bounded_iter { _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator--() _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( - __current_ != __begin_, "__static_bounded_iter::operator--: Attempt to rewind an iterator past the start"); - --__current_; + __current() != __begin(), "__static_bounded_iter::operator--: Attempt to rewind an iterator past the start"); + --__current(); return *this; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter operator--(int) _NOEXCEPT { @@ -134,11 +165,11 @@ struct __static_bounded_iter { _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator+=(difference_type __n) _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( - __n >= __begin_ - __current_, + __n >= __begin() - __current(), "__static_bounded_iter::operator+=: Attempt to rewind an iterator past the start"); _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( - __n <= __end() - __current_, "__static_bounded_iter::operator+=: Attempt to advance an iterator past the end"); - __current_ += __n; + __n <= __end() - __current(), "__static_bounded_iter::operator+=: Attempt to advance an iterator past the end"); + __current() += __n; return *this; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __static_bounded_iter @@ -156,11 +187,11 @@ struct __static_bounded_iter { _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __static_bounded_iter& operator-=(difference_type __n) _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( - __n <= __current_ - __begin_, + __n <= __current() - __begin(), "__static_bounded_iter::operator-=: Attempt to rewind an iterator past the start"); _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( - __n >= __current_ - __end(), "__static_bounded_iter::operator-=: Attempt to advance an iterator past the end"); - __current_ -= __n; + __n >= __current() - __end(), "__static_bounded_iter::operator-=: Attempt to advance an iterator past the end"); + __current() -= __n; return *this; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __static_bounded_iter @@ -171,7 +202,7 @@ struct __static_bounded_iter { } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend difference_type operator-(__static_bounded_iter const& __x, __static_bounded_iter const& __y) _NOEXCEPT { - return __x.__current_ - __y.__current_; + return __x.__current() - __y.__current(); } // Comparison operations. @@ -182,42 +213,42 @@ struct __static_bounded_iter { // if they have different validity ranges. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool operator==(__static_bounded_iter const& __x, __static_bounded_iter const& __y) _NOEXCEPT { - return __x.__current_ == __y.__current_; + return __x.__current() == __y.__current(); } #if _LIBCPP_STD_VER <= 17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool operator!=(__static_bounded_iter const& __x, __static_bounded_iter const& __y) _NOEXCEPT { - return __x.__current_ != __y.__current_; + return __x.__current() != __y.__current(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool operator<(__static_bounded_iter const& __x, __static_bounded_iter const& __y) _NOEXCEPT { - return __x.__current_ < __y.__current_; + return __x.__current() < __y.__current(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool operator>(__static_bounded_iter const& __x, __static_bounded_iter const& __y) _NOEXCEPT { - return __x.__current_ > __y.__current_; + return __x.__current() > __y.__current(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool operator<=(__static_bounded_iter const& __x, __static_bounded_iter const& __y) _NOEXCEPT { - return __x.__current_ <= __y.__current_; + return __x.__current() <= __y.__current(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool operator>=(__static_bounded_iter const& __x, __static_bounded_iter const& __y) _NOEXCEPT { - return __x.__current_ >= __y.__current_; + return __x.__current() >= __y.__current(); } #else _LIBCPP_HIDE_FROM_ABI constexpr friend strong_ordering operator<=>(__static_bounded_iter const& __x, __static_bounded_iter const& __y) noexcept { if constexpr (three_way_comparable<_Iterator, strong_ordering>) { - return __x.__current_ <=> __y.__current_; + return __x.__current() <=> __y.__current(); } else { - if (__x.__current_ < __y.__current_) + if (__x.__current() < __y.__current()) return strong_ordering::less; - if (__x.__current_ == __y.__current_) + if (__x.__current() == __y.__current()) return strong_ordering::equal; return strong_ordering::greater; @@ -230,10 +261,12 @@ struct __static_bounded_iter { friend struct pointer_traits; template friend struct __static_bounded_iter; - _Iterator __current_; // current iterator - _Iterator __begin_; // start of the valid range, which is [__begin_, __begin_ + _Size) + __static_bounded_iter_storage<_Iterator, _Size> __storage_; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __end() const _NOEXCEPT { return __begin_ + _Size; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator& __current() _NOEXCEPT { return __storage_.__current(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __current() const _NOEXCEPT { return __storage_.__current(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __begin() const _NOEXCEPT { return __storage_.__begin(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iterator __end() const _NOEXCEPT { return __storage_.__end(); } }; template @@ -254,7 +287,7 @@ struct pointer_traits<__static_bounded_iter<_Iterator, _Size> > { using difference_type = typename pointer_traits<_Iterator>::difference_type; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __it) _NOEXCEPT { - return std::__to_address(__it.__current_); + return std::__to_address(__it.__current()); } };