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/optional.h"
30 #include <initializer_list>
35 #include <type_traits>
46 template <
typename RangeT>
47 using IterOfRange = decltype(std::begin(std::declval<RangeT &>()));
49 template <
typename RangeT>
50 using ValueOfRange =
typename std::remove_reference<decltype(
51 *std::begin(std::declval<RangeT &>()))>::type;
60 using argument_type = Ty;
62 Ty &operator()(Ty &
self)
const {
65 const Ty &operator()(
const Ty &
self)
const {
71 bool operator()(
const Ty* left,
const Ty* right)
const {
72 return *left < *right;
77 bool operator()(
const Ty* left,
const Ty* right)
const {
78 return *right < *left;
90 template<
typename Ret,
typename ...Params>
92 Ret (*callback)(intptr_t callable, Params ...params) =
nullptr;
95 template<
typename Callable>
96 static Ret callback_fn(intptr_t callable, Params ...params) {
97 return (*reinterpret_cast<Callable*>(callable))(
98 std::forward<Params>(params)...);
105 template <
typename Callable>
107 typename std::enable_if<
108 !std::is_same<
typename std::remove_reference<Callable>::type,
110 : callback(callback_fn<
typename std::remove_reference<Callable>::type>),
111 callable(reinterpret_cast<intptr_t>(&callable)) {}
113 Ret operator()(Params ...params)
const {
114 return callback(callable, std::forward<Params>(params)...);
117 explicit operator bool()
const {
return callback; }
125 inline void deleter(T *Ptr) {
133 namespace adl_detail {
137 template <
typename ContainerTy>
138 auto adl_begin(ContainerTy &&container)
139 -> decltype(begin(std::forward<ContainerTy>(container))) {
140 return begin(std::forward<ContainerTy>(container));
145 template <
typename ContainerTy>
146 auto adl_end(ContainerTy &&container)
147 -> decltype(end(std::forward<ContainerTy>(container))) {
148 return end(std::forward<ContainerTy>(container));
153 template <
typename T>
154 void adl_swap(T &&lhs, T &&rhs) noexcept(noexcept(swap(
std::declval<T>(),
155 std::declval<T>()))) {
156 swap(std::forward<T>(lhs), std::forward<T>(rhs));
161 template <
typename ContainerTy>
162 auto adl_begin(ContainerTy &&container)
163 -> decltype(adl_detail::adl_begin(std::forward<ContainerTy>(container))) {
164 return adl_detail::adl_begin(std::forward<ContainerTy>(container));
167 template <
typename ContainerTy>
168 auto adl_end(ContainerTy &&container)
169 -> decltype(adl_detail::adl_end(std::forward<ContainerTy>(container))) {
170 return adl_detail::adl_end(std::forward<ContainerTy>(container));
173 template <
typename T>
174 void adl_swap(T &&lhs, T &&rhs) noexcept(
175 noexcept(adl_detail::adl_swap(
std::declval<T>(),
std::declval<T>()))) {
176 adl_detail::adl_swap(std::forward<T>(lhs), std::forward<T>(rhs));
182 template <
typename ItTy,
typename FuncTy,
183 typename FuncReturnTy =
184 decltype(std::declval<FuncTy>()(*std::declval<ItTy>()))>
187 mapped_iterator<ItTy, FuncTy>, ItTy,
188 typename std::iterator_traits<ItTy>::iterator_category,
189 typename std::remove_reference<FuncReturnTy>::type> {
192 : mapped_iterator::iterator_adaptor_base(std::move(U)), F(std::move(F)) {}
194 ItTy getCurrent() {
return this->I; }
196 FuncReturnTy operator*() {
return F(*this->I); }
204 template <
class ItTy,
class FuncTy>
214 template <
typename Inner>
215 static yes& test(Inner *I, decltype(I->rbegin()) * =
nullptr);
218 static no& test(...);
221 static const bool value =
sizeof(test<Ty>(
nullptr)) ==
sizeof(yes);
225 template <
typename Ty>
231 template <
typename ContainerTy>
232 auto reverse(ContainerTy &&C,
234 nullptr) -> decltype(
make_range(C.rbegin(), C.rend())) {
239 template <
typename IteratorTy>
240 std::reverse_iterator<IteratorTy> make_reverse_iterator(IteratorTy It) {
241 return std::reverse_iterator<IteratorTy>(It);
247 template <
typename ContainerTy>
250 typename std::enable_if<!has_rbegin<ContainerTy>::value>::type * =
nullptr)
251 -> decltype(
make_range(wpi::make_reverse_iterator(std::end(C)),
252 wpi::make_reverse_iterator(std::begin(C)))) {
253 return make_range(wpi::make_reverse_iterator(std::end(C)),
254 wpi::make_reverse_iterator(std::begin(C)));
273 template <
typename WrappedIteratorT,
typename PredicateT,
typename IterTag>
276 filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>,
278 typename std::common_type<
279 IterTag, typename std::iterator_traits<
280 WrappedIteratorT>::iterator_category>::type> {
284 typename std::common_type<
285 IterTag,
typename std::iterator_traits<
286 WrappedIteratorT>::iterator_category>::type>;
289 WrappedIteratorT End;
292 void findNextValid() {
293 while (this->I != End && !Pred(*this->I))
302 :
BaseT(Begin), End(End), Pred(Pred) {
307 using BaseT::operator++;
317 template <
typename WrappedIteratorT,
typename PredicateT,
318 typename IterTag = std::forward_iterator_tag>
326 :
BaseT(Begin, End, Pred) {}
330 template <
typename WrappedIteratorT,
typename PredicateT>
332 std::bidirectional_iterator_tag>
334 std::bidirectional_iterator_tag> {
336 std::bidirectional_iterator_tag>;
337 void findPrevValid() {
338 while (!this->Pred(*this->I))
343 using BaseT::operator--;
347 : BaseT(Begin, End, Pred) {}
359 using type = std::forward_iterator_tag;
363 using type = std::bidirectional_iterator_tag;
371 std::bidirectional_iterator_tag,
372 typename std::iterator_traits<IterT>::iterator_category>::value>::type;
379 template <
typename WrappedIteratorT,
typename PredicateT>
381 WrappedIteratorT, PredicateT,
382 typename detail::fwd_or_bidi_tag<WrappedIteratorT>::type>;
391 template <
typename RangeT,
typename PredicateT>
394 using FilterIteratorT =
397 FilterIteratorT(std::begin(std::forward<RangeT>(Range)),
398 std::end(std::forward<RangeT>(Range)), Pred),
399 FilterIteratorT(std::end(std::forward<RangeT>(Range)),
400 std::end(std::forward<RangeT>(Range)), Pred));
404 template <
typename R,
typename UnaryPredicate>
405 bool all_of(R &&range, UnaryPredicate P);
418 using type = std::tuple<decltype(*declval<Iters>())...>;
421 template <
typename ZipType,
typename... Iters>
423 ZipType,
typename std::common_type<std::bidirectional_iterator_tag,
424 typename std::iterator_traits<
425 Iters>::iterator_category...>::type,
428 typename std::iterator_traits<
typename std::tuple_element<
429 0, std::tuple<Iters...>>::type>::difference_type,
437 template <
typename ZipType,
typename... Iters>
439 using Base = zip_traits<ZipType, Iters...>;
440 using value_type =
typename Base::value_type;
442 std::tuple<Iters...> iterators;
446 return value_type(*std::get<Ns>(iterators)...);
449 template <
size_t... Ns>
451 return std::tuple<Iters...>(std::next(std::get<Ns>(iterators))...);
454 template <
size_t... Ns>
456 return std::tuple<Iters...>(std::prev(std::get<Ns>(iterators))...);
460 zip_common(Iters &&... ts) : iterators(std::forward<Iters>(ts)...) {}
464 const value_type operator*()
const {
468 ZipType &operator++() {
470 return *
reinterpret_cast<ZipType *
>(
this);
473 ZipType &operator--() {
474 static_assert(Base::IsBidirectional,
475 "All inner iterators must be at least bidirectional.");
477 return *
reinterpret_cast<ZipType *
>(
this);
481 template <
typename... Iters>
486 return std::get<0>(this->iterators) == std::get<0>(other.iterators);
489 zip_first(Iters &&... ts) :
Base(std::forward<Iters>(ts)...) {}
492 template <
typename... Iters>
494 template <
size_t... Ns>
496 return all_of(std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
497 std::get<Ns>(other.iterators)...},
511 template <
template <
typename...>
class ItType,
typename... Args>
class zippy {
513 using iterator = ItType<decltype(std::begin(std::declval<Args>()))...>;
514 using iterator_category =
typename iterator::iterator_category;
515 using value_type =
typename iterator::value_type;
516 using difference_type =
typename iterator::difference_type;
517 using pointer =
typename iterator::pointer;
518 using reference =
typename iterator::reference;
521 std::tuple<Args...> ts;
524 return iterator(std::begin(std::get<Ns>(ts))...);
527 return iterator(std::end(std::get<Ns>(ts))...);
531 zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
540 template <
typename T,
typename U,
typename... Args>
544 std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
549 template <
typename T,
typename U,
typename... Args>
553 std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
566 template <
typename ValueT,
typename... IterTs>
569 std::forward_iterator_tag, ValueT> {
570 using BaseT =
typename concat_iterator::iterator_facade_base;
578 std::tuple<std::pair<IterTs, IterTs>...> IterPairs;
584 template <
size_t Index>
bool incrementHelper() {
585 auto &IterPair = std::get<Index>(IterPairs);
586 if (IterPair.first == IterPair.second)
599 &concat_iterator::incrementHelper<Ns>...};
602 for (
auto &IncrementHelperFn : IncrementHelperFns)
603 if ((this->*IncrementHelperFn)())
606 assert(
false &&
"Attempted to increment an end concat iterator!");
612 template <
size_t Index> ValueT *getHelper()
const {
613 auto &IterPair = std::get<Index>(IterPairs);
614 if (IterPair.first == IterPair.second)
617 return &*IterPair.first;
624 template <
size_t... Ns> ValueT &
get(
index_sequence<Ns...>)
const {
627 &concat_iterator::getHelper<Ns>...};
630 for (
auto &GetHelperFn : GetHelperFns)
631 if (ValueT *P = (this->*GetHelperFn)())
634 assert(
false &&
"Attempted to get a pointer from an end concat iterator!");
642 template <
typename... RangeTs>
644 : IterPairs({std::begin(Ranges), std::end(Ranges)}...) {}
646 using BaseT::operator++;
649 increment(index_sequence_for<IterTs...>());
653 ValueT &operator*()
const {
return get(index_sequence_for<IterTs...>()); }
656 return IterPairs == RHS.IterPairs;
671 decltype(std::begin(std::declval<RangeTs &>()))...>;
674 std::tuple<RangeTs...> Ranges;
677 return iterator(std::get<Ns>(Ranges)...);
681 std::end(std::get<Ns>(Ranges)))...);
686 : Ranges(std::forward<RangeTs>(Ranges)...) {}
697 template <
typename ValueT,
typename... RangeTs>
699 static_assert(
sizeof...(RangeTs) > 1,
700 "Need more than one range to concatenate!");
702 std::forward<RangeTs>(Ranges)...);
712 template <
typename T>
bool operator()(
const T &lhs,
const T &rhs)
const {
713 return lhs.first < rhs.first;
720 template <
typename T>
bool operator()(
const T &lhs,
const T &rhs)
const {
721 return lhs.second < rhs.second;
729 using value_type = T;
731 static constexpr
size_t size() {
return sizeof...(I); }
735 template <
size_t... I>
738 template <std::size_t N, std::size_t... I>
740 template <std::size_t... I>
744 template <
class... Ts>
754 template <
typename T,
typename... Ts>
struct is_one_of {
755 static const bool value =
false;
758 template <
typename T,
typename U,
typename... Ts>
760 static const bool value =
761 std::is_same<T, U>::value ||
is_one_of<T, Ts...>::value;
767 static const bool value =
true;
770 template <
typename T,
typename U,
typename... Ts>
772 static const bool value =
773 std::is_base_of<T, U>::value &&
are_base_of<T, Ts...>::value;
781 template <
class T, std::
size_t N>
789 if (std::less<T>()(*reinterpret_cast<const T*>(P1),
790 *reinterpret_cast<const T*>(P2)))
792 if (std::less<T>()(*reinterpret_cast<const T*>(P2),
793 *reinterpret_cast<const T*>(P1)))
802 (
const void*,
const void*) {
803 return array_pod_sort_comparator<T>;
820 template<
class IteratorTy>
824 auto NElts = End - Start;
825 if (NElts <= 1)
return;
829 template <
class IteratorTy>
831 IteratorTy Start, IteratorTy End,
833 const typename std::iterator_traits<IteratorTy>::value_type *,
834 const typename std::iterator_traits<IteratorTy>::value_type *)) {
837 auto NElts = End - Start;
838 if (NElts <= 1)
return;
839 qsort(&*Start, NElts,
sizeof(*Start),
840 reinterpret_cast<int (*)(
const void *,
const void *)
>(Compare));
849 template<
typename Container>
858 template<
typename Container>
867 template <
typename R,
typename UnaryPredicate>
868 UnaryPredicate
for_each(R &&Range, UnaryPredicate P) {
869 return std::for_each(adl_begin(Range), adl_end(Range), P);
874 template <
typename R,
typename UnaryPredicate>
875 bool all_of(R &&Range, UnaryPredicate P) {
876 return std::all_of(adl_begin(Range), adl_end(Range), P);
881 template <
typename R,
typename UnaryPredicate>
882 bool any_of(R &&Range, UnaryPredicate P) {
883 return std::any_of(adl_begin(Range), adl_end(Range), P);
888 template <
typename R,
typename UnaryPredicate>
890 return std::none_of(adl_begin(Range), adl_end(Range), P);
895 template <
typename R,
typename T>
896 auto find(R &&Range,
const T &Val) -> decltype(adl_begin(Range)) {
897 return std::find(adl_begin(Range), adl_end(Range), Val);
902 template <
typename R,
typename UnaryPredicate>
903 auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
904 return std::find_if(adl_begin(Range), adl_end(Range), P);
907 template <
typename R,
typename UnaryPredicate>
908 auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
909 return std::find_if_not(adl_begin(Range), adl_end(Range), P);
914 template <
typename R,
typename UnaryPredicate>
915 auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
916 return std::remove_if(adl_begin(Range), adl_end(Range), P);
921 template <
typename R,
typename OutputIt,
typename UnaryPredicate>
922 OutputIt
copy_if(R &&Range, OutputIt Out, UnaryPredicate P) {
923 return std::copy_if(adl_begin(Range), adl_end(Range), Out, P);
926 template <
typename R,
typename OutputIt>
927 OutputIt copy(R &&Range, OutputIt Out) {
928 return std::copy(adl_begin(Range), adl_end(Range), Out);
933 template <
typename R,
typename E>
935 return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range);
940 template <
typename R,
typename E>
941 auto count(R &&Range,
const E &Element) ->
942 typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
943 return std::count(adl_begin(Range), adl_end(Range), Element);
948 template <
typename R,
typename UnaryPredicate>
950 typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
951 return std::count_if(adl_begin(Range), adl_end(Range), P);
956 template <
typename R,
typename OutputIt,
typename UnaryPredicate>
957 OutputIt
transform(R &&Range, OutputIt d_first, UnaryPredicate P) {
958 return std::transform(adl_begin(Range), adl_end(Range), d_first, P);
963 template <
typename R,
typename UnaryPredicate>
964 auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
965 return std::partition(adl_begin(Range), adl_end(Range), P);
970 template <
typename R,
typename ForwardIt>
971 auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
972 return std::lower_bound(adl_begin(Range), adl_end(Range), I);
978 template <
unsigned Size,
typename R>
979 SmallVector<typename std::remove_const<detail::ValueOfRange<R>>::type, Size>
981 return {adl_begin(Range), adl_end(Range)};
991 template <
typename Container,
typename UnaryPredicate>
998 template <
typename R>
999 auto size(R &&Range,
typename std::enable_if<
1000 std::is_same<
typename std::iterator_traits<decltype(
1001 Range.begin())>::iterator_category,
1002 std::random_access_iterator_tag>::value,
1003 void>::type * =
nullptr)
1004 -> decltype(std::distance(Range.begin(), Range.end())) {
1005 return std::distance(Range.begin(), Range.end());
1021 template <
class T,
class... Args>
1022 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
1024 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
1036 typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
1037 std::unique_ptr<T>>::type
1039 return std::unique_ptr<T>(
new typename std::remove_extent<T>::type[n]());
1043 template <
class T,
class... Args>
1044 typename std::enable_if<std::extent<T>::value != 0>::type
1048 void operator()(
void* v) {
1053 template<
typename First,
typename Second>
1055 size_t operator()(
const std::pair<First, Second> &P)
const {
1056 return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
1062 template <
typename A,
typename B>
bool operator()(A &&a, B &&b)
const {
1063 return std::forward<A>(a) < std::forward<B>(b);
1069 template <
typename A,
typename B>
bool operator()(A &&a, B &&b)
const {
1070 return std::forward<A>(a) == std::forward<B>(b);
1082 template <
typename A,
typename B>
1083 auto operator()(A &lhs, B &rhs)
const -> decltype(func(*lhs, *rhs)) {
1086 return func(*lhs, *rhs);
1098 result_pair(std::size_t Index, IterOfRange<R> Iter)
1099 : Index(Index), Iter(Iter) {}
1102 Index = Other.Index;
1107 std::size_t index()
const {
return Index; }
1108 const ValueOfRange<R> &value()
const {
return *Iter; }
1109 ValueOfRange<R> &value() {
return *Iter; }
1112 std::size_t Index = std::numeric_limits<std::size_t>::max();
1113 IterOfRange<R> Iter;
1116 template <
typename R>
1119 enumerator_iter<R>, std::forward_iterator_tag, result_pair<R>,
1120 typename std::iterator_traits<IterOfRange<R>>::difference_type,
1121 typename std::iterator_traits<IterOfRange<R>>::pointer,
1122 typename std::iterator_traits<IterOfRange<R>>::reference> {
1127 : Result(
std::numeric_limits<size_t>::max(), EndIter) {}
1129 enumerator_iter(std::size_t Index, IterOfRange<R> Iter)
1130 : Result(Index, Iter) {}
1132 result_type &operator*() {
return Result; }
1133 const result_type &operator*()
const {
return Result; }
1135 enumerator_iter<R> &operator++() {
1136 assert(Result.Index != std::numeric_limits<size_t>::max());
1142 bool operator==(
const enumerator_iter<R> &RHS)
const {
1146 return Result.Iter == RHS.Result.Iter;
1149 enumerator_iter<R> &operator=(
const enumerator_iter<R> &Other) {
1150 Result = Other.Result;
1160 explicit enumerator(R &&Range) : TheRange(std::forward<R>(Range)) {}
1197 template <
typename F,
typename Tuple, std::size_t... I>
1198 auto apply_tuple_impl(F &&f, Tuple &&t, index_sequence<I...>)
1199 -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...)) {
1200 return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
1208 template <
typename F,
typename Tuple>
1209 auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl(
1210 std::forward<F>(f), std::forward<Tuple>(t),
1212 std::tuple_size<
typename std::decay<Tuple>::type>::value>{})) {
1213 using Indices = build_index_impl<
1214 std::tuple_size<typename std::decay<Tuple>::type>::value>;
1216 return detail::apply_tuple_impl(std::forward<F>(f), std::forward<Tuple>(t),
1222 #endif // LLVM_ADT_STLEXTRAS_H
Helper to store a sequence of ranges being concatenated and access them.
Definition: STLExtras.h:667
Definition: STLExtras.h:482
Function object to check whether the first component of a std::pair compares less than the first comp...
Definition: STLExtras.h:711
detail::enumerator< R > enumerate(R &&TheRange)
Given an input range, returns a new range whose values are are pair (A,B) such that A is the 0-based ...
Definition: STLExtras.h:1191
A functor like C++14's std::less in its absence.
Definition: STLExtras.h:1061
Metafunction to determine if T& or T has a member called rbegin().
Definition: STLExtras.h:226
Definition: STLExtras.h:42
auto count_if(R &&Range, UnaryPredicate P) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition: STLExtras.h:949
OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere...
Definition: STLExtras.h:957
An iterator adaptor that filters the elements of given inner iterators.
Definition: STLExtras.h:274
Definition: STLExtras.h:493
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
int array_pod_sort_comparator(const void *P1, const void *P2)
Adapt std::less for array_pod_sort.
Definition: STLExtras.h:788
Definition: STLExtras.h:438
Iterator wrapper that concatenates sequences together.
Definition: STLExtras.h:567
Definition: optional.h:885
Utility type to build an inheritance chain that makes it easy to rank overload candidates.
Definition: STLExtras.h:749
Alias for the common case of a sequence of size_ts.
Definition: STLExtras.h:407
SmallVector< typename std::remove_const< detail::ValueOfRange< R > >::type, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
Definition: STLExtras.h:980
Specialization of filter_iterator_base for forward iteration only.
Definition: STLExtras.h:319
Definition: STLExtras.h:185
auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::partition which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:964
detail::zippy< detail::zip_first, T, U, Args...> zip_first(T &&t, U &&u, Args &&...args)
zip iterator that, for the sake of efficiency, assumes the first iteratee to be the shortest...
Definition: STLExtras.h:550
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:903
WPILib C++ utilities (wpiutil) namespace.
Definition: SmallString.h:21
auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range))
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:971
Definition: STLExtras.h:511
CRTP base class for adapting an iterator to a different type.
Definition: iterator.h:208
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition: iterator.h:68
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:88
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition: STLExtras.h:393
Function object to check whether the second component of a std::pair compares less than the second co...
Definition: STLExtras.h:719
Creates a compile-time integer sequence for a parameter pack.
Definition: STLExtras.h:409
concat_iterator(RangeTs &&...Ranges)
Constructs an iterator from a squence of ranges.
Definition: STLExtras.h:643
Definition: STLExtras.h:417
A range adaptor for a pair of iterators.
Definition: iterator_range.h:32
void DeleteContainerSeconds(Container &C)
In a container of pairs (usually a map) whose second element is a pointer, deletes the second element...
Definition: STLExtras.h:859
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:896
auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl(std::forward< F >(f), std::forward< Tuple >(t), build_index_impl< std::tuple_size< typename std::decay< Tuple >::type >::value >
Given an input tuple (a1, a2, ..., an), pass the arguments of the tuple variadically to f as if by ca...
Definition: STLExtras.h:1209
void DeleteContainerPointers(Container &C)
For a container of pointers, deletes the pointers and then clears the container.
Definition: STLExtras.h:850
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&...args)
Constructs a new T() with the given args and returns a unique_ptr which owns the object...
Definition: STLExtras.h:1023
Definition: STLExtras.h:358
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:889
detail::zippy< detail::zip_shortest, T, U, Args...> zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
Definition: STLExtras.h:541
Definition: STLExtras.h:1094
Definition: STLExtras.h:1092
int(*)(const void *, const void *) get_array_pod_sort_comparator(const T &)
get_array_pod_sort_comparator - This is an internal helper function used to get type deduction of T r...
Definition: STLExtras.h:801
Definition: STLExtras.h:739
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:882
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:54
Definition: STLExtras.h:70
Definition: STLExtras.h:59
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:875
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:999
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
Definition: STLExtras.h:821
Definition: STLExtras.h:1047
Represents a compile-time sequence of integers.
Definition: STLExtras.h:728
Definition: STLExtras.h:76
Definition: STLExtras.h:1158
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:941
traits class for checking whether type T is one of any of the given types in the variadic list...
Definition: STLExtras.h:754
OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)
Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:922
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:782
Definition: STLExtras.h:1054
A functor like C++14's std::equal in its absence.
Definition: STLExtras.h:1068
Helper to determine if type T has a member called rbegin().
Definition: STLExtras.h:210
traits class for checking whether type T is a base class for all the given types in the variadic list...
Definition: STLExtras.h:766
Binary functor that adapts to any other binary functor after dereferencing operands.
Definition: STLExtras.h:1076
UnaryPredicate for_each(R &&Range, UnaryPredicate P)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:868
Helper which sets its type member to forward_iterator_tag if the category of IterT does not derive fr...
Definition: STLExtras.h:369
detail::concat_range< ValueT, RangeTs...> concat(RangeTs &&...Ranges)
Concatenated range across two or more ranges.
Definition: STLExtras.h:698
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:934
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:915
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:992