17 #ifndef LLVM_ADT_STLEXTRAS_H
18 #define LLVM_ADT_STLEXTRAS_H
44 template <
typename RangeT>
54 struct identity :
public std::unary_function<Ty, Ty> {
64 struct less_ptr :
public std::binary_function<Ty, Ty, bool> {
66 return *left < *right;
71 struct greater_ptr :
public std::binary_function<Ty, Ty, bool> {
73 return *right < *left;
85 template<
typename Ret,
typename ...Params>
87 Ret (*callback)(
intptr_t callable, Params ...params);
90 template<
typename Callable>
91 static Ret callback_fn(
intptr_t callable, Params ...params) {
92 return (*reinterpret_cast<Callable*>(callable))(
93 std::forward<Params>(params)...);
97 template <
typename Callable>
99 typename std::enable_if<
100 !std::is_same<
typename std::remove_reference<Callable>::type,
102 : callback(callback_fn<typename std::remove_reference<Callable>::type>),
103 callable(reinterpret_cast<
intptr_t>(&callable)) {}
105 return callback(callable, std::forward<Params>(params)...);
128 template <
class RootIt,
class UnaryFunc>
133 typedef typename std::iterator_traits<RootIt>::iterator_category
135 typedef typename std::iterator_traits<RootIt>::difference_type
137 typedef typename std::result_of<
138 UnaryFunc(decltype(*std::declval<RootIt>()))>
148 inline const UnaryFunc &
getFunc()
const {
return Fn; }
151 : current(I), Fn(F) {}
193 return current == X.current;
198 return current - X.current;
202 template <
class Iterator,
class Func>
203 inline mapped_iterator<Iterator, Func>
213 template <
class ItTy,
class FuncTy>
223 template <
typename Inner>
224 static yes& test(Inner *
I, decltype(I->rbegin()) * =
nullptr);
227 static no& test(...);
230 static const bool value =
sizeof(test<Ty>(
nullptr)) ==
sizeof(yes);
234 template <
typename Ty>
240 template <
typename ContainerTy>
243 nullptr) -> decltype(
make_range(
C.rbegin(),
C.rend())) {
248 template <
typename IteratorTy>
250 return std::reverse_iterator<IteratorTy>(It);
256 template <
typename ContainerTy>
278 template <
typename WrappedIteratorT,
typename PredicateT>
281 filter_iterator<WrappedIteratorT, PredicateT>, WrappedIteratorT,
282 typename std::common_type<
283 std::forward_iterator_tag,
284 typename std::iterator_traits<
285 WrappedIteratorT>::iterator_category>::type> {
288 typename std::common_type<
289 std::forward_iterator_tag,
290 typename std::iterator_traits<WrappedIteratorT>::iterator_category>::
294 WrappedIteratorT
End;
300 void findNextValid() {
301 assert(Payload &&
"Payload should be engaged when findNextValid is called");
302 while (this->
I != Payload->End && !Payload->Pred(*this->I))
309 :
BaseT(std::move(Begin)),
310 Payload(PayloadType{std::move(End), std::move(Pred)}) {
319 using BaseT::operator++;
327 template <
typename RT,
typename PT>
339 template <
typename RangeT,
typename PredicateT>
340 iterator_range<filter_iterator<detail::IterOfRange<RangeT>, PredicateT>>
342 using FilterIteratorT =
345 std::end(std::forward<RangeT>(Range)),
347 FilterIteratorT(
std::end(std::forward<RangeT>(Range))));
351 template <
typename R,
typename UnaryPredicate>
352 bool all_of(R &&range, UnaryPredicate
P);
362 typedef std::tuple<decltype(*std::declval<Iters>())...>
value_type;
371 return std::tuple<Iters...>(std::next(std::get<Ns>(
iterators))...);
386 template <
size_t... Ns>
388 return all_of(std::initializer_list<bool>{std::get<Ns>(this->
iterators) !=
398 :
zip_first<Iters...>(std::forward<Iters>(ts)...) {}
401 template <
template <
typename...>
class ItType,
typename...
Args>
class zippy {
403 typedef ItType<decltype(std::begin(std::declval<Args>()))...>
iterator;
406 std::tuple<
Args...> ts;
423 template <
typename T,
typename U,
typename...
Args>
427 std::forward<T>(
t), std::forward<U>(u), std::forward<Args>(args)...);
432 template <
typename T,
typename U,
typename...
Args>
436 std::forward<T>(
t), std::forward<U>(u), std::forward<Args>(args)...);
449 template <
typename ValueT,
typename... IterTs>
452 std::forward_iterator_tag, ValueT> {
453 typedef typename concat_iterator::iterator_facade_base BaseT;
461 std::tuple<std::pair<IterTs, IterTs>...> IterPairs;
467 template <
size_t Index>
bool incrementHelper() {
468 auto &IterPair = std::get<Index>(IterPairs);
469 if (IterPair.first == IterPair.second)
482 &concat_iterator::incrementHelper<Ns>...};
485 for (
auto &IncrementHelperFn : IncrementHelperFns)
486 if ((this->*IncrementHelperFn)())
495 template <
size_t Index>
ValueT *getHelper()
const {
496 auto &IterPair = std::get<Index>(IterPairs);
497 if (IterPair.first == IterPair.second)
500 return &*IterPair.first;
510 &concat_iterator::getHelper<Ns>...};
513 for (
auto &GetHelperFn : GetHelperFns)
514 if (
ValueT *
P = (this->*GetHelperFn)())
517 llvm_unreachable(
"Attempted to get a pointer from an end concat iterator!");
525 template <
typename... RangeTs>
529 using BaseT::operator++;
538 return IterPairs == RHS.IterPairs;
551 decltype(
std::begin(std::declval<RangeTs &>()))...>
555 std::tuple<RangeTs...> Ranges;
558 return iterator(std::get<Ns>(Ranges)...);
562 std::end(std::get<Ns>(Ranges)))...);
569 : Ranges(std::forward<RangeTs>(Ranges)...) {}
576 template <
typename ValueT,
typename... RangeTs>
578 static_assert(
sizeof...(RangeTs) > 1,
579 "Need more than one range to concatenate!");
581 std::forward<RangeTs>(Ranges)...);
591 template <
typename T>
bool operator()(
const T &lhs,
const T &rhs)
const {
592 return lhs.first < rhs.first;
599 template <
typename T>
bool operator()(
const T &lhs,
const T &rhs)
const {
600 return lhs.second < rhs.second;
610 static constexpr
size_t size() {
return sizeof...(I); }
614 template <
size_t...
I>
615 struct index_sequence : integer_sequence<std::size_t, I...> {};
617 template <std::size_t
N, std::size_t...
I>
619 template <std::size_t...
I>
623 template <
class... Ts>
637 template <
typename T,
typename U,
typename... Ts>
648 template <
class T, std::
size_t N>
656 if (std::less<T>()(*reinterpret_cast<const T*>(P1),
657 *reinterpret_cast<const T*>(P2)))
659 if (std::less<T>()(*reinterpret_cast<const T*>(P2),
660 *reinterpret_cast<const T*>(P1)))
669 (
const void*,
const void*) {
670 return array_pod_sort_comparator<T>;
688 template<
class IteratorTy>
692 auto NElts = End - Start;
693 if (NElts <= 1)
return;
697 template <
class IteratorTy>
699 IteratorTy Start, IteratorTy
End,
701 const typename std::iterator_traits<IteratorTy>::value_type *,
702 const typename std::iterator_traits<IteratorTy>::value_type *)) {
705 auto NElts = End - Start;
706 if (NElts <= 1)
return;
707 qsort(&*Start, NElts,
sizeof(*Start),
708 reinterpret_cast<int (*)(
const void *,
const void *)
>(
Compare));
717 template<
typename Container>
726 template<
typename Container>
735 template <
typename R,
typename UnaryPredicate>
742 template <
typename R,
typename UnaryPredicate>
749 template <
typename R,
typename UnaryPredicate>
756 template <
typename R,
typename T>
763 template <
typename R,
typename UnaryPredicate>
768 template <
typename R,
typename UnaryPredicate>
775 template <
typename R,
typename UnaryPredicate>
782 template <
typename R,
typename E>
790 template <
typename R,
typename E>
791 auto count(R &&Range,
const E &Element) ->
typename std::iterator_traits<
792 decltype(
std::begin(Range))>::difference_type {
798 template <
typename R,
typename UnaryPredicate>
799 auto count_if(R &&Range, UnaryPredicate
P) ->
typename std::iterator_traits<
800 decltype(
std::begin(Range))>::difference_type {
806 template <
typename R,
typename OutputIt,
typename UnaryPredicate>
807 OutputIt
transform(R &&Range, OutputIt d_first, UnaryPredicate
P) {
813 template <
typename R,
typename UnaryPredicate>
825 template <
typename Container,
typename UnaryPredicate>
843 template <
class T,
class...
Args>
844 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
846 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
858 typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
859 std::unique_ptr<T>>::type
861 return std::unique_ptr<T>(
new typename std::remove_extent<T>::type[n]());
865 template <
class T,
class...
Args>
866 typename std::enable_if<std::extent<T>::value != 0>::type
875 template<
typename First,
typename Second>
878 return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
884 template <
typename A,
typename B>
bool operator()(
A &&a,
B &&b)
const {
885 return std::forward<A>(a) < std::forward<B>(b);
891 template <
typename A,
typename B>
bool operator()(
A &&a,
B &&b)
const {
892 return std::forward<A>(a) == std::forward<B>(b);
898 template <
typename T>
struct deref {
903 template <
typename A,
typename B>
907 return func(*lhs, *rhs);
923 typename std::iterator_traits<IterOfRange<R>>::reference iter_reference;
928 : Iter(Iter), Index(Index) {}
976 template <
typename F,
typename Tuple, std::size_t...
I>
978 -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(
t))...)) {
979 return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(
t))...);
986 template <
typename F,
typename Tuple>
988 std::forward<F>(f), std::forward<Tuple>(
t),
990 std::tuple_size<
typename std::decay<Tuple>::type>::value>{})) {
991 using Indices = build_index_impl<
992 std::tuple_size<typename std::decay<Tuple>::type>::value>;
void DeleteContainerSeconds(Container &C)
In a container of pairs (usually a map) whose second element is a pointer, deletes the second element...
void DeleteContainerPointers(Container &C)
For a container of pointers, deletes the pointers and then clears the container.
const_iterator end(StringRef path)
Get end iterator over path.
std::result_of< UnaryFunc(decltype(*std::declval< RootIt >)))>::type value_type
const Ty & operator()(const Ty &self) const
APInt operator+(APInt a, const APInt &b)
Function object to check whether the second component of a std::pair compares less than the second co...
result_pair(std::size_t Index, X Value)
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
mapped_iterator operator+(difference_type n) const
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
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...
Ret operator()(Params...params) const
An efficient, type-erasing, non-owning reference to a callable.
A functor like C++14's std::less<void> in its absence.
zip_shortest(Iters &&...ts)
const_iterator begin(StringRef path)
Get begin iterator over path.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
filter_iterator & operator++()
ItType< decltype(std::begin(std::declval< Args >)))...> iterator
int array_pod_sort_comparator(const void *P1, const void *P2)
Adapt std::less<T> for array_pod_sort.
Metafunction to determine if T& or T has a member called rbegin().
function_ref(Callable &&callable, typename std::enable_if< !std::is_same< typename std::remove_reference< Callable >::type, function_ref >::value >::type *=nullptr)
mapped_iterator(const RootIt &I, UnaryFunc F)
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...
detail::enumerator_impl< R > enumerate(R &&Range)
Given an input range, returns a new range whose values are are pair (A,B) such that A is the 0-based ...
auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
bool operator()(A &&a, B &&b) const
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly...
bool operator()(const T &lhs, const T &rhs) const
ValueT & operator*() const
Alias for the common case of a sequence of size_ts.
mapped_iterator< ItTy, FuncTy > map_iterator(const ItTy &I, FuncTy F)
std::iterator_traits< RootIt >::iterator_category iterator_category
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
mapped_iterator & operator--()
enumerator_impl(R &&Range)
concat_iterator(RangeTs &&...Ranges)
Constructs an iterator from a squence of ranges.
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...
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(std::begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Helper to store a sequence of ranges being concatenated and access them.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
traits class for checking whether type T is one of any of the given types in the variadic list...
bool operator()(A &&a, B &&b) const
std::iterator_traits< RootIt >::difference_type difference_type
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
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<T> which owns the object...
An iterator adaptor that filters the elements of given inner iterators.
CRTP base class for adapting an iterator to a different type.
mapped_iterator & operator++()
size_t operator()(const std::pair< First, Second > &P) const
Helper to determine if type T has a member called rbegin().
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
detail::zippy< detail::zip_shortest, T, U, Args...> zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
static const unsigned End
mapped_iterator operator++(int)
bool operator<(const mapped_iterator &X) const
bool operator!=(const zip_first< Iters...> &other) const
detail::concat_range< ValueT, RangeTs...> concat(RangeTs &&...Ranges)
Concatenated range across two or more ranges.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Ty & operator()(Ty &self) const
bool operator!=(const iterator &RHS) const
static constexpr size_t size()
value_type operator*() const
A functor like C++14's std::equal<void> in its absence.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool operator()(const T &lhs, const T &rhs) const
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
const UnaryFunc & getFunc() const
mapped_iterator & operator+=(difference_type n)
std::tuple< decltype(*std::declval< Iters >))...> value_type
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Creates a compile-time integer sequence for a parameter pack.
std::tuple< Iters...> iterators
bool operator()(const Ty *left, const Ty *right) const
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
A range adaptor for a pair of iterators.
difference_type operator-(const mapped_iterator &X) const
bool operator!=(const zip_first< Iters...> &other) const
bool operator()(const Ty *left, const Ty *right) const
Represents a compile-time sequence of integers.
concat_iterator & operator++()
mapped_iterator operator--(int)
const RootIt & getCurrent() const
bool operator==(const mapped_iterator &X) const
auto partition(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::partition which take ranges instead of having to pass begin/end explicitly...
decltype(std::begin(std::declval< RangeT & >())) IterOfRange
bool operator!=(const mapped_iterator &X) const
friend iterator_range< filter_iterator< detail::IterOfRange< RT >, PT > > make_filter_range(RT &&, PT)
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...
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...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
mapped_iterator & operator-=(difference_type n)
std::reverse_iterator< IteratorTy > make_reverse_iterator(IteratorTy It)
LLVM Value Representation.
concat_range(RangeTs &&...Ranges)
auto operator()(A &lhs, B &rhs) const -> decltype(func(*lhs,*rhs))
Binary functor that adapts to any other binary functor after dereferencing operands.
Iterator wrapper that concatenates sequences together.
Utility type to build an inheritance chain that makes it easy to rank overload candidates.
bool operator==(const concat_iterator &RHS) const
concat_iterator< ValueT, decltype(std::begin(std::declval< RangeTs & >)))...> iterator
auto find_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
reference operator[](difference_type n) const
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
auto apply_tuple_impl(F &&f, Tuple &&t, index_sequence< I...>) -> decltype(std::forward< F >(f)(std::get< I >(std::forward< Tuple >(t))...))
Function object to check whether the first component of a std::pair compares less than the first comp...
auto count_if(R &&Range, UnaryPredicate P) -> typename std::iterator_traits< decltype(std::begin(Range))>::difference_type
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
result_type operator*() const
std::input_iterator_tag iterator_category
iterator(IterOfRange< R > &&Iter, std::size_t Index)
mapped_iterator operator-(difference_type n) const
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.