File indexing completed on 2026-05-03 08:13:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___ITERATOR_MOVE_ITERATOR_H
0011 #define _LIBCPP___CXX03___ITERATOR_MOVE_ITERATOR_H
0012
0013 #include <__cxx03/__compare/compare_three_way_result.h>
0014 #include <__cxx03/__compare/three_way_comparable.h>
0015 #include <__cxx03/__concepts/assignable.h>
0016 #include <__cxx03/__concepts/convertible_to.h>
0017 #include <__cxx03/__concepts/derived_from.h>
0018 #include <__cxx03/__concepts/same_as.h>
0019 #include <__cxx03/__config>
0020 #include <__cxx03/__iterator/concepts.h>
0021 #include <__cxx03/__iterator/incrementable_traits.h>
0022 #include <__cxx03/__iterator/iter_move.h>
0023 #include <__cxx03/__iterator/iter_swap.h>
0024 #include <__cxx03/__iterator/iterator_traits.h>
0025 #include <__cxx03/__iterator/move_sentinel.h>
0026 #include <__cxx03/__iterator/readable_traits.h>
0027 #include <__cxx03/__type_traits/conditional.h>
0028 #include <__cxx03/__type_traits/enable_if.h>
0029 #include <__cxx03/__type_traits/is_assignable.h>
0030 #include <__cxx03/__type_traits/is_constructible.h>
0031 #include <__cxx03/__type_traits/is_convertible.h>
0032 #include <__cxx03/__type_traits/is_reference.h>
0033 #include <__cxx03/__type_traits/is_same.h>
0034 #include <__cxx03/__type_traits/remove_reference.h>
0035 #include <__cxx03/__utility/declval.h>
0036 #include <__cxx03/__utility/move.h>
0037
0038 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0039 # pragma GCC system_header
0040 #endif
0041
0042 _LIBCPP_PUSH_MACROS
0043 #include <__cxx03/__undef_macros>
0044
0045 _LIBCPP_BEGIN_NAMESPACE_STD
0046
0047 #if _LIBCPP_STD_VER >= 20
0048 template <class _Iter, class = void>
0049 struct __move_iter_category_base {};
0050
0051 template <class _Iter>
0052 requires requires { typename iterator_traits<_Iter>::iterator_category; }
0053 struct __move_iter_category_base<_Iter> {
0054 using iterator_category =
0055 _If< derived_from<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>,
0056 random_access_iterator_tag,
0057 typename iterator_traits<_Iter>::iterator_category >;
0058 };
0059
0060 template <class _Iter, class _Sent>
0061 concept __move_iter_comparable = requires {
0062 { std::declval<const _Iter&>() == std::declval<_Sent>() } -> convertible_to<bool>;
0063 };
0064 #endif
0065
0066 template <class _Iter>
0067 class _LIBCPP_TEMPLATE_VIS move_iterator
0068 #if _LIBCPP_STD_VER >= 20
0069 : public __move_iter_category_base<_Iter>
0070 #endif
0071 {
0072 #if _LIBCPP_STD_VER >= 20
0073
0074 private:
0075 _LIBCPP_HIDE_FROM_ABI static constexpr auto __get_iter_concept() {
0076 if constexpr (random_access_iterator<_Iter>) {
0077 return random_access_iterator_tag{};
0078 } else if constexpr (bidirectional_iterator<_Iter>) {
0079 return bidirectional_iterator_tag{};
0080 } else if constexpr (forward_iterator<_Iter>) {
0081 return forward_iterator_tag{};
0082 } else {
0083 return input_iterator_tag{};
0084 }
0085 }
0086 #endif
0087
0088 public:
0089 #if _LIBCPP_STD_VER >= 20
0090 using iterator_type = _Iter;
0091 using iterator_concept = decltype(__get_iter_concept());
0092
0093 using value_type = iter_value_t<_Iter>;
0094 using difference_type = iter_difference_t<_Iter>;
0095 using pointer = _Iter;
0096 using reference = iter_rvalue_reference_t<_Iter>;
0097 #else
0098 typedef _Iter iterator_type;
0099 typedef _If< __has_random_access_iterator_category<_Iter>::value,
0100 random_access_iterator_tag,
0101 typename iterator_traits<_Iter>::iterator_category >
0102 iterator_category;
0103 typedef typename iterator_traits<iterator_type>::value_type value_type;
0104 typedef typename iterator_traits<iterator_type>::difference_type difference_type;
0105 typedef iterator_type pointer;
0106
0107 typedef typename iterator_traits<iterator_type>::reference __reference;
0108 typedef __conditional_t<is_reference<__reference>::value, __libcpp_remove_reference_t<__reference>&&, __reference>
0109 reference;
0110 #endif
0111
0112 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {}
0113
0114 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator++() {
0115 ++__current_;
0116 return *this;
0117 }
0118
0119 _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pointer operator->() const {
0120 return __current_;
0121 }
0122
0123 #if _LIBCPP_STD_VER >= 20
0124 _LIBCPP_HIDE_FROM_ABI constexpr move_iterator()
0125 requires is_constructible_v<_Iter>
0126 : __current_() {}
0127
0128 template <class _Up>
0129 requires(!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter>
0130 _LIBCPP_HIDE_FROM_ABI constexpr move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {}
0131
0132 template <class _Up>
0133 requires(!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter> && assignable_from<_Iter&, const _Up&>
0134 _LIBCPP_HIDE_FROM_ABI constexpr move_iterator& operator=(const move_iterator<_Up>& __u) {
0135 __current_ = __u.base();
0136 return *this;
0137 }
0138
0139 _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const& noexcept { return __current_; }
0140 _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); }
0141
0142 _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return ranges::iter_move(__current_); }
0143 _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](difference_type __n) const {
0144 return ranges::iter_move(__current_ + __n);
0145 }
0146
0147 _LIBCPP_HIDE_FROM_ABI constexpr auto operator++(int)
0148 requires forward_iterator<_Iter>
0149 {
0150 move_iterator __tmp(*this);
0151 ++__current_;
0152 return __tmp;
0153 }
0154
0155 _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; }
0156 #else
0157 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator() : __current_() {}
0158
0159 template <class _Up, __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value, int> = 0>
0160 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator(const move_iterator<_Up>& __u)
0161 : __current_(__u.base()) {}
0162
0163 template <class _Up,
0164 __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value &&
0165 is_assignable<_Iter&, const _Up&>::value,
0166 int> = 0>
0167 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator=(const move_iterator<_Up>& __u) {
0168 __current_ = __u.base();
0169 return *this;
0170 }
0171
0172 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter base() const { return __current_; }
0173
0174 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator*() const {
0175 return static_cast<reference>(*__current_);
0176 }
0177 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](difference_type __n) const {
0178 return static_cast<reference>(__current_[__n]);
0179 }
0180
0181 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator++(int) {
0182 move_iterator __tmp(*this);
0183 ++__current_;
0184 return __tmp;
0185 }
0186 #endif
0187
0188 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator--() {
0189 --__current_;
0190 return *this;
0191 }
0192 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator--(int) {
0193 move_iterator __tmp(*this);
0194 --__current_;
0195 return __tmp;
0196 }
0197 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator+(difference_type __n) const {
0198 return move_iterator(__current_ + __n);
0199 }
0200 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator+=(difference_type __n) {
0201 __current_ += __n;
0202 return *this;
0203 }
0204 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator-(difference_type __n) const {
0205 return move_iterator(__current_ - __n);
0206 }
0207 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator-=(difference_type __n) {
0208 __current_ -= __n;
0209 return *this;
0210 }
0211
0212 #if _LIBCPP_STD_VER >= 20
0213 template <sentinel_for<_Iter> _Sent>
0214 friend _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y)
0215 requires __move_iter_comparable<_Iter, _Sent>
0216 {
0217 return __x.base() == __y.base();
0218 }
0219
0220 template <sized_sentinel_for<_Iter> _Sent>
0221 friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
0222 operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) {
0223 return __x.base() - __y.base();
0224 }
0225
0226 template <sized_sentinel_for<_Iter> _Sent>
0227 friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
0228 operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) {
0229 return __x.base() - __y.base();
0230 }
0231
0232 friend _LIBCPP_HIDE_FROM_ABI constexpr iter_rvalue_reference_t<_Iter>
0233 iter_move(const move_iterator& __i) noexcept(noexcept(ranges::iter_move(__i.__current_))) {
0234 return ranges::iter_move(__i.__current_);
0235 }
0236
0237 template <indirectly_swappable<_Iter> _It2>
0238 friend _LIBCPP_HIDE_FROM_ABI constexpr void
0239 iter_swap(const move_iterator& __x,
0240 const move_iterator<_It2>& __y) noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) {
0241 return ranges::iter_swap(__x.__current_, __y.__current_);
0242 }
0243 #endif
0244
0245 private:
0246 template <class _It2>
0247 friend class move_iterator;
0248
0249 _Iter __current_;
0250 };
0251 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator);
0252
0253 template <class _Iter1, class _Iter2>
0254 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
0255 operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
0256 return __x.base() == __y.base();
0257 }
0258
0259 #if _LIBCPP_STD_VER <= 17
0260 template <class _Iter1, class _Iter2>
0261 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
0262 operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
0263 return __x.base() != __y.base();
0264 }
0265 #endif
0266
0267 template <class _Iter1, class _Iter2>
0268 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
0269 operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
0270 return __x.base() < __y.base();
0271 }
0272
0273 template <class _Iter1, class _Iter2>
0274 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
0275 operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
0276 return __x.base() > __y.base();
0277 }
0278
0279 template <class _Iter1, class _Iter2>
0280 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
0281 operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
0282 return __x.base() <= __y.base();
0283 }
0284
0285 template <class _Iter1, class _Iter2>
0286 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
0287 operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
0288 return __x.base() >= __y.base();
0289 }
0290
0291 #if _LIBCPP_STD_VER >= 20
0292 template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
0293 inline _LIBCPP_HIDE_FROM_ABI constexpr auto
0294 operator<=>(const move_iterator<_Iter1>& __x,
0295 const move_iterator<_Iter2>& __y) -> compare_three_way_result_t<_Iter1, _Iter2> {
0296 return __x.base() <=> __y.base();
0297 }
0298 #endif
0299
0300 #ifndef _LIBCPP_CXX03_LANG
0301 template <class _Iter1, class _Iter2>
0302 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
0303 operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -> decltype(__x.base() - __y.base()) {
0304 return __x.base() - __y.base();
0305 }
0306 #else
0307 template <class _Iter1, class _Iter2>
0308 inline _LIBCPP_HIDE_FROM_ABI typename move_iterator<_Iter1>::difference_type
0309 operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
0310 return __x.base() - __y.base();
0311 }
0312 #endif
0313
0314 #if _LIBCPP_STD_VER >= 20
0315 template <class _Iter>
0316 inline _LIBCPP_HIDE_FROM_ABI constexpr move_iterator<_Iter>
0317 operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x)
0318 requires requires {
0319 { __x.base() + __n } -> same_as<_Iter>;
0320 }
0321 {
0322 return __x + __n;
0323 }
0324 #else
0325 template <class _Iter>
0326 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter>
0327 operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) {
0328 return move_iterator<_Iter>(__x.base() + __n);
0329 }
0330 #endif
0331
0332 #if _LIBCPP_STD_VER >= 20
0333 template <class _Iter1, class _Iter2>
0334 requires(!sized_sentinel_for<_Iter1, _Iter2>)
0335 inline constexpr bool disable_sized_sentinel_for<move_iterator<_Iter1>, move_iterator<_Iter2>> = true;
0336 #endif
0337
0338 template <class _Iter>
0339 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> make_move_iterator(_Iter __i) {
0340 return move_iterator<_Iter>(std::move(__i));
0341 }
0342
0343 _LIBCPP_END_NAMESPACE_STD
0344
0345 _LIBCPP_POP_MACROS
0346
0347 #endif