29template <
typename T,
typename =
void>
30constexpr auto canPreDecrement =
false;
33constexpr auto canPreDecrement<T, std::void_t<
decltype (--std::declval<T>())>> =
true;
35template <
typename T,
typename I,
typename =
void>
36constexpr auto canAddAssign =
false;
38template <
typename T,
typename I>
39constexpr auto canAddAssign<T, I, std::void_t<decltype (std::declval<T>() += std::declval<I>())>> =
true;
41template <
typename T,
typename I,
typename =
void>
42constexpr auto canSubAssign =
false;
44template <
typename T,
typename I>
45constexpr auto canSubAssign<T, I, std::void_t<decltype (std::declval<T>() -= std::declval<I>())>> =
true;
47template <
typename T,
typename I,
typename =
void>
48constexpr auto canAdd =
false;
50template <
typename T,
typename I>
51constexpr auto canAdd<T, I, std::void_t<decltype (std::declval<T>() + std::declval<I>())>> =
true;
53template <
typename T,
typename I,
typename =
void>
54constexpr auto canSub =
false;
56template <
typename T,
typename I>
57constexpr auto canSub<T, I, std::void_t<decltype (std::declval<T>() - std::declval<I>())>> =
true;
59template <
typename T,
typename I,
typename =
void>
60constexpr auto canLessThan =
false;
62template <
typename T,
typename I>
63constexpr auto canLessThan<T, I, std::void_t<decltype (std::declval<T>() < std::declval<I>())>> =
true;
65template <
typename T,
typename I,
typename =
void>
66constexpr auto canLessThanEqual =
false;
68template <
typename T,
typename I>
69constexpr auto canLessThanEqual<T, I, std::void_t<decltype (std::declval<T>() <= std::declval<I>())>> =
true;
71template <
typename T,
typename I,
typename =
void>
72constexpr auto canGreaterThan =
false;
74template <
typename T,
typename I>
75constexpr auto canGreaterThan<T, I, std::void_t<decltype (std::declval<T>() > std::declval<I>())>> =
true;
77template <
typename T,
typename I,
typename =
void>
78constexpr auto canGreaterThanEqual =
false;
80template <
typename T,
typename I>
81constexpr auto canGreaterThanEqual<T, I, std::void_t<decltype (std::declval<T>() >= std::declval<I>())>> =
true;
87 template <
typename Range>
88 using AdlSize =
decltype (size (std::declval<Range>()));
90 template <
typename Range>
91 using AdlSignedSize = std::common_type_t<std::ptrdiff_t, std::make_signed_t<AdlSize<Range>>>;
108template <
typename Index,
typename Value>
126template <
typename Iter,
typename Index = ptrdiff_t>
139 : iterator (std::move (iter)), index (ind) {}
142 template <
typename OtherIter,
typename OtherInd>
145 return iterator == other.iterator;
149 template <
typename OtherIter,
typename OtherInd>
161 return { index, *iterator };
183 template <
typename T = Iter, std::enable_if_t<detail::canPreDecrement<T>,
int> = 0>
194 template <
typename T = Iter, std::enable_if_t<detail::canPreDecrement<T>,
int> = 0>
205 template <
typename I, std::enable_if_t<detail::canAddAssign<Iter&, I>,
int> = 0>
209 index +=
static_cast<Index
> (diff);
216 template <
typename I, std::enable_if_t<detail::canSubAssign<Iter&, I>,
int> = 0>
220 index -=
static_cast<Index
> (diff);
229 template <
typename OtherIter,
typename OtherInd, std::enable_if_t<detail::canSub<Iter, OtherIter>,
int> = 0>
232 return iterator - other.iterator;
240 template <
typename I, std::enable_if_t<detail::canAdd<EnumerateIterator, I>,
int> = 0>
243 return *(*
this + diff);
249 template <
typename OtherIter,
typename OtherInd, std::enable_if_t<detail::canLessThan<Iter, OtherIter>,
int> = 0>
252 return iterator < other.iterator;
258 template <
typename OtherIter,
typename OtherInd, std::enable_if_t<detail::canLessThanEqual<Iter, OtherIter>,
int> = 0>
261 return iterator <= other.iterator;
267 template <
typename OtherIter,
typename OtherInd, std::enable_if_t<detail::canGreaterThan<Iter, OtherIter>,
int> = 0>
270 return iterator > other.iterator;
276 template <
typename OtherIter,
typename OtherInd, std::enable_if_t<detail::canGreaterThanEqual<Iter, OtherIter>,
int> = 0>
279 return iterator >= other.iterator;
285 template <
typename I, std::enable_if_t<detail::canAddAssign<EnumerateIterator&, I>,
int> = 0>
294 template <
typename I, std::enable_if_t<detail::canAddAssign<EnumerateIterator&, I>,
int> = 0>
303 template <
typename I, std::enable_if_t<detail::canSubAssign<EnumerateIterator&, I>,
int> = 0>
324template <
typename Begin,
typename End>
332 : b (std::move (bIn)), e (std::move (eIn)) {}
335 constexpr auto begin()
const {
return b; }
338 constexpr auto end()
const {
return e; }
352template <
typename Begin,
typename End = Begin>
353[[nodiscard]]
constexpr auto makeRange (Begin begin, End end)
355 return IteratorPair<Begin, End> { std::move (begin), std::move (end) };
418template <
typename Range,
typename Index = detail::withAdlSize::AdlSignedSize<Range>>
419[[nodiscard]]
constexpr auto enumerate (
Range&& range, Index startingValue = {})
422 using std::begin, std::end;
constexpr EnumerateIterator(Iter iter, Index ind)
constexpr EnumerateIterator & operator-=(I diff)
constexpr EnumerateIterator & operator++()
constexpr bool operator<(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr EnumerateIterator()=default
constexpr EnumerateIterator(Iter iter)
constexpr bool operator!=(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr bool operator>(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr EnumerateIterator & operator--()
constexpr friend auto operator+(EnumerateIterator iter, I ind)
constexpr auto operator[](I diff) const
constexpr bool operator<=(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr EnumerateIterator & operator+=(I diff)
constexpr bool operator==(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr auto operator-(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr bool operator>=(const EnumerateIterator< OtherIter, OtherInd > &other) const
constexpr IteratorPair(Begin bIn, End eIn)
constexpr auto end() const
constexpr auto begin() const