17 #ifndef WPIUTIL_WPI_STLEXTRAS_H
18 #define WPIUTIL_WPI_STLEXTRAS_H
20 #include "wpi/SmallVector.h"
21 #include "wpi/iterator.h"
23 #include "wpi/ErrorHandling.h"
30 #include <initializer_list>
36 #include <type_traits>
47 template <
typename RangeT>
48 using IterOfRange = decltype(std::begin(std::declval<RangeT &>()));
50 template <
typename RangeT>
51 using ValueOfRange =
typename std::remove_reference<decltype(
52 *std::begin(std::declval<RangeT &>()))>::type;
62 typename std::add_pointer<typename std::add_const<T>::type>::type;
66 using type =
typename std::add_lvalue_reference<
67 typename std::add_const<T>::type>::type;
75 using argument_type = Ty;
77 Ty &operator()(Ty &
self)
const {
80 const Ty &operator()(
const Ty &
self)
const {
86 bool operator()(
const Ty* left,
const Ty* right)
const {
87 return *left < *right;
92 bool operator()(
const Ty* left,
const Ty* right)
const {
93 return *right < *left;
105 template<
typename Ret,
typename ...Params>
107 Ret (*callback)(intptr_t callable, Params ...params) =
nullptr;
110 template<
typename Callable>
111 static Ret callback_fn(intptr_t callable, Params ...params) {
112 return (*reinterpret_cast<Callable*>(callable))(
113 std::forward<Params>(params)...);
120 template <
typename Callable>
122 typename std::enable_if<
123 !std::is_same<
typename std::remove_reference<Callable>::type,
125 : callback(callback_fn<
typename std::remove_reference<Callable>::type>),
126 callable(reinterpret_cast<intptr_t>(&callable)) {}
128 Ret operator()(Params ...params)
const {
129 return callback(callable, std::forward<Params>(params)...);
132 explicit operator bool()
const {
return callback; }
140 inline void deleter(T *Ptr) {
148 namespace adl_detail {
152 template <
typename ContainerTy>
153 auto adl_begin(ContainerTy &&container)
154 -> decltype(begin(std::forward<ContainerTy>(container))) {
155 return begin(std::forward<ContainerTy>(container));
160 template <
typename ContainerTy>
161 auto adl_end(ContainerTy &&container)
162 -> decltype(end(std::forward<ContainerTy>(container))) {
163 return end(std::forward<ContainerTy>(container));
168 template <
typename T>
169 void adl_swap(T &&lhs, T &&rhs) noexcept(noexcept(swap(std::declval<T>(),
170 std::declval<T>()))) {
171 swap(std::forward<T>(lhs), std::forward<T>(rhs));
176 template <
typename ContainerTy>
177 auto adl_begin(ContainerTy &&container)
178 -> decltype(adl_detail::adl_begin(std::forward<ContainerTy>(container))) {
179 return adl_detail::adl_begin(std::forward<ContainerTy>(container));
182 template <
typename ContainerTy>
183 auto adl_end(ContainerTy &&container)
184 -> decltype(adl_detail::adl_end(std::forward<ContainerTy>(container))) {
185 return adl_detail::adl_end(std::forward<ContainerTy>(container));
188 template <
typename T>
189 void adl_swap(T &&lhs, T &&rhs) noexcept(
190 noexcept(adl_detail::adl_swap(std::declval<T>(), std::declval<T>()))) {
191 adl_detail::adl_swap(std::forward<T>(lhs), std::forward<T>(rhs));
195 template <
typename T>
196 constexpr
bool empty(
const T &RangeOrContainer) {
197 return adl_begin(RangeOrContainer) == adl_end(RangeOrContainer);
203 template <
typename ItTy,
typename FuncTy,
204 typename FuncReturnTy =
205 decltype(std::declval<FuncTy>()(*std::declval<ItTy>()))>
208 mapped_iterator<ItTy, FuncTy>, ItTy,
209 typename std::iterator_traits<ItTy>::iterator_category,
210 typename std::remove_reference<FuncReturnTy>::type> {
213 : mapped_iterator::iterator_adaptor_base(std::move(U)), F(std::move(F)) {}
215 ItTy getCurrent() {
return this->I; }
217 FuncReturnTy operator*() {
return F(*this->I); }
225 template <
class ItTy,
class FuncTy>
235 template <
typename Inner>
236 static yes& test(Inner *I, decltype(I->rbegin()) * =
nullptr);
239 static no& test(...);
242 static const bool value =
sizeof(test<Ty>(
nullptr)) ==
sizeof(yes);
246 template <
typename Ty>
252 template <
typename ContainerTy>
253 auto reverse(ContainerTy &&C,
255 nullptr) -> decltype(
make_range(C.rbegin(), C.rend())) {
260 template <
typename IteratorTy>
261 std::reverse_iterator<IteratorTy> make_reverse_iterator(IteratorTy It) {
262 return std::reverse_iterator<IteratorTy>(It);
268 template <
typename ContainerTy>
271 typename std::enable_if<!has_rbegin<ContainerTy>::value>::type * =
nullptr)
272 -> decltype(
make_range(wpi::make_reverse_iterator(std::end(C)),
273 wpi::make_reverse_iterator(std::begin(C)))) {
274 return make_range(wpi::make_reverse_iterator(std::end(C)),
275 wpi::make_reverse_iterator(std::begin(C)));
294 template <
typename WrappedIteratorT,
typename PredicateT,
typename IterTag>
297 filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>,
299 typename std::common_type<
300 IterTag, typename std::iterator_traits<
301 WrappedIteratorT>::iterator_category>::type> {
305 typename std::common_type<
306 IterTag,
typename std::iterator_traits<
307 WrappedIteratorT>::iterator_category>::type>;
310 WrappedIteratorT End;
313 void findNextValid() {
314 while (this->I != End && !Pred(*this->I))
323 :
BaseT(Begin), End(End), Pred(Pred) {
328 using BaseT::operator++;
338 template <
typename WrappedIteratorT,
typename PredicateT,
339 typename IterTag = std::forward_iterator_tag>
347 :
BaseT(Begin, End, Pred) {}
351 template <
typename WrappedIteratorT,
typename PredicateT>
353 std::bidirectional_iterator_tag>
355 std::bidirectional_iterator_tag> {
357 std::bidirectional_iterator_tag>;
358 void findPrevValid() {
359 while (!this->Pred(*this->I))
364 using BaseT::operator--;
368 :
BaseT(Begin, End, Pred) {}
380 using type = std::forward_iterator_tag;
384 using type = std::bidirectional_iterator_tag;
392 std::bidirectional_iterator_tag,
393 typename std::iterator_traits<IterT>::iterator_category>::value>::type;
400 template <
typename WrappedIteratorT,
typename PredicateT>
402 WrappedIteratorT, PredicateT,
403 typename detail::fwd_or_bidi_tag<WrappedIteratorT>::type>;
412 template <
typename RangeT,
typename PredicateT>
415 using FilterIteratorT =
418 FilterIteratorT(std::begin(std::forward<RangeT>(Range)),
419 std::end(std::forward<RangeT>(Range)), Pred),
420 FilterIteratorT(std::end(std::forward<RangeT>(Range)),
421 std::end(std::forward<RangeT>(Range)), Pred));
425 template <
typename R,
typename UnaryPredicate>
426 bool all_of(R &&range, UnaryPredicate P);
427 template <
typename R,
typename UnaryPredicate>
428 bool any_of(R &&range, UnaryPredicate P);
437 using type = std::tuple<decltype(*declval<Iters>())...>;
440 template <
typename ZipType,
typename... Iters>
442 ZipType,
typename std::common_type<std::bidirectional_iterator_tag,
443 typename std::iterator_traits<
444 Iters>::iterator_category...>::type,
447 typename std::iterator_traits<
typename std::tuple_element<
448 0, std::tuple<Iters...>>::type>::difference_type,
456 template <
typename ZipType,
typename... Iters>
459 using value_type =
typename Base::value_type;
461 std::tuple<Iters...> iterators;
464 template <
size_t... Ns> value_type
deref(std::index_sequence<Ns...>)
const {
465 return value_type(*std::get<Ns>(iterators)...);
468 template <
size_t... Ns>
469 decltype(iterators) tup_inc(std::index_sequence<Ns...>)
const {
470 return std::tuple<Iters...>(std::next(std::get<Ns>(iterators))...);
473 template <
size_t... Ns>
474 decltype(iterators) tup_dec(std::index_sequence<Ns...>)
const {
475 return std::tuple<Iters...>(std::prev(std::get<Ns>(iterators))...);
479 zip_common(Iters &&... ts) : iterators(std::forward<Iters>(ts)...) {}
481 value_type operator*() {
return deref(std::index_sequence_for<Iters...>{}); }
483 const value_type operator*()
const {
484 return deref(std::index_sequence_for<Iters...>{});
487 ZipType &operator++() {
488 iterators = tup_inc(std::index_sequence_for<Iters...>{});
489 return *reinterpret_cast<ZipType *>(
this);
492 ZipType &operator--() {
493 static_assert(Base::IsBidirectional,
494 "All inner iterators must be at least bidirectional.");
495 iterators = tup_dec(std::index_sequence_for<Iters...>{});
496 return *reinterpret_cast<ZipType *>(
this);
500 template <
typename... Iters>
505 return std::get<0>(this->iterators) == std::get<0>(other.iterators);
508 zip_first(Iters &&... ts) :
Base(std::forward<Iters>(ts)...) {}
511 template <
typename... Iters>
513 template <
size_t... Ns>
515 return all_of(std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
516 std::get<Ns>(other.iterators)...},
526 return !test(other, std::index_sequence_for<Iters...>{});
530 template <
template <
typename...>
class ItType,
typename... Args>
class zippy {
532 using iterator = ItType<decltype(std::begin(std::declval<Args>()))...>;
533 using iterator_category =
typename iterator::iterator_category;
534 using value_type =
typename iterator::value_type;
535 using difference_type =
typename iterator::difference_type;
536 using pointer =
typename iterator::pointer;
537 using reference =
typename iterator::reference;
540 std::tuple<Args...> ts;
542 template <
size_t... Ns> iterator begin_impl(std::index_sequence<Ns...>)
const {
543 return iterator(std::begin(std::get<Ns>(ts))...);
545 template <
size_t... Ns> iterator end_impl(std::index_sequence<Ns...>)
const {
546 return iterator(std::end(std::get<Ns>(ts))...);
550 zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
552 iterator begin()
const {
return begin_impl(std::index_sequence_for<Args...>{}); }
553 iterator end()
const {
return end_impl(std::index_sequence_for<Args...>{}); }
559 template <
typename T,
typename U,
typename... Args>
563 std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
568 template <
typename T,
typename U,
typename... Args>
572 std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
576 template <
typename Iter>
577 static Iter next_or_end(
const Iter &I,
const Iter &End) {
583 template <
typename Iter>
584 static auto deref_or_none(
const Iter &I,
const Iter &End)
585 -> std::optional<
typename std::remove_const<
586 typename std::remove_reference<decltype(*I)>::type>::type> {
594 std::optional<
typename std::remove_const<
typename std::remove_reference<
595 decltype(*std::declval<Iter>())>::type>::type>;
599 using type = std::tuple<typename ZipLongestItemType<Iters>::type...>;
602 template <
typename... Iters>
605 zip_longest_iterator<Iters...>,
606 typename std::common_type<
607 std::forward_iterator_tag,
608 typename std::iterator_traits<Iters>::iterator_category...>::type,
609 typename ZipLongestTupleType<Iters...>::type,
610 typename std::iterator_traits<typename std::tuple_element<
611 0, std::tuple<Iters...>>::type>::difference_type,
612 typename ZipLongestTupleType<Iters...>::type *,
613 typename ZipLongestTupleType<Iters...>::type> {
618 std::tuple<Iters...> iterators;
619 std::tuple<Iters...> end_iterators;
621 template <
size_t... Ns>
623 std::index_sequence<Ns...>)
const {
625 std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
626 std::get<Ns>(other.iterators)...},
630 template <
size_t... Ns> value_type
deref(std::index_sequence<Ns...>)
const {
632 deref_or_none(std::get<Ns>(iterators), std::get<Ns>(end_iterators))...);
635 template <
size_t... Ns>
636 decltype(iterators) tup_inc(std::index_sequence<Ns...>)
const {
637 return std::tuple<Iters...>(
638 next_or_end(std::get<Ns>(iterators), std::get<Ns>(end_iterators))...);
643 : iterators(std::forward<Iters>(ts.first)...),
644 end_iterators(std::forward<Iters>(ts.second)...) {}
646 value_type operator*() {
return deref(std::index_sequence_for<Iters...>{}); }
648 value_type operator*()
const {
return deref(std::index_sequence_for<Iters...>{}); }
651 iterators = tup_inc(std::index_sequence_for<Iters...>{});
656 return !test(other, std::index_sequence_for<Iters...>{});
664 using iterator_category =
typename iterator::iterator_category;
665 using value_type =
typename iterator::value_type;
666 using difference_type =
typename iterator::difference_type;
667 using pointer =
typename iterator::pointer;
668 using reference =
typename iterator::reference;
671 std::tuple<Args...> ts;
673 template <
size_t... Ns>
iterator begin_impl(std::index_sequence<Ns...>)
const {
674 return iterator(std::make_pair(adl_begin(std::get<Ns>(ts)),
675 adl_end(std::get<Ns>(ts)))...);
678 template <
size_t... Ns>
iterator end_impl(std::index_sequence<Ns...>)
const {
679 return iterator(std::make_pair(adl_end(std::get<Ns>(ts)),
680 adl_end(std::get<Ns>(ts)))...);
686 iterator begin()
const {
return begin_impl(std::index_sequence_for<Args...>{}); }
687 iterator end()
const {
return end_impl(std::index_sequence_for<Args...>{}); }
694 template <
typename T,
typename U,
typename... Args>
698 std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
711 template <
typename ValueT,
typename... IterTs>
714 std::forward_iterator_tag, ValueT> {
715 using BaseT =
typename concat_iterator::iterator_facade_base;
723 std::tuple<IterTs...> Begins;
724 std::tuple<IterTs...> Ends;
730 template <
size_t Index>
bool incrementHelper() {
731 auto &Begin = std::get<Index>(Begins);
732 auto &End = std::get<Index>(Ends);
743 template <
size_t... Ns>
void increment(std::index_sequence<Ns...>) {
746 &concat_iterator::incrementHelper<Ns>...};
749 for (
auto &IncrementHelperFn : IncrementHelperFns)
750 if ((this->*IncrementHelperFn)())
753 assert(
false &&
"Attempted to increment an end concat iterator!");
759 template <
size_t Index> ValueT *getHelper()
const {
760 auto &Begin = std::get<Index>(Begins);
761 auto &End = std::get<Index>(Ends);
772 template <
size_t... Ns> ValueT &get(std::index_sequence<Ns...>)
const {
775 &concat_iterator::getHelper<Ns>...};
778 for (
auto &GetHelperFn : GetHelperFns)
779 if (ValueT *P = (this->*GetHelperFn)())
782 assert(
false &&
"Attempted to get a pointer from an end concat iterator!");
790 template <
typename... RangeTs>
792 : Begins(std::begin(Ranges)...), Ends(std::end(Ranges)...) {}
794 using BaseT::operator++;
797 increment(std::index_sequence_for<IterTs...>());
801 ValueT &operator*()
const {
return get(std::index_sequence_for<IterTs...>()); }
804 return Begins == RHS.Begins && Ends == RHS.Ends;
819 decltype(std::begin(std::declval<RangeTs &>()))...>;
822 std::tuple<RangeTs...> Ranges;
824 template <
size_t... Ns>
iterator begin_impl(std::index_sequence<Ns...>) {
825 return iterator(std::get<Ns>(Ranges)...);
827 template <
size_t... Ns>
iterator end_impl(std::index_sequence<Ns...>) {
829 std::end(std::get<Ns>(Ranges)))...);
834 : Ranges(std::forward<RangeTs>(Ranges)...) {}
836 iterator begin() {
return begin_impl(std::index_sequence_for<RangeTs...>{}); }
837 iterator end() {
return end_impl(std::index_sequence_for<RangeTs...>{}); }
845 template <
typename ValueT,
typename... RangeTs>
847 static_assert(
sizeof...(RangeTs) > 1,
848 "Need more than one range to concatenate!");
850 std::forward<RangeTs>(Ranges)...);
860 template <
typename T>
bool operator()(
const T &lhs,
const T &rhs)
const {
861 return lhs.first < rhs.first;
868 template <
typename T>
bool operator()(
const T &lhs,
const T &rhs)
const {
869 return lhs.second < rhs.second;
875 template<
typename FuncTy>
879 template <
typename T>
880 auto operator()(
const T &lhs,
const T &rhs)
const
881 -> decltype(func(lhs.first, rhs.first)) {
882 return func(lhs.first, rhs.first);
893 template <
typename T,
typename... Ts>
struct is_one_of {
894 static const bool value =
false;
897 template <
typename T,
typename U,
typename... Ts>
899 static const bool value =
900 std::is_same<T, U>::value ||
is_one_of<T, Ts...>::value;
906 static const bool value =
true;
909 template <
typename T,
typename U,
typename... Ts>
911 static const bool value =
912 std::is_base_of<T, U>::value &&
are_base_of<T, Ts...>::value;
920 template <
class T, std::
size_t N>
928 if (std::less<T>()(*reinterpret_cast<const T*>(P1),
929 *reinterpret_cast<const T*>(P2)))
931 if (std::less<T>()(*reinterpret_cast<const T*>(P2),
932 *reinterpret_cast<const T*>(P1)))
941 (
const void*,
const void*) {
942 return array_pod_sort_comparator<T>;
959 template<
class IteratorTy>
963 auto NElts = End - Start;
964 if (NElts <= 1)
return;
968 template <
class IteratorTy>
970 IteratorTy Start, IteratorTy End,
972 const typename std::iterator_traits<IteratorTy>::value_type *,
973 const typename std::iterator_traits<IteratorTy>::value_type *)) {
976 auto NElts = End - Start;
977 if (NElts <= 1)
return;
978 qsort(&*Start, NElts,
sizeof(*Start),
979 reinterpret_cast<int (*)(
const void *,
const void *)
>(Compare));
988 template<
typename Container>
997 template<
typename Container>
1006 template <
typename R>
1007 auto size(R &&Range,
typename std::enable_if<
1008 std::is_same<
typename std::iterator_traits<decltype(
1009 Range.begin())>::iterator_category,
1010 std::random_access_iterator_tag>::value,
1011 void>::type * =
nullptr)
1012 -> decltype(std::distance(Range.begin(), Range.end())) {
1013 return std::distance(Range.begin(), Range.end());
1018 template <
typename R,
typename UnaryPredicate>
1020 return std::for_each(adl_begin(Range), adl_end(Range), P);
1025 template <
typename R,
typename UnaryPredicate>
1027 return std::all_of(adl_begin(Range), adl_end(Range), P);
1032 template <
typename R,
typename UnaryPredicate>
1034 return std::any_of(adl_begin(Range), adl_end(Range), P);
1039 template <
typename R,
typename UnaryPredicate>
1041 return std::none_of(adl_begin(Range), adl_end(Range), P);
1046 template <
typename R,
typename T>
1047 auto find(R &&Range,
const T &Val) -> decltype(adl_begin(Range)) {
1048 return std::find(adl_begin(Range), adl_end(Range), Val);
1053 template <
typename R,
typename UnaryPredicate>
1054 auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1055 return std::find_if(adl_begin(Range), adl_end(Range), P);
1058 template <
typename R,
typename UnaryPredicate>
1059 auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1060 return std::find_if_not(adl_begin(Range), adl_end(Range), P);
1065 template <
typename R,
typename UnaryPredicate>
1066 auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1067 return std::remove_if(adl_begin(Range), adl_end(Range), P);
1072 template <
typename R,
typename OutputIt,
typename UnaryPredicate>
1073 OutputIt
copy_if(R &&Range, OutputIt Out, UnaryPredicate P) {
1074 return std::copy_if(adl_begin(Range), adl_end(Range), Out, P);
1077 template <
typename R,
typename OutputIt>
1078 OutputIt copy(R &&Range, OutputIt Out) {
1079 return std::copy(adl_begin(Range), adl_end(Range), Out);
1084 template <
typename R,
typename E>
1086 return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range);
1091 template <
typename R,
typename E>
1092 auto count(R &&Range,
const E &Element) ->
1093 typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
1094 return std::count(adl_begin(Range), adl_end(Range), Element);
1099 template <
typename R,
typename UnaryPredicate>
1101 typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
1102 return std::count_if(adl_begin(Range), adl_end(Range), P);
1107 template <
typename R,
typename OutputIt,
typename UnaryPredicate>
1108 OutputIt
transform(R &&Range, OutputIt d_first, UnaryPredicate P) {
1109 return std::transform(adl_begin(Range), adl_end(Range), d_first, P);
1114 template <
typename R,
typename UnaryPredicate>
1115 auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1116 return std::partition(adl_begin(Range), adl_end(Range), P);
1121 template <
typename R,
typename ForwardIt>
1122 auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
1123 return std::lower_bound(adl_begin(Range), adl_end(Range), I);
1126 template <
typename R,
typename ForwardIt,
typename Compare>
1127 auto lower_bound(R &&Range, ForwardIt I, Compare C)
1128 -> decltype(adl_begin(Range)) {
1129 return std::lower_bound(adl_begin(Range), adl_end(Range), I, C);
1134 template <
typename R,
typename ForwardIt>
1135 auto upper_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
1136 return std::upper_bound(adl_begin(Range), adl_end(Range), I);
1139 template <
typename R,
typename ForwardIt,
typename Compare>
1140 auto upper_bound(R &&Range, ForwardIt I, Compare C)
1141 -> decltype(adl_begin(Range)) {
1142 return std::upper_bound(adl_begin(Range), adl_end(Range), I, C);
1146 template <
typename R>
1148 size_t range_size =
size(Range);
1149 return range_size != 0 && (range_size == 1 ||
1150 std::equal(adl_begin(Range) + 1, adl_end(Range), adl_begin(Range)));
1156 template <
unsigned Size,
typename R>
1157 SmallVector<typename std::remove_const<detail::ValueOfRange<R>>::type, Size>
1159 return {adl_begin(Range), adl_end(Range)};
1169 template <
typename Container,
typename UnaryPredicate>
1179 void operator()(
void* v) {
1184 template<
typename First,
typename Second>
1186 size_t operator()(
const std::pair<First, Second> &P)
const {
1187 return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
1199 template <
typename A,
typename B>
1200 auto operator()(A &lhs, B &rhs)
const -> decltype(func(*lhs, *rhs)) {
1203 return func(*lhs, *rhs);
1215 result_pair(std::size_t Index, IterOfRange<R> Iter)
1216 : Index(Index), Iter(Iter) {}
1219 Index = Other.Index;
1224 std::size_t index()
const {
return Index; }
1225 const ValueOfRange<R> &value()
const {
return *Iter; }
1226 ValueOfRange<R> &value() {
return *Iter; }
1229 std::size_t Index = (std::numeric_limits<std::size_t>::max)();
1230 IterOfRange<R> Iter;
1233 template <
typename R>
1236 enumerator_iter<R>, std::forward_iterator_tag, result_pair<R>,
1237 typename std::iterator_traits<IterOfRange<R>>::difference_type,
1238 typename std::iterator_traits<IterOfRange<R>>::pointer,
1239 typename std::iterator_traits<IterOfRange<R>>::reference> {
1244 : Result((std::numeric_limits<size_t>::max)(), EndIter) {}
1246 enumerator_iter(std::size_t Index, IterOfRange<R> Iter)
1247 : Result(Index, Iter) {}
1249 result_type &operator*() {
return Result; }
1250 const result_type &operator*()
const {
return Result; }
1252 enumerator_iter<R> &operator++() {
1253 assert(Result.Index != (std::numeric_limits<size_t>::max)());
1259 bool operator==(
const enumerator_iter<R> &RHS)
const {
1263 return Result.Iter == RHS.Result.Iter;
1266 enumerator_iter<R> &operator=(
const enumerator_iter<R> &Other) {
1267 Result = Other.Result;
1277 explicit enumerator(R &&Range) : TheRange(std::forward<R>(Range)) {}
1314 template <
typename IterTy>
1316 IterTy &&Begin, IterTy &&End,
unsigned N,
1317 typename std::enable_if<
1319 typename std::iterator_traits<
typename std::remove_reference<
1320 decltype(Begin)>::type>::iterator_category,
1321 std::random_access_iterator_tag>::value,
1322 void>::type * =
nullptr) {
1323 for (; N; --N, ++Begin)
1326 return Begin == End;
1331 template <
typename IterTy>
1333 IterTy &&Begin, IterTy &&End,
unsigned N,
1334 typename std::enable_if<
1336 typename std::iterator_traits<
typename std::remove_reference<
1337 decltype(Begin)>::type>::iterator_category,
1338 std::random_access_iterator_tag>::value,
1339 void>::type * =
nullptr) {
1340 for (; N; --N, ++Begin)
1348 #endif // LLVM_ADT_STLEXTRAS_H