xref: /freebsd-src/contrib/llvm-project/libcxx/include/__iterator/move_iterator.h (revision 8cc087a1eee9ec1ca9f7ac1e63ad51bdb5a682eb)
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H
11 #define _LIBCPP___ITERATOR_MOVE_ITERATOR_H
12 
13 #include <__config>
14 #include <__iterator/iterator_traits.h>
15 #include <__utility/move.h>
16 #include <type_traits>
17 
18 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19 #pragma GCC system_header
20 #endif
21 
22 _LIBCPP_BEGIN_NAMESPACE_STD
23 
24 template <class _Iter>
25 class _LIBCPP_TEMPLATE_VIS move_iterator
26 {
27 public:
28 #if _LIBCPP_STD_VER > 17
29     typedef input_iterator_tag iterator_concept;
30 #endif
31 
32     typedef _Iter iterator_type;
33     typedef _If<
34         __is_cpp17_random_access_iterator<_Iter>::value,
35         random_access_iterator_tag,
36         typename iterator_traits<_Iter>::iterator_category
37     >  iterator_category;
38     typedef typename iterator_traits<iterator_type>::value_type value_type;
39     typedef typename iterator_traits<iterator_type>::difference_type difference_type;
40     typedef iterator_type pointer;
41 
42 #ifndef _LIBCPP_CXX03_LANG
43     typedef typename iterator_traits<iterator_type>::reference __reference;
44     typedef typename conditional<
45             is_reference<__reference>::value,
46             typename remove_reference<__reference>::type&&,
47             __reference
48         >::type reference;
49 #else
50     typedef typename iterator_traits<iterator_type>::reference reference;
51 #endif
52 
53     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
54     move_iterator() : __current_() {}
55 
56     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
57     explicit move_iterator(_Iter __i) : __current_(_VSTD::move(__i)) {}
58 
59     template <class _Up, class = __enable_if_t<
60         !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value
61     > >
62     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
63     move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {}
64 
65     template <class _Up, class = __enable_if_t<
66         !is_same<_Up, _Iter>::value &&
67         is_convertible<const _Up&, _Iter>::value &&
68         is_assignable<_Iter&, const _Up&>::value
69     > >
70     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
71     move_iterator& operator=(const move_iterator<_Up>& __u) {
72         __current_ = __u.base();
73         return *this;
74     }
75 
76     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
77     _Iter base() const { return __current_; }
78 
79     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
80     reference operator*() const { return static_cast<reference>(*__current_); }
81     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
82     pointer operator->() const { return __current_; }
83     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
84     reference operator[](difference_type __n) const { return static_cast<reference>(__current_[__n]); }
85 
86     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
87     move_iterator& operator++() { ++__current_; return *this; }
88     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
89     move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; }
90     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
91     move_iterator& operator--() { --__current_; return *this; }
92     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
93     move_iterator operator--(int) { move_iterator __tmp(*this); --__current_; return __tmp; }
94     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
95     move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); }
96     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
97     move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; }
98     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
99     move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); }
100     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
101     move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; }
102 
103 private:
104     _Iter __current_;
105 };
106 
107 template <class _Iter1, class _Iter2>
108 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
109 bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
110 {
111     return __x.base() == __y.base();
112 }
113 
114 template <class _Iter1, class _Iter2>
115 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
116 bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
117 {
118     return __x.base() != __y.base();
119 }
120 
121 template <class _Iter1, class _Iter2>
122 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
123 bool operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
124 {
125     return __x.base() < __y.base();
126 }
127 
128 template <class _Iter1, class _Iter2>
129 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
130 bool operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
131 {
132     return __x.base() > __y.base();
133 }
134 
135 template <class _Iter1, class _Iter2>
136 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
137 bool operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
138 {
139     return __x.base() <= __y.base();
140 }
141 
142 template <class _Iter1, class _Iter2>
143 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
144 bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
145 {
146     return __x.base() >= __y.base();
147 }
148 
149 #ifndef _LIBCPP_CXX03_LANG
150 template <class _Iter1, class _Iter2>
151 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
152 auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
153     -> decltype(__x.base() - __y.base())
154 {
155     return __x.base() - __y.base();
156 }
157 #else
158 template <class _Iter1, class _Iter2>
159 inline _LIBCPP_HIDE_FROM_ABI
160 typename move_iterator<_Iter1>::difference_type
161 operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
162 {
163     return __x.base() - __y.base();
164 }
165 #endif
166 
167 template <class _Iter>
168 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
169 move_iterator<_Iter>
170 operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
171 {
172     return move_iterator<_Iter>(__x.base() + __n);
173 }
174 
175 template <class _Iter>
176 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
177 move_iterator<_Iter>
178 make_move_iterator(_Iter __i)
179 {
180     return move_iterator<_Iter>(_VSTD::move(__i));
181 }
182 
183 _LIBCPP_END_NAMESPACE_STD
184 
185 #endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H
186