9 #ifndef UTIL_ITERATOR_H
10 #define UTIL_ITERATOR_H
15 #include <type_traits>
64 template <
typename DerivedT,
typename IteratorCategoryT,
typename T,
65 typename DifferenceTypeT = std::ptrdiff_t,
typename PointerT = T *,
66 typename ReferenceT = T &>
80 IteratorCategoryT>::value,
82 IteratorCategoryT>::value,
99 operator ReferenceT()
const
108 static_assert(std::is_base_of<iter_facade_base, DerivedT>::value,
109 "Must pass the derived type to this template!");
112 "The '+' operator is only defined for random access iterators.");
113 DerivedT tmp = *
static_cast<const DerivedT *
>(
this);
117 friend DerivedT
operator+(DifferenceTypeT
n,
const DerivedT &i)
121 "The '+' operator is only defined for random access iterators.");
128 "The '-' operator is only defined for random access iterators.");
129 DerivedT tmp = *
static_cast<const DerivedT *
>(
this);
136 static_assert(std::is_base_of<iter_facade_base, DerivedT>::value,
137 "Must pass the derived type to this template!");
138 return static_cast<DerivedT *
>(
this)->
operator+=(1);
142 DerivedT tmp = *
static_cast<DerivedT *
>(
this);
143 ++*
static_cast<DerivedT *
>(
this);
150 "The decrement operator is only defined for bidirectional iterators.");
151 return static_cast<DerivedT *
>(
this)->
operator-=(1);
157 "The decrement operator is only defined for bidirectional iterators.");
158 DerivedT tmp = *
static_cast<DerivedT *
>(
this);
159 --*
static_cast<DerivedT *
>(
this);
163 #ifndef __cpp_impl_three_way_comparison
166 return !(
static_cast<const DerivedT &
>(*this) == RHS);
174 "Relational operators are only defined for random access iterators.");
175 return !(
static_cast<const DerivedT &
>(*this) < RHS) &&
176 !(
static_cast<const DerivedT &
>(*
this) == RHS);
182 "Relational operators are only defined for random access iterators.");
183 return !(
static_cast<const DerivedT &
>(*this) > RHS);
189 "Relational operators are only defined for random access iterators.");
190 return !(
static_cast<const DerivedT &
>(*this) < RHS);
195 return &
static_cast<DerivedT *
>(
this)->
operator*();
199 return &
static_cast<const DerivedT *
>(
this)->
operator*();
204 "Subscripting is only defined for random access iterators.");
210 "Subscripting is only defined for random access iterators.");
211 return ReferenceProxy(
static_cast<const DerivedT *
>(
this)->
operator+(
n));
221 typename DerivedT,
typename WrappedIteratorT,
222 typename IteratorCategoryT =
223 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
224 typename T =
typename std::iterator_traits<WrappedIteratorT>::value_type,
225 typename DifferenceTypeT =
226 typename std::iterator_traits<WrappedIteratorT>::difference_type,
227 typename PointerT = std::conditional_t<
228 std::is_same<T,
typename std::iterator_traits<
229 WrappedIteratorT>::value_type>::value,
230 typename std::iterator_traits<WrappedIteratorT>::pointer, T *>,
231 typename ReferenceT = std::conditional_t<
232 std::is_same<T,
typename std::iterator_traits<
233 WrappedIteratorT>::value_type>::value,
234 typename std::iterator_traits<WrappedIteratorT>::reference, T &>>
237 DifferenceTypeT, PointerT, ReferenceT>
239 using BaseT =
typename iter_adaptor_base::iter_facade_base;
248 static_assert(std::is_base_of<iter_adaptor_base, DerivedT>::value,
249 "Must pass the derived type to this template!");
263 BaseT::IsRandomAccess,
264 "The '+=' operator is only defined for random access iterators.");
266 return *
static_cast<DerivedT *
>(
this);
271 BaseT::IsRandomAccess,
272 "The '-=' operator is only defined for random access iterators.");
274 return *
static_cast<DerivedT *
>(
this);
276 using BaseT::operator-;
280 BaseT::IsRandomAccess,
281 "The '-' operator is only defined for random access iterators.");
287 using BaseT::operator++;
291 return *
static_cast<DerivedT *
>(
this);
293 using BaseT::operator--;
297 BaseT::IsBidirectional,
298 "The decrement operator is only defined for bidirectional iterators.");
300 return *
static_cast<DerivedT *
>(
this);
306 return LHS.
I == RHS.
I;
312 BaseT::IsRandomAccess,
313 "Relational operators are only defined for random access iterators.");
314 return LHS.
I < RHS.
I;
332 template <
typename WrappedIteratorT,
333 typename T = std::remove_reference_t<decltype(
334 **std::declval<WrappedIteratorT>())>>
337 pointee_iter<WrappedIteratorT, T>, WrappedIteratorT,
338 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
342 template <
typename U>
352 template <
typename RangeT,
typename WrappedIteratorT =
353 decltype(std::begin(std::declval<RangeT>()))>
354 iter_range<pointee_iter<WrappedIteratorT>>
358 return make_range(PointeeIteratorT(std::begin(std::forward<RangeT>(Range))),
359 PointeeIteratorT(std::end(std::forward<RangeT>(Range))));
362 template <
typename WrappedIteratorT,
363 typename T = decltype(&*std::declval<WrappedIteratorT>())>
366 pointer_iterator<WrappedIteratorT, T>, WrappedIteratorT,
367 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
380 return Ptr = &*this->
I;
384 return Ptr = &*this->
I;
388 template <
typename RangeT,
typename WrappedIteratorT =
389 decltype(std::begin(std::declval<RangeT>()))>
390 iter_range<pointer_iterator<WrappedIteratorT>>
394 return make_range(PointerIteratorT(std::begin(std::forward<RangeT>(Range))),
395 PointerIteratorT(std::end(std::forward<RangeT>(Range))));
398 template <
typename WrappedIteratorT,
399 typename T1 = std::remove_reference_t<decltype(
400 **std::declval<WrappedIteratorT>())>,
401 typename T2 = std::add_pointer_t<T1>>
DerivedT & operator+=(difference_type n)
friend bool operator<(const iter_adaptor_base &LHS, const iter_adaptor_base &RHS)
friend bool operator==(const iter_adaptor_base &LHS, const iter_adaptor_base &RHS)
DifferenceTypeT difference_type
DerivedT & operator-=(difference_type n)
difference_type operator-(const DerivedT &RHS) const
iter_adaptor_base()=default
iter_adaptor_base(WrappedIteratorT u)
ReferenceT operator*() const
const WrappedIteratorT & wrapped() const
typename iter_adaptor_base::iter_facade_base BaseT
ReferenceProxy(DerivedT I)
IteratorCategoryT iterator_category
ReferenceProxy operator[](DifferenceTypeT n)
DifferenceTypeT difference_type
bool operator>(const DerivedT &RHS) const
friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i)
bool operator!=(const DerivedT &RHS) const
PointerT operator->() const
DerivedT operator+(DifferenceTypeT n) const
ReferenceProxy operator[](DifferenceTypeT n) const
bool operator>=(const DerivedT &RHS) const
bool operator<=(const DerivedT &RHS) const
DerivedT operator-(DifferenceTypeT n) const
pointer_iterator(WrappedIteratorT u)
pointer_iterator()=default
const T & operator*() const
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
iter_range< T > make_range(T x, T y)
iter_range< pointee_iter< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
iter_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)