xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ADT/STLExtras.h (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
10b57cec5SDimitry Andric //===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains some templates that are useful if you are working with the
100b57cec5SDimitry Andric // STL at all.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric // No library is required when using these functions.
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #ifndef LLVM_ADT_STLEXTRAS_H
170b57cec5SDimitry Andric #define LLVM_ADT_STLEXTRAS_H
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric #include "llvm/ADT/Optional.h"
200b57cec5SDimitry Andric #include "llvm/ADT/iterator.h"
210b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
220b57cec5SDimitry Andric #include "llvm/Config/abi-breaking.h"
230b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
240b57cec5SDimitry Andric #include <algorithm>
250b57cec5SDimitry Andric #include <cassert>
260b57cec5SDimitry Andric #include <cstddef>
270b57cec5SDimitry Andric #include <cstdint>
280b57cec5SDimitry Andric #include <cstdlib>
290b57cec5SDimitry Andric #include <functional>
300b57cec5SDimitry Andric #include <initializer_list>
310b57cec5SDimitry Andric #include <iterator>
320b57cec5SDimitry Andric #include <limits>
330b57cec5SDimitry Andric #include <memory>
340b57cec5SDimitry Andric #include <tuple>
350b57cec5SDimitry Andric #include <type_traits>
360b57cec5SDimitry Andric #include <utility>
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
390b57cec5SDimitry Andric #include <random> // for std::mt19937
400b57cec5SDimitry Andric #endif
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric namespace llvm {
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric // Only used by compiler if both template types are the same.  Useful when
450b57cec5SDimitry Andric // using SFINAE to test for the existence of member functions.
460b57cec5SDimitry Andric template <typename T, T> struct SameType;
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric namespace detail {
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric template <typename RangeT>
510b57cec5SDimitry Andric using IterOfRange = decltype(std::begin(std::declval<RangeT &>()));
520b57cec5SDimitry Andric 
53*5ffd83dbSDimitry Andric template <typename RangeT>
54*5ffd83dbSDimitry Andric using ValueOfRange = typename std::remove_reference<decltype(
55*5ffd83dbSDimitry Andric     *std::begin(std::declval<RangeT &>()))>::type;
56*5ffd83dbSDimitry Andric 
570b57cec5SDimitry Andric } // end namespace detail
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
600b57cec5SDimitry Andric //     Extra additions to <type_traits>
610b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric template <typename T>
640b57cec5SDimitry Andric struct negation : std::integral_constant<bool, !bool(T::value)> {};
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric template <typename...> struct conjunction : std::true_type {};
670b57cec5SDimitry Andric template <typename B1> struct conjunction<B1> : B1 {};
680b57cec5SDimitry Andric template <typename B1, typename... Bn>
690b57cec5SDimitry Andric struct conjunction<B1, Bn...>
700b57cec5SDimitry Andric     : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric template <typename T> struct make_const_ptr {
730b57cec5SDimitry Andric   using type =
740b57cec5SDimitry Andric       typename std::add_pointer<typename std::add_const<T>::type>::type;
750b57cec5SDimitry Andric };
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric template <typename T> struct make_const_ref {
780b57cec5SDimitry Andric   using type = typename std::add_lvalue_reference<
790b57cec5SDimitry Andric       typename std::add_const<T>::type>::type;
800b57cec5SDimitry Andric };
810b57cec5SDimitry Andric 
82*5ffd83dbSDimitry Andric /// Utilities for detecting if a given trait holds for some set of arguments
83*5ffd83dbSDimitry Andric /// 'Args'. For example, the given trait could be used to detect if a given type
84*5ffd83dbSDimitry Andric /// has a copy assignment operator:
85*5ffd83dbSDimitry Andric ///   template<class T>
86*5ffd83dbSDimitry Andric ///   using has_copy_assign_t = decltype(std::declval<T&>()
87*5ffd83dbSDimitry Andric ///                                                 = std::declval<const T&>());
88*5ffd83dbSDimitry Andric ///   bool fooHasCopyAssign = is_detected<has_copy_assign_t, FooClass>::value;
89*5ffd83dbSDimitry Andric namespace detail {
90*5ffd83dbSDimitry Andric template <typename...> using void_t = void;
91*5ffd83dbSDimitry Andric template <class, template <class...> class Op, class... Args> struct detector {
92*5ffd83dbSDimitry Andric   using value_t = std::false_type;
93*5ffd83dbSDimitry Andric };
94*5ffd83dbSDimitry Andric template <template <class...> class Op, class... Args>
95*5ffd83dbSDimitry Andric struct detector<void_t<Op<Args...>>, Op, Args...> {
96*5ffd83dbSDimitry Andric   using value_t = std::true_type;
97*5ffd83dbSDimitry Andric };
98*5ffd83dbSDimitry Andric } // end namespace detail
99*5ffd83dbSDimitry Andric 
100*5ffd83dbSDimitry Andric template <template <class...> class Op, class... Args>
101*5ffd83dbSDimitry Andric using is_detected = typename detail::detector<void, Op, Args...>::value_t;
102*5ffd83dbSDimitry Andric 
103*5ffd83dbSDimitry Andric /// Check if a Callable type can be invoked with the given set of arg types.
104*5ffd83dbSDimitry Andric namespace detail {
105*5ffd83dbSDimitry Andric template <typename Callable, typename... Args>
106*5ffd83dbSDimitry Andric using is_invocable =
107*5ffd83dbSDimitry Andric     decltype(std::declval<Callable &>()(std::declval<Args>()...));
108*5ffd83dbSDimitry Andric } // namespace detail
109*5ffd83dbSDimitry Andric 
110*5ffd83dbSDimitry Andric template <typename Callable, typename... Args>
111*5ffd83dbSDimitry Andric using is_invocable = is_detected<detail::is_invocable, Callable, Args...>;
112*5ffd83dbSDimitry Andric 
113*5ffd83dbSDimitry Andric /// This class provides various trait information about a callable object.
114*5ffd83dbSDimitry Andric ///   * To access the number of arguments: Traits::num_args
115*5ffd83dbSDimitry Andric ///   * To access the type of an argument: Traits::arg_t<Index>
116*5ffd83dbSDimitry Andric ///   * To access the type of the result:  Traits::result_t
117*5ffd83dbSDimitry Andric template <typename T, bool isClass = std::is_class<T>::value>
118*5ffd83dbSDimitry Andric struct function_traits : public function_traits<decltype(&T::operator())> {};
119*5ffd83dbSDimitry Andric 
120*5ffd83dbSDimitry Andric /// Overload for class function types.
121*5ffd83dbSDimitry Andric template <typename ClassType, typename ReturnType, typename... Args>
122*5ffd83dbSDimitry Andric struct function_traits<ReturnType (ClassType::*)(Args...) const, false> {
123*5ffd83dbSDimitry Andric   /// The number of arguments to this function.
124*5ffd83dbSDimitry Andric   enum { num_args = sizeof...(Args) };
125*5ffd83dbSDimitry Andric 
126*5ffd83dbSDimitry Andric   /// The result type of this function.
127*5ffd83dbSDimitry Andric   using result_t = ReturnType;
128*5ffd83dbSDimitry Andric 
129*5ffd83dbSDimitry Andric   /// The type of an argument to this function.
130*5ffd83dbSDimitry Andric   template <size_t Index>
131*5ffd83dbSDimitry Andric   using arg_t = typename std::tuple_element<Index, std::tuple<Args...>>::type;
132*5ffd83dbSDimitry Andric };
133*5ffd83dbSDimitry Andric /// Overload for class function types.
134*5ffd83dbSDimitry Andric template <typename ClassType, typename ReturnType, typename... Args>
135*5ffd83dbSDimitry Andric struct function_traits<ReturnType (ClassType::*)(Args...), false>
136*5ffd83dbSDimitry Andric     : function_traits<ReturnType (ClassType::*)(Args...) const> {};
137*5ffd83dbSDimitry Andric /// Overload for non-class function types.
138*5ffd83dbSDimitry Andric template <typename ReturnType, typename... Args>
139*5ffd83dbSDimitry Andric struct function_traits<ReturnType (*)(Args...), false> {
140*5ffd83dbSDimitry Andric   /// The number of arguments to this function.
141*5ffd83dbSDimitry Andric   enum { num_args = sizeof...(Args) };
142*5ffd83dbSDimitry Andric 
143*5ffd83dbSDimitry Andric   /// The result type of this function.
144*5ffd83dbSDimitry Andric   using result_t = ReturnType;
145*5ffd83dbSDimitry Andric 
146*5ffd83dbSDimitry Andric   /// The type of an argument to this function.
147*5ffd83dbSDimitry Andric   template <size_t i>
148*5ffd83dbSDimitry Andric   using arg_t = typename std::tuple_element<i, std::tuple<Args...>>::type;
149*5ffd83dbSDimitry Andric };
150*5ffd83dbSDimitry Andric /// Overload for non-class function type references.
151*5ffd83dbSDimitry Andric template <typename ReturnType, typename... Args>
152*5ffd83dbSDimitry Andric struct function_traits<ReturnType (&)(Args...), false>
153*5ffd83dbSDimitry Andric     : public function_traits<ReturnType (*)(Args...)> {};
154*5ffd83dbSDimitry Andric 
1550b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1560b57cec5SDimitry Andric //     Extra additions to <functional>
1570b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric template <class Ty> struct identity {
1600b57cec5SDimitry Andric   using argument_type = Ty;
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   Ty &operator()(Ty &self) const {
1630b57cec5SDimitry Andric     return self;
1640b57cec5SDimitry Andric   }
1650b57cec5SDimitry Andric   const Ty &operator()(const Ty &self) const {
1660b57cec5SDimitry Andric     return self;
1670b57cec5SDimitry Andric   }
1680b57cec5SDimitry Andric };
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric /// An efficient, type-erasing, non-owning reference to a callable. This is
1710b57cec5SDimitry Andric /// intended for use as the type of a function parameter that is not used
1720b57cec5SDimitry Andric /// after the function in question returns.
1730b57cec5SDimitry Andric ///
1740b57cec5SDimitry Andric /// This class does not own the callable, so it is not in general safe to store
1750b57cec5SDimitry Andric /// a function_ref.
1760b57cec5SDimitry Andric template<typename Fn> class function_ref;
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric template<typename Ret, typename ...Params>
1790b57cec5SDimitry Andric class function_ref<Ret(Params...)> {
1800b57cec5SDimitry Andric   Ret (*callback)(intptr_t callable, Params ...params) = nullptr;
1810b57cec5SDimitry Andric   intptr_t callable;
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric   template<typename Callable>
1840b57cec5SDimitry Andric   static Ret callback_fn(intptr_t callable, Params ...params) {
1850b57cec5SDimitry Andric     return (*reinterpret_cast<Callable*>(callable))(
1860b57cec5SDimitry Andric         std::forward<Params>(params)...);
1870b57cec5SDimitry Andric   }
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric public:
1900b57cec5SDimitry Andric   function_ref() = default;
1910b57cec5SDimitry Andric   function_ref(std::nullptr_t) {}
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric   template <typename Callable>
194*5ffd83dbSDimitry Andric   function_ref(
195*5ffd83dbSDimitry Andric       Callable &&callable,
196*5ffd83dbSDimitry Andric       std::enable_if_t<
197*5ffd83dbSDimitry Andric           !std::is_same<std::remove_cv_t<std::remove_reference_t<Callable>>,
198*5ffd83dbSDimitry Andric                         function_ref>::value> * = nullptr)
1990b57cec5SDimitry Andric       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
2000b57cec5SDimitry Andric         callable(reinterpret_cast<intptr_t>(&callable)) {}
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   Ret operator()(Params ...params) const {
2030b57cec5SDimitry Andric     return callback(callable, std::forward<Params>(params)...);
2040b57cec5SDimitry Andric   }
2050b57cec5SDimitry Andric 
206*5ffd83dbSDimitry Andric   explicit operator bool() const { return callback; }
2070b57cec5SDimitry Andric };
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric // deleter - Very very very simple method that is used to invoke operator
2100b57cec5SDimitry Andric // delete on something.  It is used like this:
2110b57cec5SDimitry Andric //
2120b57cec5SDimitry Andric //   for_each(V.begin(), B.end(), deleter<Interval>);
2130b57cec5SDimitry Andric template <class T>
2140b57cec5SDimitry Andric inline void deleter(T *Ptr) {
2150b57cec5SDimitry Andric   delete Ptr;
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2190b57cec5SDimitry Andric //     Extra additions to <iterator>
2200b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric namespace adl_detail {
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric using std::begin;
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric template <typename ContainerTy>
227*5ffd83dbSDimitry Andric decltype(auto) adl_begin(ContainerTy &&container) {
2280b57cec5SDimitry Andric   return begin(std::forward<ContainerTy>(container));
2290b57cec5SDimitry Andric }
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric using std::end;
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric template <typename ContainerTy>
234*5ffd83dbSDimitry Andric decltype(auto) adl_end(ContainerTy &&container) {
2350b57cec5SDimitry Andric   return end(std::forward<ContainerTy>(container));
2360b57cec5SDimitry Andric }
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric using std::swap;
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric template <typename T>
2410b57cec5SDimitry Andric void adl_swap(T &&lhs, T &&rhs) noexcept(noexcept(swap(std::declval<T>(),
2420b57cec5SDimitry Andric                                                        std::declval<T>()))) {
2430b57cec5SDimitry Andric   swap(std::forward<T>(lhs), std::forward<T>(rhs));
2440b57cec5SDimitry Andric }
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric } // end namespace adl_detail
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric template <typename ContainerTy>
249*5ffd83dbSDimitry Andric decltype(auto) adl_begin(ContainerTy &&container) {
2500b57cec5SDimitry Andric   return adl_detail::adl_begin(std::forward<ContainerTy>(container));
2510b57cec5SDimitry Andric }
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric template <typename ContainerTy>
254*5ffd83dbSDimitry Andric decltype(auto) adl_end(ContainerTy &&container) {
2550b57cec5SDimitry Andric   return adl_detail::adl_end(std::forward<ContainerTy>(container));
2560b57cec5SDimitry Andric }
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric template <typename T>
2590b57cec5SDimitry Andric void adl_swap(T &&lhs, T &&rhs) noexcept(
2600b57cec5SDimitry Andric     noexcept(adl_detail::adl_swap(std::declval<T>(), std::declval<T>()))) {
2610b57cec5SDimitry Andric   adl_detail::adl_swap(std::forward<T>(lhs), std::forward<T>(rhs));
2620b57cec5SDimitry Andric }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric /// Test whether \p RangeOrContainer is empty. Similar to C++17 std::empty.
2650b57cec5SDimitry Andric template <typename T>
2660b57cec5SDimitry Andric constexpr bool empty(const T &RangeOrContainer) {
2670b57cec5SDimitry Andric   return adl_begin(RangeOrContainer) == adl_end(RangeOrContainer);
2680b57cec5SDimitry Andric }
2690b57cec5SDimitry Andric 
270*5ffd83dbSDimitry Andric /// Returns true if the given container only contains a single element.
271*5ffd83dbSDimitry Andric template <typename ContainerTy> bool hasSingleElement(ContainerTy &&C) {
272*5ffd83dbSDimitry Andric   auto B = std::begin(C), E = std::end(C);
273*5ffd83dbSDimitry Andric   return B != E && std::next(B) == E;
274*5ffd83dbSDimitry Andric }
275*5ffd83dbSDimitry Andric 
276480093f4SDimitry Andric /// Return a range covering \p RangeOrContainer with the first N elements
277480093f4SDimitry Andric /// excluded.
278*5ffd83dbSDimitry Andric template <typename T> auto drop_begin(T &&RangeOrContainer, size_t N) {
279480093f4SDimitry Andric   return make_range(std::next(adl_begin(RangeOrContainer), N),
280480093f4SDimitry Andric                     adl_end(RangeOrContainer));
281480093f4SDimitry Andric }
282480093f4SDimitry Andric 
2830b57cec5SDimitry Andric // mapped_iterator - This is a simple iterator adapter that causes a function to
2840b57cec5SDimitry Andric // be applied whenever operator* is invoked on the iterator.
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric template <typename ItTy, typename FuncTy,
2870b57cec5SDimitry Andric           typename FuncReturnTy =
2880b57cec5SDimitry Andric             decltype(std::declval<FuncTy>()(*std::declval<ItTy>()))>
2890b57cec5SDimitry Andric class mapped_iterator
2900b57cec5SDimitry Andric     : public iterator_adaptor_base<
2910b57cec5SDimitry Andric              mapped_iterator<ItTy, FuncTy>, ItTy,
2920b57cec5SDimitry Andric              typename std::iterator_traits<ItTy>::iterator_category,
2930b57cec5SDimitry Andric              typename std::remove_reference<FuncReturnTy>::type> {
2940b57cec5SDimitry Andric public:
2950b57cec5SDimitry Andric   mapped_iterator(ItTy U, FuncTy F)
2960b57cec5SDimitry Andric     : mapped_iterator::iterator_adaptor_base(std::move(U)), F(std::move(F)) {}
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   ItTy getCurrent() { return this->I; }
2990b57cec5SDimitry Andric 
300*5ffd83dbSDimitry Andric   FuncReturnTy operator*() const { return F(*this->I); }
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric private:
3030b57cec5SDimitry Andric   FuncTy F;
3040b57cec5SDimitry Andric };
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric // map_iterator - Provide a convenient way to create mapped_iterators, just like
3070b57cec5SDimitry Andric // make_pair is useful for creating pairs...
3080b57cec5SDimitry Andric template <class ItTy, class FuncTy>
3090b57cec5SDimitry Andric inline mapped_iterator<ItTy, FuncTy> map_iterator(ItTy I, FuncTy F) {
3100b57cec5SDimitry Andric   return mapped_iterator<ItTy, FuncTy>(std::move(I), std::move(F));
3110b57cec5SDimitry Andric }
3120b57cec5SDimitry Andric 
3130b57cec5SDimitry Andric template <class ContainerTy, class FuncTy>
314*5ffd83dbSDimitry Andric auto map_range(ContainerTy &&C, FuncTy F) {
3150b57cec5SDimitry Andric   return make_range(map_iterator(C.begin(), F), map_iterator(C.end(), F));
3160b57cec5SDimitry Andric }
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric /// Helper to determine if type T has a member called rbegin().
3190b57cec5SDimitry Andric template <typename Ty> class has_rbegin_impl {
3200b57cec5SDimitry Andric   using yes = char[1];
3210b57cec5SDimitry Andric   using no = char[2];
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric   template <typename Inner>
3240b57cec5SDimitry Andric   static yes& test(Inner *I, decltype(I->rbegin()) * = nullptr);
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   template <typename>
3270b57cec5SDimitry Andric   static no& test(...);
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric public:
3300b57cec5SDimitry Andric   static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
3310b57cec5SDimitry Andric };
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric /// Metafunction to determine if T& or T has a member called rbegin().
3340b57cec5SDimitry Andric template <typename Ty>
3350b57cec5SDimitry Andric struct has_rbegin : has_rbegin_impl<typename std::remove_reference<Ty>::type> {
3360b57cec5SDimitry Andric };
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric // Returns an iterator_range over the given container which iterates in reverse.
3390b57cec5SDimitry Andric // Note that the container must have rbegin()/rend() methods for this to work.
3400b57cec5SDimitry Andric template <typename ContainerTy>
3410b57cec5SDimitry Andric auto reverse(ContainerTy &&C,
342*5ffd83dbSDimitry Andric              std::enable_if_t<has_rbegin<ContainerTy>::value> * = nullptr) {
3430b57cec5SDimitry Andric   return make_range(C.rbegin(), C.rend());
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric // Returns a std::reverse_iterator wrapped around the given iterator.
3470b57cec5SDimitry Andric template <typename IteratorTy>
3480b57cec5SDimitry Andric std::reverse_iterator<IteratorTy> make_reverse_iterator(IteratorTy It) {
3490b57cec5SDimitry Andric   return std::reverse_iterator<IteratorTy>(It);
3500b57cec5SDimitry Andric }
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric // Returns an iterator_range over the given container which iterates in reverse.
3530b57cec5SDimitry Andric // Note that the container must have begin()/end() methods which return
3540b57cec5SDimitry Andric // bidirectional iterators for this to work.
3550b57cec5SDimitry Andric template <typename ContainerTy>
356*5ffd83dbSDimitry Andric auto reverse(ContainerTy &&C,
357*5ffd83dbSDimitry Andric              std::enable_if_t<!has_rbegin<ContainerTy>::value> * = nullptr) {
3580b57cec5SDimitry Andric   return make_range(llvm::make_reverse_iterator(std::end(C)),
3590b57cec5SDimitry Andric                     llvm::make_reverse_iterator(std::begin(C)));
3600b57cec5SDimitry Andric }
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric /// An iterator adaptor that filters the elements of given inner iterators.
3630b57cec5SDimitry Andric ///
3640b57cec5SDimitry Andric /// The predicate parameter should be a callable object that accepts the wrapped
3650b57cec5SDimitry Andric /// iterator's reference type and returns a bool. When incrementing or
3660b57cec5SDimitry Andric /// decrementing the iterator, it will call the predicate on each element and
3670b57cec5SDimitry Andric /// skip any where it returns false.
3680b57cec5SDimitry Andric ///
3690b57cec5SDimitry Andric /// \code
3700b57cec5SDimitry Andric ///   int A[] = { 1, 2, 3, 4 };
3710b57cec5SDimitry Andric ///   auto R = make_filter_range(A, [](int N) { return N % 2 == 1; });
3720b57cec5SDimitry Andric ///   // R contains { 1, 3 }.
3730b57cec5SDimitry Andric /// \endcode
3740b57cec5SDimitry Andric ///
3750b57cec5SDimitry Andric /// Note: filter_iterator_base implements support for forward iteration.
3760b57cec5SDimitry Andric /// filter_iterator_impl exists to provide support for bidirectional iteration,
3770b57cec5SDimitry Andric /// conditional on whether the wrapped iterator supports it.
3780b57cec5SDimitry Andric template <typename WrappedIteratorT, typename PredicateT, typename IterTag>
3790b57cec5SDimitry Andric class filter_iterator_base
3800b57cec5SDimitry Andric     : public iterator_adaptor_base<
3810b57cec5SDimitry Andric           filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>,
3820b57cec5SDimitry Andric           WrappedIteratorT,
3830b57cec5SDimitry Andric           typename std::common_type<
3840b57cec5SDimitry Andric               IterTag, typename std::iterator_traits<
3850b57cec5SDimitry Andric                            WrappedIteratorT>::iterator_category>::type> {
3860b57cec5SDimitry Andric   using BaseT = iterator_adaptor_base<
3870b57cec5SDimitry Andric       filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>,
3880b57cec5SDimitry Andric       WrappedIteratorT,
3890b57cec5SDimitry Andric       typename std::common_type<
3900b57cec5SDimitry Andric           IterTag, typename std::iterator_traits<
3910b57cec5SDimitry Andric                        WrappedIteratorT>::iterator_category>::type>;
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric protected:
3940b57cec5SDimitry Andric   WrappedIteratorT End;
3950b57cec5SDimitry Andric   PredicateT Pred;
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric   void findNextValid() {
3980b57cec5SDimitry Andric     while (this->I != End && !Pred(*this->I))
3990b57cec5SDimitry Andric       BaseT::operator++();
4000b57cec5SDimitry Andric   }
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric   // Construct the iterator. The begin iterator needs to know where the end
4030b57cec5SDimitry Andric   // is, so that it can properly stop when it gets there. The end iterator only
4040b57cec5SDimitry Andric   // needs the predicate to support bidirectional iteration.
4050b57cec5SDimitry Andric   filter_iterator_base(WrappedIteratorT Begin, WrappedIteratorT End,
4060b57cec5SDimitry Andric                        PredicateT Pred)
4070b57cec5SDimitry Andric       : BaseT(Begin), End(End), Pred(Pred) {
4080b57cec5SDimitry Andric     findNextValid();
4090b57cec5SDimitry Andric   }
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric public:
4120b57cec5SDimitry Andric   using BaseT::operator++;
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   filter_iterator_base &operator++() {
4150b57cec5SDimitry Andric     BaseT::operator++();
4160b57cec5SDimitry Andric     findNextValid();
4170b57cec5SDimitry Andric     return *this;
4180b57cec5SDimitry Andric   }
4190b57cec5SDimitry Andric };
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric /// Specialization of filter_iterator_base for forward iteration only.
4220b57cec5SDimitry Andric template <typename WrappedIteratorT, typename PredicateT,
4230b57cec5SDimitry Andric           typename IterTag = std::forward_iterator_tag>
4240b57cec5SDimitry Andric class filter_iterator_impl
4250b57cec5SDimitry Andric     : public filter_iterator_base<WrappedIteratorT, PredicateT, IterTag> {
4260b57cec5SDimitry Andric   using BaseT = filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>;
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric public:
4290b57cec5SDimitry Andric   filter_iterator_impl(WrappedIteratorT Begin, WrappedIteratorT End,
4300b57cec5SDimitry Andric                        PredicateT Pred)
4310b57cec5SDimitry Andric       : BaseT(Begin, End, Pred) {}
4320b57cec5SDimitry Andric };
4330b57cec5SDimitry Andric 
4340b57cec5SDimitry Andric /// Specialization of filter_iterator_base for bidirectional iteration.
4350b57cec5SDimitry Andric template <typename WrappedIteratorT, typename PredicateT>
4360b57cec5SDimitry Andric class filter_iterator_impl<WrappedIteratorT, PredicateT,
4370b57cec5SDimitry Andric                            std::bidirectional_iterator_tag>
4380b57cec5SDimitry Andric     : public filter_iterator_base<WrappedIteratorT, PredicateT,
4390b57cec5SDimitry Andric                                   std::bidirectional_iterator_tag> {
4400b57cec5SDimitry Andric   using BaseT = filter_iterator_base<WrappedIteratorT, PredicateT,
4410b57cec5SDimitry Andric                                      std::bidirectional_iterator_tag>;
4420b57cec5SDimitry Andric   void findPrevValid() {
4430b57cec5SDimitry Andric     while (!this->Pred(*this->I))
4440b57cec5SDimitry Andric       BaseT::operator--();
4450b57cec5SDimitry Andric   }
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric public:
4480b57cec5SDimitry Andric   using BaseT::operator--;
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric   filter_iterator_impl(WrappedIteratorT Begin, WrappedIteratorT End,
4510b57cec5SDimitry Andric                        PredicateT Pred)
4520b57cec5SDimitry Andric       : BaseT(Begin, End, Pred) {}
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric   filter_iterator_impl &operator--() {
4550b57cec5SDimitry Andric     BaseT::operator--();
4560b57cec5SDimitry Andric     findPrevValid();
4570b57cec5SDimitry Andric     return *this;
4580b57cec5SDimitry Andric   }
4590b57cec5SDimitry Andric };
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric namespace detail {
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric template <bool is_bidirectional> struct fwd_or_bidi_tag_impl {
4640b57cec5SDimitry Andric   using type = std::forward_iterator_tag;
4650b57cec5SDimitry Andric };
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric template <> struct fwd_or_bidi_tag_impl<true> {
4680b57cec5SDimitry Andric   using type = std::bidirectional_iterator_tag;
4690b57cec5SDimitry Andric };
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric /// Helper which sets its type member to forward_iterator_tag if the category
4720b57cec5SDimitry Andric /// of \p IterT does not derive from bidirectional_iterator_tag, and to
4730b57cec5SDimitry Andric /// bidirectional_iterator_tag otherwise.
4740b57cec5SDimitry Andric template <typename IterT> struct fwd_or_bidi_tag {
4750b57cec5SDimitry Andric   using type = typename fwd_or_bidi_tag_impl<std::is_base_of<
4760b57cec5SDimitry Andric       std::bidirectional_iterator_tag,
4770b57cec5SDimitry Andric       typename std::iterator_traits<IterT>::iterator_category>::value>::type;
4780b57cec5SDimitry Andric };
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric } // namespace detail
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric /// Defines filter_iterator to a suitable specialization of
4830b57cec5SDimitry Andric /// filter_iterator_impl, based on the underlying iterator's category.
4840b57cec5SDimitry Andric template <typename WrappedIteratorT, typename PredicateT>
4850b57cec5SDimitry Andric using filter_iterator = filter_iterator_impl<
4860b57cec5SDimitry Andric     WrappedIteratorT, PredicateT,
4870b57cec5SDimitry Andric     typename detail::fwd_or_bidi_tag<WrappedIteratorT>::type>;
4880b57cec5SDimitry Andric 
4890b57cec5SDimitry Andric /// Convenience function that takes a range of elements and a predicate,
4900b57cec5SDimitry Andric /// and return a new filter_iterator range.
4910b57cec5SDimitry Andric ///
4920b57cec5SDimitry Andric /// FIXME: Currently if RangeT && is a rvalue reference to a temporary, the
4930b57cec5SDimitry Andric /// lifetime of that temporary is not kept by the returned range object, and the
4940b57cec5SDimitry Andric /// temporary is going to be dropped on the floor after the make_iterator_range
4950b57cec5SDimitry Andric /// full expression that contains this function call.
4960b57cec5SDimitry Andric template <typename RangeT, typename PredicateT>
4970b57cec5SDimitry Andric iterator_range<filter_iterator<detail::IterOfRange<RangeT>, PredicateT>>
4980b57cec5SDimitry Andric make_filter_range(RangeT &&Range, PredicateT Pred) {
4990b57cec5SDimitry Andric   using FilterIteratorT =
5000b57cec5SDimitry Andric       filter_iterator<detail::IterOfRange<RangeT>, PredicateT>;
5010b57cec5SDimitry Andric   return make_range(
5020b57cec5SDimitry Andric       FilterIteratorT(std::begin(std::forward<RangeT>(Range)),
5030b57cec5SDimitry Andric                       std::end(std::forward<RangeT>(Range)), Pred),
5040b57cec5SDimitry Andric       FilterIteratorT(std::end(std::forward<RangeT>(Range)),
5050b57cec5SDimitry Andric                       std::end(std::forward<RangeT>(Range)), Pred));
5060b57cec5SDimitry Andric }
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric /// A pseudo-iterator adaptor that is designed to implement "early increment"
5090b57cec5SDimitry Andric /// style loops.
5100b57cec5SDimitry Andric ///
5110b57cec5SDimitry Andric /// This is *not a normal iterator* and should almost never be used directly. It
5120b57cec5SDimitry Andric /// is intended primarily to be used with range based for loops and some range
5130b57cec5SDimitry Andric /// algorithms.
5140b57cec5SDimitry Andric ///
5150b57cec5SDimitry Andric /// The iterator isn't quite an `OutputIterator` or an `InputIterator` but
5160b57cec5SDimitry Andric /// somewhere between them. The constraints of these iterators are:
5170b57cec5SDimitry Andric ///
5180b57cec5SDimitry Andric /// - On construction or after being incremented, it is comparable and
5190b57cec5SDimitry Andric ///   dereferencable. It is *not* incrementable.
5200b57cec5SDimitry Andric /// - After being dereferenced, it is neither comparable nor dereferencable, it
5210b57cec5SDimitry Andric ///   is only incrementable.
5220b57cec5SDimitry Andric ///
5230b57cec5SDimitry Andric /// This means you can only dereference the iterator once, and you can only
5240b57cec5SDimitry Andric /// increment it once between dereferences.
5250b57cec5SDimitry Andric template <typename WrappedIteratorT>
5260b57cec5SDimitry Andric class early_inc_iterator_impl
5270b57cec5SDimitry Andric     : public iterator_adaptor_base<early_inc_iterator_impl<WrappedIteratorT>,
5280b57cec5SDimitry Andric                                    WrappedIteratorT, std::input_iterator_tag> {
5290b57cec5SDimitry Andric   using BaseT =
5300b57cec5SDimitry Andric       iterator_adaptor_base<early_inc_iterator_impl<WrappedIteratorT>,
5310b57cec5SDimitry Andric                             WrappedIteratorT, std::input_iterator_tag>;
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric   using PointerT = typename std::iterator_traits<WrappedIteratorT>::pointer;
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric protected:
5360b57cec5SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
5370b57cec5SDimitry Andric   bool IsEarlyIncremented = false;
5380b57cec5SDimitry Andric #endif
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric public:
5410b57cec5SDimitry Andric   early_inc_iterator_impl(WrappedIteratorT I) : BaseT(I) {}
5420b57cec5SDimitry Andric 
5430b57cec5SDimitry Andric   using BaseT::operator*;
5440b57cec5SDimitry Andric   typename BaseT::reference operator*() {
5450b57cec5SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
5460b57cec5SDimitry Andric     assert(!IsEarlyIncremented && "Cannot dereference twice!");
5470b57cec5SDimitry Andric     IsEarlyIncremented = true;
5480b57cec5SDimitry Andric #endif
5490b57cec5SDimitry Andric     return *(this->I)++;
5500b57cec5SDimitry Andric   }
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric   using BaseT::operator++;
5530b57cec5SDimitry Andric   early_inc_iterator_impl &operator++() {
5540b57cec5SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
5550b57cec5SDimitry Andric     assert(IsEarlyIncremented && "Cannot increment before dereferencing!");
5560b57cec5SDimitry Andric     IsEarlyIncremented = false;
5570b57cec5SDimitry Andric #endif
5580b57cec5SDimitry Andric     return *this;
5590b57cec5SDimitry Andric   }
5600b57cec5SDimitry Andric 
5610b57cec5SDimitry Andric   using BaseT::operator==;
5620b57cec5SDimitry Andric   bool operator==(const early_inc_iterator_impl &RHS) const {
5630b57cec5SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
5640b57cec5SDimitry Andric     assert(!IsEarlyIncremented && "Cannot compare after dereferencing!");
5650b57cec5SDimitry Andric #endif
5660b57cec5SDimitry Andric     return BaseT::operator==(RHS);
5670b57cec5SDimitry Andric   }
5680b57cec5SDimitry Andric };
5690b57cec5SDimitry Andric 
5700b57cec5SDimitry Andric /// Make a range that does early increment to allow mutation of the underlying
5710b57cec5SDimitry Andric /// range without disrupting iteration.
5720b57cec5SDimitry Andric ///
5730b57cec5SDimitry Andric /// The underlying iterator will be incremented immediately after it is
5740b57cec5SDimitry Andric /// dereferenced, allowing deletion of the current node or insertion of nodes to
5750b57cec5SDimitry Andric /// not disrupt iteration provided they do not invalidate the *next* iterator --
5760b57cec5SDimitry Andric /// the current iterator can be invalidated.
5770b57cec5SDimitry Andric ///
5780b57cec5SDimitry Andric /// This requires a very exact pattern of use that is only really suitable to
5790b57cec5SDimitry Andric /// range based for loops and other range algorithms that explicitly guarantee
5800b57cec5SDimitry Andric /// to dereference exactly once each element, and to increment exactly once each
5810b57cec5SDimitry Andric /// element.
5820b57cec5SDimitry Andric template <typename RangeT>
5830b57cec5SDimitry Andric iterator_range<early_inc_iterator_impl<detail::IterOfRange<RangeT>>>
5840b57cec5SDimitry Andric make_early_inc_range(RangeT &&Range) {
5850b57cec5SDimitry Andric   using EarlyIncIteratorT =
5860b57cec5SDimitry Andric       early_inc_iterator_impl<detail::IterOfRange<RangeT>>;
5870b57cec5SDimitry Andric   return make_range(EarlyIncIteratorT(std::begin(std::forward<RangeT>(Range))),
5880b57cec5SDimitry Andric                     EarlyIncIteratorT(std::end(std::forward<RangeT>(Range))));
5890b57cec5SDimitry Andric }
5900b57cec5SDimitry Andric 
5910b57cec5SDimitry Andric // forward declarations required by zip_shortest/zip_first/zip_longest
5920b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
5930b57cec5SDimitry Andric bool all_of(R &&range, UnaryPredicate P);
5940b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
5950b57cec5SDimitry Andric bool any_of(R &&range, UnaryPredicate P);
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric namespace detail {
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric using std::declval;
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric // We have to alias this since inlining the actual type at the usage site
6020b57cec5SDimitry Andric // in the parameter list of iterator_facade_base<> below ICEs MSVC 2017.
6030b57cec5SDimitry Andric template<typename... Iters> struct ZipTupleType {
6040b57cec5SDimitry Andric   using type = std::tuple<decltype(*declval<Iters>())...>;
6050b57cec5SDimitry Andric };
6060b57cec5SDimitry Andric 
6070b57cec5SDimitry Andric template <typename ZipType, typename... Iters>
6080b57cec5SDimitry Andric using zip_traits = iterator_facade_base<
6090b57cec5SDimitry Andric     ZipType, typename std::common_type<std::bidirectional_iterator_tag,
6100b57cec5SDimitry Andric                                        typename std::iterator_traits<
6110b57cec5SDimitry Andric                                            Iters>::iterator_category...>::type,
6120b57cec5SDimitry Andric     // ^ TODO: Implement random access methods.
6130b57cec5SDimitry Andric     typename ZipTupleType<Iters...>::type,
6140b57cec5SDimitry Andric     typename std::iterator_traits<typename std::tuple_element<
6150b57cec5SDimitry Andric         0, std::tuple<Iters...>>::type>::difference_type,
6160b57cec5SDimitry Andric     // ^ FIXME: This follows boost::make_zip_iterator's assumption that all
6170b57cec5SDimitry Andric     // inner iterators have the same difference_type. It would fail if, for
6180b57cec5SDimitry Andric     // instance, the second field's difference_type were non-numeric while the
6190b57cec5SDimitry Andric     // first is.
6200b57cec5SDimitry Andric     typename ZipTupleType<Iters...>::type *,
6210b57cec5SDimitry Andric     typename ZipTupleType<Iters...>::type>;
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric template <typename ZipType, typename... Iters>
6240b57cec5SDimitry Andric struct zip_common : public zip_traits<ZipType, Iters...> {
6250b57cec5SDimitry Andric   using Base = zip_traits<ZipType, Iters...>;
6260b57cec5SDimitry Andric   using value_type = typename Base::value_type;
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric   std::tuple<Iters...> iterators;
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric protected:
6318bcb0991SDimitry Andric   template <size_t... Ns> value_type deref(std::index_sequence<Ns...>) const {
6320b57cec5SDimitry Andric     return value_type(*std::get<Ns>(iterators)...);
6330b57cec5SDimitry Andric   }
6340b57cec5SDimitry Andric 
6350b57cec5SDimitry Andric   template <size_t... Ns>
6368bcb0991SDimitry Andric   decltype(iterators) tup_inc(std::index_sequence<Ns...>) const {
6370b57cec5SDimitry Andric     return std::tuple<Iters...>(std::next(std::get<Ns>(iterators))...);
6380b57cec5SDimitry Andric   }
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric   template <size_t... Ns>
6418bcb0991SDimitry Andric   decltype(iterators) tup_dec(std::index_sequence<Ns...>) const {
6420b57cec5SDimitry Andric     return std::tuple<Iters...>(std::prev(std::get<Ns>(iterators))...);
6430b57cec5SDimitry Andric   }
6440b57cec5SDimitry Andric 
6450b57cec5SDimitry Andric public:
6460b57cec5SDimitry Andric   zip_common(Iters &&... ts) : iterators(std::forward<Iters>(ts)...) {}
6470b57cec5SDimitry Andric 
6488bcb0991SDimitry Andric   value_type operator*() { return deref(std::index_sequence_for<Iters...>{}); }
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric   const value_type operator*() const {
6518bcb0991SDimitry Andric     return deref(std::index_sequence_for<Iters...>{});
6520b57cec5SDimitry Andric   }
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric   ZipType &operator++() {
6558bcb0991SDimitry Andric     iterators = tup_inc(std::index_sequence_for<Iters...>{});
6560b57cec5SDimitry Andric     return *reinterpret_cast<ZipType *>(this);
6570b57cec5SDimitry Andric   }
6580b57cec5SDimitry Andric 
6590b57cec5SDimitry Andric   ZipType &operator--() {
6600b57cec5SDimitry Andric     static_assert(Base::IsBidirectional,
6610b57cec5SDimitry Andric                   "All inner iterators must be at least bidirectional.");
6628bcb0991SDimitry Andric     iterators = tup_dec(std::index_sequence_for<Iters...>{});
6630b57cec5SDimitry Andric     return *reinterpret_cast<ZipType *>(this);
6640b57cec5SDimitry Andric   }
6650b57cec5SDimitry Andric };
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric template <typename... Iters>
6680b57cec5SDimitry Andric struct zip_first : public zip_common<zip_first<Iters...>, Iters...> {
6690b57cec5SDimitry Andric   using Base = zip_common<zip_first<Iters...>, Iters...>;
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric   bool operator==(const zip_first<Iters...> &other) const {
6720b57cec5SDimitry Andric     return std::get<0>(this->iterators) == std::get<0>(other.iterators);
6730b57cec5SDimitry Andric   }
6740b57cec5SDimitry Andric 
6750b57cec5SDimitry Andric   zip_first(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
6760b57cec5SDimitry Andric };
6770b57cec5SDimitry Andric 
6780b57cec5SDimitry Andric template <typename... Iters>
6790b57cec5SDimitry Andric class zip_shortest : public zip_common<zip_shortest<Iters...>, Iters...> {
6800b57cec5SDimitry Andric   template <size_t... Ns>
6818bcb0991SDimitry Andric   bool test(const zip_shortest<Iters...> &other,
6828bcb0991SDimitry Andric             std::index_sequence<Ns...>) const {
6830b57cec5SDimitry Andric     return all_of(std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
6840b57cec5SDimitry Andric                                               std::get<Ns>(other.iterators)...},
6850b57cec5SDimitry Andric                   identity<bool>{});
6860b57cec5SDimitry Andric   }
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric public:
6890b57cec5SDimitry Andric   using Base = zip_common<zip_shortest<Iters...>, Iters...>;
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric   zip_shortest(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
6920b57cec5SDimitry Andric 
6930b57cec5SDimitry Andric   bool operator==(const zip_shortest<Iters...> &other) const {
6948bcb0991SDimitry Andric     return !test(other, std::index_sequence_for<Iters...>{});
6950b57cec5SDimitry Andric   }
6960b57cec5SDimitry Andric };
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric template <template <typename...> class ItType, typename... Args> class zippy {
6990b57cec5SDimitry Andric public:
7000b57cec5SDimitry Andric   using iterator = ItType<decltype(std::begin(std::declval<Args>()))...>;
7010b57cec5SDimitry Andric   using iterator_category = typename iterator::iterator_category;
7020b57cec5SDimitry Andric   using value_type = typename iterator::value_type;
7030b57cec5SDimitry Andric   using difference_type = typename iterator::difference_type;
7040b57cec5SDimitry Andric   using pointer = typename iterator::pointer;
7050b57cec5SDimitry Andric   using reference = typename iterator::reference;
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric private:
7080b57cec5SDimitry Andric   std::tuple<Args...> ts;
7090b57cec5SDimitry Andric 
7108bcb0991SDimitry Andric   template <size_t... Ns>
7118bcb0991SDimitry Andric   iterator begin_impl(std::index_sequence<Ns...>) const {
7120b57cec5SDimitry Andric     return iterator(std::begin(std::get<Ns>(ts))...);
7130b57cec5SDimitry Andric   }
7148bcb0991SDimitry Andric   template <size_t... Ns> iterator end_impl(std::index_sequence<Ns...>) const {
7150b57cec5SDimitry Andric     return iterator(std::end(std::get<Ns>(ts))...);
7160b57cec5SDimitry Andric   }
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric public:
7190b57cec5SDimitry Andric   zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
7200b57cec5SDimitry Andric 
7218bcb0991SDimitry Andric   iterator begin() const {
7228bcb0991SDimitry Andric     return begin_impl(std::index_sequence_for<Args...>{});
7238bcb0991SDimitry Andric   }
7248bcb0991SDimitry Andric   iterator end() const { return end_impl(std::index_sequence_for<Args...>{}); }
7250b57cec5SDimitry Andric };
7260b57cec5SDimitry Andric 
7270b57cec5SDimitry Andric } // end namespace detail
7280b57cec5SDimitry Andric 
7290b57cec5SDimitry Andric /// zip iterator for two or more iteratable types.
7300b57cec5SDimitry Andric template <typename T, typename U, typename... Args>
7310b57cec5SDimitry Andric detail::zippy<detail::zip_shortest, T, U, Args...> zip(T &&t, U &&u,
7320b57cec5SDimitry Andric                                                        Args &&... args) {
7330b57cec5SDimitry Andric   return detail::zippy<detail::zip_shortest, T, U, Args...>(
7340b57cec5SDimitry Andric       std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
7350b57cec5SDimitry Andric }
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric /// zip iterator that, for the sake of efficiency, assumes the first iteratee to
7380b57cec5SDimitry Andric /// be the shortest.
7390b57cec5SDimitry Andric template <typename T, typename U, typename... Args>
7400b57cec5SDimitry Andric detail::zippy<detail::zip_first, T, U, Args...> zip_first(T &&t, U &&u,
7410b57cec5SDimitry Andric                                                           Args &&... args) {
7420b57cec5SDimitry Andric   return detail::zippy<detail::zip_first, T, U, Args...>(
7430b57cec5SDimitry Andric       std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
7440b57cec5SDimitry Andric }
7450b57cec5SDimitry Andric 
7460b57cec5SDimitry Andric namespace detail {
7470b57cec5SDimitry Andric template <typename Iter>
748*5ffd83dbSDimitry Andric Iter next_or_end(const Iter &I, const Iter &End) {
7490b57cec5SDimitry Andric   if (I == End)
7500b57cec5SDimitry Andric     return End;
7510b57cec5SDimitry Andric   return std::next(I);
7520b57cec5SDimitry Andric }
7530b57cec5SDimitry Andric 
7540b57cec5SDimitry Andric template <typename Iter>
755*5ffd83dbSDimitry Andric auto deref_or_none(const Iter &I, const Iter &End) -> llvm::Optional<
756*5ffd83dbSDimitry Andric     std::remove_const_t<std::remove_reference_t<decltype(*I)>>> {
7570b57cec5SDimitry Andric   if (I == End)
7580b57cec5SDimitry Andric     return None;
7590b57cec5SDimitry Andric   return *I;
7600b57cec5SDimitry Andric }
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric template <typename Iter> struct ZipLongestItemType {
7630b57cec5SDimitry Andric   using type =
7640b57cec5SDimitry Andric       llvm::Optional<typename std::remove_const<typename std::remove_reference<
7650b57cec5SDimitry Andric           decltype(*std::declval<Iter>())>::type>::type>;
7660b57cec5SDimitry Andric };
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric template <typename... Iters> struct ZipLongestTupleType {
7690b57cec5SDimitry Andric   using type = std::tuple<typename ZipLongestItemType<Iters>::type...>;
7700b57cec5SDimitry Andric };
7710b57cec5SDimitry Andric 
7720b57cec5SDimitry Andric template <typename... Iters>
7730b57cec5SDimitry Andric class zip_longest_iterator
7740b57cec5SDimitry Andric     : public iterator_facade_base<
7750b57cec5SDimitry Andric           zip_longest_iterator<Iters...>,
7760b57cec5SDimitry Andric           typename std::common_type<
7770b57cec5SDimitry Andric               std::forward_iterator_tag,
7780b57cec5SDimitry Andric               typename std::iterator_traits<Iters>::iterator_category...>::type,
7790b57cec5SDimitry Andric           typename ZipLongestTupleType<Iters...>::type,
7800b57cec5SDimitry Andric           typename std::iterator_traits<typename std::tuple_element<
7810b57cec5SDimitry Andric               0, std::tuple<Iters...>>::type>::difference_type,
7820b57cec5SDimitry Andric           typename ZipLongestTupleType<Iters...>::type *,
7830b57cec5SDimitry Andric           typename ZipLongestTupleType<Iters...>::type> {
7840b57cec5SDimitry Andric public:
7850b57cec5SDimitry Andric   using value_type = typename ZipLongestTupleType<Iters...>::type;
7860b57cec5SDimitry Andric 
7870b57cec5SDimitry Andric private:
7880b57cec5SDimitry Andric   std::tuple<Iters...> iterators;
7890b57cec5SDimitry Andric   std::tuple<Iters...> end_iterators;
7900b57cec5SDimitry Andric 
7910b57cec5SDimitry Andric   template <size_t... Ns>
7920b57cec5SDimitry Andric   bool test(const zip_longest_iterator<Iters...> &other,
7938bcb0991SDimitry Andric             std::index_sequence<Ns...>) const {
7940b57cec5SDimitry Andric     return llvm::any_of(
7950b57cec5SDimitry Andric         std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
7960b57cec5SDimitry Andric                                     std::get<Ns>(other.iterators)...},
7970b57cec5SDimitry Andric         identity<bool>{});
7980b57cec5SDimitry Andric   }
7990b57cec5SDimitry Andric 
8008bcb0991SDimitry Andric   template <size_t... Ns> value_type deref(std::index_sequence<Ns...>) const {
8010b57cec5SDimitry Andric     return value_type(
8020b57cec5SDimitry Andric         deref_or_none(std::get<Ns>(iterators), std::get<Ns>(end_iterators))...);
8030b57cec5SDimitry Andric   }
8040b57cec5SDimitry Andric 
8050b57cec5SDimitry Andric   template <size_t... Ns>
8068bcb0991SDimitry Andric   decltype(iterators) tup_inc(std::index_sequence<Ns...>) const {
8070b57cec5SDimitry Andric     return std::tuple<Iters...>(
8080b57cec5SDimitry Andric         next_or_end(std::get<Ns>(iterators), std::get<Ns>(end_iterators))...);
8090b57cec5SDimitry Andric   }
8100b57cec5SDimitry Andric 
8110b57cec5SDimitry Andric public:
8120b57cec5SDimitry Andric   zip_longest_iterator(std::pair<Iters &&, Iters &&>... ts)
8130b57cec5SDimitry Andric       : iterators(std::forward<Iters>(ts.first)...),
8140b57cec5SDimitry Andric         end_iterators(std::forward<Iters>(ts.second)...) {}
8150b57cec5SDimitry Andric 
8168bcb0991SDimitry Andric   value_type operator*() { return deref(std::index_sequence_for<Iters...>{}); }
8170b57cec5SDimitry Andric 
8188bcb0991SDimitry Andric   value_type operator*() const {
8198bcb0991SDimitry Andric     return deref(std::index_sequence_for<Iters...>{});
8208bcb0991SDimitry Andric   }
8210b57cec5SDimitry Andric 
8220b57cec5SDimitry Andric   zip_longest_iterator<Iters...> &operator++() {
8238bcb0991SDimitry Andric     iterators = tup_inc(std::index_sequence_for<Iters...>{});
8240b57cec5SDimitry Andric     return *this;
8250b57cec5SDimitry Andric   }
8260b57cec5SDimitry Andric 
8270b57cec5SDimitry Andric   bool operator==(const zip_longest_iterator<Iters...> &other) const {
8288bcb0991SDimitry Andric     return !test(other, std::index_sequence_for<Iters...>{});
8290b57cec5SDimitry Andric   }
8300b57cec5SDimitry Andric };
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric template <typename... Args> class zip_longest_range {
8330b57cec5SDimitry Andric public:
8340b57cec5SDimitry Andric   using iterator =
8350b57cec5SDimitry Andric       zip_longest_iterator<decltype(adl_begin(std::declval<Args>()))...>;
8360b57cec5SDimitry Andric   using iterator_category = typename iterator::iterator_category;
8370b57cec5SDimitry Andric   using value_type = typename iterator::value_type;
8380b57cec5SDimitry Andric   using difference_type = typename iterator::difference_type;
8390b57cec5SDimitry Andric   using pointer = typename iterator::pointer;
8400b57cec5SDimitry Andric   using reference = typename iterator::reference;
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric private:
8430b57cec5SDimitry Andric   std::tuple<Args...> ts;
8440b57cec5SDimitry Andric 
8458bcb0991SDimitry Andric   template <size_t... Ns>
8468bcb0991SDimitry Andric   iterator begin_impl(std::index_sequence<Ns...>) const {
8470b57cec5SDimitry Andric     return iterator(std::make_pair(adl_begin(std::get<Ns>(ts)),
8480b57cec5SDimitry Andric                                    adl_end(std::get<Ns>(ts)))...);
8490b57cec5SDimitry Andric   }
8500b57cec5SDimitry Andric 
8518bcb0991SDimitry Andric   template <size_t... Ns> iterator end_impl(std::index_sequence<Ns...>) const {
8520b57cec5SDimitry Andric     return iterator(std::make_pair(adl_end(std::get<Ns>(ts)),
8530b57cec5SDimitry Andric                                    adl_end(std::get<Ns>(ts)))...);
8540b57cec5SDimitry Andric   }
8550b57cec5SDimitry Andric 
8560b57cec5SDimitry Andric public:
8570b57cec5SDimitry Andric   zip_longest_range(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
8580b57cec5SDimitry Andric 
8598bcb0991SDimitry Andric   iterator begin() const {
8608bcb0991SDimitry Andric     return begin_impl(std::index_sequence_for<Args...>{});
8618bcb0991SDimitry Andric   }
8628bcb0991SDimitry Andric   iterator end() const { return end_impl(std::index_sequence_for<Args...>{}); }
8630b57cec5SDimitry Andric };
8640b57cec5SDimitry Andric } // namespace detail
8650b57cec5SDimitry Andric 
8660b57cec5SDimitry Andric /// Iterate over two or more iterators at the same time. Iteration continues
8670b57cec5SDimitry Andric /// until all iterators reach the end. The llvm::Optional only contains a value
8680b57cec5SDimitry Andric /// if the iterator has not reached the end.
8690b57cec5SDimitry Andric template <typename T, typename U, typename... Args>
8700b57cec5SDimitry Andric detail::zip_longest_range<T, U, Args...> zip_longest(T &&t, U &&u,
8710b57cec5SDimitry Andric                                                      Args &&... args) {
8720b57cec5SDimitry Andric   return detail::zip_longest_range<T, U, Args...>(
8730b57cec5SDimitry Andric       std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
8740b57cec5SDimitry Andric }
8750b57cec5SDimitry Andric 
8760b57cec5SDimitry Andric /// Iterator wrapper that concatenates sequences together.
8770b57cec5SDimitry Andric ///
8780b57cec5SDimitry Andric /// This can concatenate different iterators, even with different types, into
8790b57cec5SDimitry Andric /// a single iterator provided the value types of all the concatenated
8800b57cec5SDimitry Andric /// iterators expose `reference` and `pointer` types that can be converted to
8810b57cec5SDimitry Andric /// `ValueT &` and `ValueT *` respectively. It doesn't support more
8820b57cec5SDimitry Andric /// interesting/customized pointer or reference types.
8830b57cec5SDimitry Andric ///
8840b57cec5SDimitry Andric /// Currently this only supports forward or higher iterator categories as
8850b57cec5SDimitry Andric /// inputs and always exposes a forward iterator interface.
8860b57cec5SDimitry Andric template <typename ValueT, typename... IterTs>
8870b57cec5SDimitry Andric class concat_iterator
8880b57cec5SDimitry Andric     : public iterator_facade_base<concat_iterator<ValueT, IterTs...>,
8890b57cec5SDimitry Andric                                   std::forward_iterator_tag, ValueT> {
8900b57cec5SDimitry Andric   using BaseT = typename concat_iterator::iterator_facade_base;
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric   /// We store both the current and end iterators for each concatenated
8930b57cec5SDimitry Andric   /// sequence in a tuple of pairs.
8940b57cec5SDimitry Andric   ///
8950b57cec5SDimitry Andric   /// Note that something like iterator_range seems nice at first here, but the
8960b57cec5SDimitry Andric   /// range properties are of little benefit and end up getting in the way
8970b57cec5SDimitry Andric   /// because we need to do mutation on the current iterators.
8980b57cec5SDimitry Andric   std::tuple<IterTs...> Begins;
8990b57cec5SDimitry Andric   std::tuple<IterTs...> Ends;
9000b57cec5SDimitry Andric 
9010b57cec5SDimitry Andric   /// Attempts to increment a specific iterator.
9020b57cec5SDimitry Andric   ///
9030b57cec5SDimitry Andric   /// Returns true if it was able to increment the iterator. Returns false if
9040b57cec5SDimitry Andric   /// the iterator is already at the end iterator.
9050b57cec5SDimitry Andric   template <size_t Index> bool incrementHelper() {
9060b57cec5SDimitry Andric     auto &Begin = std::get<Index>(Begins);
9070b57cec5SDimitry Andric     auto &End = std::get<Index>(Ends);
9080b57cec5SDimitry Andric     if (Begin == End)
9090b57cec5SDimitry Andric       return false;
9100b57cec5SDimitry Andric 
9110b57cec5SDimitry Andric     ++Begin;
9120b57cec5SDimitry Andric     return true;
9130b57cec5SDimitry Andric   }
9140b57cec5SDimitry Andric 
9150b57cec5SDimitry Andric   /// Increments the first non-end iterator.
9160b57cec5SDimitry Andric   ///
9170b57cec5SDimitry Andric   /// It is an error to call this with all iterators at the end.
9188bcb0991SDimitry Andric   template <size_t... Ns> void increment(std::index_sequence<Ns...>) {
9190b57cec5SDimitry Andric     // Build a sequence of functions to increment each iterator if possible.
9200b57cec5SDimitry Andric     bool (concat_iterator::*IncrementHelperFns[])() = {
9210b57cec5SDimitry Andric         &concat_iterator::incrementHelper<Ns>...};
9220b57cec5SDimitry Andric 
9230b57cec5SDimitry Andric     // Loop over them, and stop as soon as we succeed at incrementing one.
9240b57cec5SDimitry Andric     for (auto &IncrementHelperFn : IncrementHelperFns)
9250b57cec5SDimitry Andric       if ((this->*IncrementHelperFn)())
9260b57cec5SDimitry Andric         return;
9270b57cec5SDimitry Andric 
9280b57cec5SDimitry Andric     llvm_unreachable("Attempted to increment an end concat iterator!");
9290b57cec5SDimitry Andric   }
9300b57cec5SDimitry Andric 
9310b57cec5SDimitry Andric   /// Returns null if the specified iterator is at the end. Otherwise,
9320b57cec5SDimitry Andric   /// dereferences the iterator and returns the address of the resulting
9330b57cec5SDimitry Andric   /// reference.
9340b57cec5SDimitry Andric   template <size_t Index> ValueT *getHelper() const {
9350b57cec5SDimitry Andric     auto &Begin = std::get<Index>(Begins);
9360b57cec5SDimitry Andric     auto &End = std::get<Index>(Ends);
9370b57cec5SDimitry Andric     if (Begin == End)
9380b57cec5SDimitry Andric       return nullptr;
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric     return &*Begin;
9410b57cec5SDimitry Andric   }
9420b57cec5SDimitry Andric 
9430b57cec5SDimitry Andric   /// Finds the first non-end iterator, dereferences, and returns the resulting
9440b57cec5SDimitry Andric   /// reference.
9450b57cec5SDimitry Andric   ///
9460b57cec5SDimitry Andric   /// It is an error to call this with all iterators at the end.
9478bcb0991SDimitry Andric   template <size_t... Ns> ValueT &get(std::index_sequence<Ns...>) const {
9480b57cec5SDimitry Andric     // Build a sequence of functions to get from iterator if possible.
9490b57cec5SDimitry Andric     ValueT *(concat_iterator::*GetHelperFns[])() const = {
9500b57cec5SDimitry Andric         &concat_iterator::getHelper<Ns>...};
9510b57cec5SDimitry Andric 
9520b57cec5SDimitry Andric     // Loop over them, and return the first result we find.
9530b57cec5SDimitry Andric     for (auto &GetHelperFn : GetHelperFns)
9540b57cec5SDimitry Andric       if (ValueT *P = (this->*GetHelperFn)())
9550b57cec5SDimitry Andric         return *P;
9560b57cec5SDimitry Andric 
9570b57cec5SDimitry Andric     llvm_unreachable("Attempted to get a pointer from an end concat iterator!");
9580b57cec5SDimitry Andric   }
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric public:
961*5ffd83dbSDimitry Andric   /// Constructs an iterator from a sequence of ranges.
9620b57cec5SDimitry Andric   ///
9630b57cec5SDimitry Andric   /// We need the full range to know how to switch between each of the
9640b57cec5SDimitry Andric   /// iterators.
9650b57cec5SDimitry Andric   template <typename... RangeTs>
9660b57cec5SDimitry Andric   explicit concat_iterator(RangeTs &&... Ranges)
9670b57cec5SDimitry Andric       : Begins(std::begin(Ranges)...), Ends(std::end(Ranges)...) {}
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric   using BaseT::operator++;
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric   concat_iterator &operator++() {
9728bcb0991SDimitry Andric     increment(std::index_sequence_for<IterTs...>());
9730b57cec5SDimitry Andric     return *this;
9740b57cec5SDimitry Andric   }
9750b57cec5SDimitry Andric 
9768bcb0991SDimitry Andric   ValueT &operator*() const {
9778bcb0991SDimitry Andric     return get(std::index_sequence_for<IterTs...>());
9788bcb0991SDimitry Andric   }
9790b57cec5SDimitry Andric 
9800b57cec5SDimitry Andric   bool operator==(const concat_iterator &RHS) const {
9810b57cec5SDimitry Andric     return Begins == RHS.Begins && Ends == RHS.Ends;
9820b57cec5SDimitry Andric   }
9830b57cec5SDimitry Andric };
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric namespace detail {
9860b57cec5SDimitry Andric 
9870b57cec5SDimitry Andric /// Helper to store a sequence of ranges being concatenated and access them.
9880b57cec5SDimitry Andric ///
9890b57cec5SDimitry Andric /// This is designed to facilitate providing actual storage when temporaries
9900b57cec5SDimitry Andric /// are passed into the constructor such that we can use it as part of range
9910b57cec5SDimitry Andric /// based for loops.
9920b57cec5SDimitry Andric template <typename ValueT, typename... RangeTs> class concat_range {
9930b57cec5SDimitry Andric public:
9940b57cec5SDimitry Andric   using iterator =
9950b57cec5SDimitry Andric       concat_iterator<ValueT,
9960b57cec5SDimitry Andric                       decltype(std::begin(std::declval<RangeTs &>()))...>;
9970b57cec5SDimitry Andric 
9980b57cec5SDimitry Andric private:
9990b57cec5SDimitry Andric   std::tuple<RangeTs...> Ranges;
10000b57cec5SDimitry Andric 
10018bcb0991SDimitry Andric   template <size_t... Ns> iterator begin_impl(std::index_sequence<Ns...>) {
10020b57cec5SDimitry Andric     return iterator(std::get<Ns>(Ranges)...);
10030b57cec5SDimitry Andric   }
10048bcb0991SDimitry Andric   template <size_t... Ns> iterator end_impl(std::index_sequence<Ns...>) {
10050b57cec5SDimitry Andric     return iterator(make_range(std::end(std::get<Ns>(Ranges)),
10060b57cec5SDimitry Andric                                std::end(std::get<Ns>(Ranges)))...);
10070b57cec5SDimitry Andric   }
10080b57cec5SDimitry Andric 
10090b57cec5SDimitry Andric public:
10100b57cec5SDimitry Andric   concat_range(RangeTs &&... Ranges)
10110b57cec5SDimitry Andric       : Ranges(std::forward<RangeTs>(Ranges)...) {}
10120b57cec5SDimitry Andric 
10138bcb0991SDimitry Andric   iterator begin() { return begin_impl(std::index_sequence_for<RangeTs...>{}); }
10148bcb0991SDimitry Andric   iterator end() { return end_impl(std::index_sequence_for<RangeTs...>{}); }
10150b57cec5SDimitry Andric };
10160b57cec5SDimitry Andric 
10170b57cec5SDimitry Andric } // end namespace detail
10180b57cec5SDimitry Andric 
10190b57cec5SDimitry Andric /// Concatenated range across two or more ranges.
10200b57cec5SDimitry Andric ///
10210b57cec5SDimitry Andric /// The desired value type must be explicitly specified.
10220b57cec5SDimitry Andric template <typename ValueT, typename... RangeTs>
10230b57cec5SDimitry Andric detail::concat_range<ValueT, RangeTs...> concat(RangeTs &&... Ranges) {
10240b57cec5SDimitry Andric   static_assert(sizeof...(RangeTs) > 1,
10250b57cec5SDimitry Andric                 "Need more than one range to concatenate!");
10260b57cec5SDimitry Andric   return detail::concat_range<ValueT, RangeTs...>(
10270b57cec5SDimitry Andric       std::forward<RangeTs>(Ranges)...);
10280b57cec5SDimitry Andric }
10290b57cec5SDimitry Andric 
1030*5ffd83dbSDimitry Andric /// A utility class used to implement an iterator that contains some base object
1031*5ffd83dbSDimitry Andric /// and an index. The iterator moves the index but keeps the base constant.
1032*5ffd83dbSDimitry Andric template <typename DerivedT, typename BaseT, typename T,
1033*5ffd83dbSDimitry Andric           typename PointerT = T *, typename ReferenceT = T &>
1034*5ffd83dbSDimitry Andric class indexed_accessor_iterator
1035*5ffd83dbSDimitry Andric     : public llvm::iterator_facade_base<DerivedT,
1036*5ffd83dbSDimitry Andric                                         std::random_access_iterator_tag, T,
1037*5ffd83dbSDimitry Andric                                         std::ptrdiff_t, PointerT, ReferenceT> {
1038*5ffd83dbSDimitry Andric public:
1039*5ffd83dbSDimitry Andric   ptrdiff_t operator-(const indexed_accessor_iterator &rhs) const {
1040*5ffd83dbSDimitry Andric     assert(base == rhs.base && "incompatible iterators");
1041*5ffd83dbSDimitry Andric     return index - rhs.index;
1042*5ffd83dbSDimitry Andric   }
1043*5ffd83dbSDimitry Andric   bool operator==(const indexed_accessor_iterator &rhs) const {
1044*5ffd83dbSDimitry Andric     return base == rhs.base && index == rhs.index;
1045*5ffd83dbSDimitry Andric   }
1046*5ffd83dbSDimitry Andric   bool operator<(const indexed_accessor_iterator &rhs) const {
1047*5ffd83dbSDimitry Andric     assert(base == rhs.base && "incompatible iterators");
1048*5ffd83dbSDimitry Andric     return index < rhs.index;
1049*5ffd83dbSDimitry Andric   }
1050*5ffd83dbSDimitry Andric 
1051*5ffd83dbSDimitry Andric   DerivedT &operator+=(ptrdiff_t offset) {
1052*5ffd83dbSDimitry Andric     this->index += offset;
1053*5ffd83dbSDimitry Andric     return static_cast<DerivedT &>(*this);
1054*5ffd83dbSDimitry Andric   }
1055*5ffd83dbSDimitry Andric   DerivedT &operator-=(ptrdiff_t offset) {
1056*5ffd83dbSDimitry Andric     this->index -= offset;
1057*5ffd83dbSDimitry Andric     return static_cast<DerivedT &>(*this);
1058*5ffd83dbSDimitry Andric   }
1059*5ffd83dbSDimitry Andric 
1060*5ffd83dbSDimitry Andric   /// Returns the current index of the iterator.
1061*5ffd83dbSDimitry Andric   ptrdiff_t getIndex() const { return index; }
1062*5ffd83dbSDimitry Andric 
1063*5ffd83dbSDimitry Andric   /// Returns the current base of the iterator.
1064*5ffd83dbSDimitry Andric   const BaseT &getBase() const { return base; }
1065*5ffd83dbSDimitry Andric 
1066*5ffd83dbSDimitry Andric protected:
1067*5ffd83dbSDimitry Andric   indexed_accessor_iterator(BaseT base, ptrdiff_t index)
1068*5ffd83dbSDimitry Andric       : base(base), index(index) {}
1069*5ffd83dbSDimitry Andric   BaseT base;
1070*5ffd83dbSDimitry Andric   ptrdiff_t index;
1071*5ffd83dbSDimitry Andric };
1072*5ffd83dbSDimitry Andric 
1073*5ffd83dbSDimitry Andric namespace detail {
1074*5ffd83dbSDimitry Andric /// The class represents the base of a range of indexed_accessor_iterators. It
1075*5ffd83dbSDimitry Andric /// provides support for many different range functionalities, e.g.
1076*5ffd83dbSDimitry Andric /// drop_front/slice/etc.. Derived range classes must implement the following
1077*5ffd83dbSDimitry Andric /// static methods:
1078*5ffd83dbSDimitry Andric ///   * ReferenceT dereference_iterator(const BaseT &base, ptrdiff_t index)
1079*5ffd83dbSDimitry Andric ///     - Dereference an iterator pointing to the base object at the given
1080*5ffd83dbSDimitry Andric ///       index.
1081*5ffd83dbSDimitry Andric ///   * BaseT offset_base(const BaseT &base, ptrdiff_t index)
1082*5ffd83dbSDimitry Andric ///     - Return a new base that is offset from the provide base by 'index'
1083*5ffd83dbSDimitry Andric ///       elements.
1084*5ffd83dbSDimitry Andric template <typename DerivedT, typename BaseT, typename T,
1085*5ffd83dbSDimitry Andric           typename PointerT = T *, typename ReferenceT = T &>
1086*5ffd83dbSDimitry Andric class indexed_accessor_range_base {
1087*5ffd83dbSDimitry Andric public:
1088*5ffd83dbSDimitry Andric   using RangeBaseT =
1089*5ffd83dbSDimitry Andric       indexed_accessor_range_base<DerivedT, BaseT, T, PointerT, ReferenceT>;
1090*5ffd83dbSDimitry Andric 
1091*5ffd83dbSDimitry Andric   /// An iterator element of this range.
1092*5ffd83dbSDimitry Andric   class iterator : public indexed_accessor_iterator<iterator, BaseT, T,
1093*5ffd83dbSDimitry Andric                                                     PointerT, ReferenceT> {
1094*5ffd83dbSDimitry Andric   public:
1095*5ffd83dbSDimitry Andric     // Index into this iterator, invoking a static method on the derived type.
1096*5ffd83dbSDimitry Andric     ReferenceT operator*() const {
1097*5ffd83dbSDimitry Andric       return DerivedT::dereference_iterator(this->getBase(), this->getIndex());
1098*5ffd83dbSDimitry Andric     }
1099*5ffd83dbSDimitry Andric 
1100*5ffd83dbSDimitry Andric   private:
1101*5ffd83dbSDimitry Andric     iterator(BaseT owner, ptrdiff_t curIndex)
1102*5ffd83dbSDimitry Andric         : indexed_accessor_iterator<iterator, BaseT, T, PointerT, ReferenceT>(
1103*5ffd83dbSDimitry Andric               owner, curIndex) {}
1104*5ffd83dbSDimitry Andric 
1105*5ffd83dbSDimitry Andric     /// Allow access to the constructor.
1106*5ffd83dbSDimitry Andric     friend indexed_accessor_range_base<DerivedT, BaseT, T, PointerT,
1107*5ffd83dbSDimitry Andric                                        ReferenceT>;
1108*5ffd83dbSDimitry Andric   };
1109*5ffd83dbSDimitry Andric 
1110*5ffd83dbSDimitry Andric   indexed_accessor_range_base(iterator begin, iterator end)
1111*5ffd83dbSDimitry Andric       : base(offset_base(begin.getBase(), begin.getIndex())),
1112*5ffd83dbSDimitry Andric         count(end.getIndex() - begin.getIndex()) {}
1113*5ffd83dbSDimitry Andric   indexed_accessor_range_base(const iterator_range<iterator> &range)
1114*5ffd83dbSDimitry Andric       : indexed_accessor_range_base(range.begin(), range.end()) {}
1115*5ffd83dbSDimitry Andric   indexed_accessor_range_base(BaseT base, ptrdiff_t count)
1116*5ffd83dbSDimitry Andric       : base(base), count(count) {}
1117*5ffd83dbSDimitry Andric 
1118*5ffd83dbSDimitry Andric   iterator begin() const { return iterator(base, 0); }
1119*5ffd83dbSDimitry Andric   iterator end() const { return iterator(base, count); }
1120*5ffd83dbSDimitry Andric   ReferenceT operator[](unsigned index) const {
1121*5ffd83dbSDimitry Andric     assert(index < size() && "invalid index for value range");
1122*5ffd83dbSDimitry Andric     return DerivedT::dereference_iterator(base, index);
1123*5ffd83dbSDimitry Andric   }
1124*5ffd83dbSDimitry Andric   ReferenceT front() const {
1125*5ffd83dbSDimitry Andric     assert(!empty() && "expected non-empty range");
1126*5ffd83dbSDimitry Andric     return (*this)[0];
1127*5ffd83dbSDimitry Andric   }
1128*5ffd83dbSDimitry Andric   ReferenceT back() const {
1129*5ffd83dbSDimitry Andric     assert(!empty() && "expected non-empty range");
1130*5ffd83dbSDimitry Andric     return (*this)[size() - 1];
1131*5ffd83dbSDimitry Andric   }
1132*5ffd83dbSDimitry Andric 
1133*5ffd83dbSDimitry Andric   /// Compare this range with another.
1134*5ffd83dbSDimitry Andric   template <typename OtherT> bool operator==(const OtherT &other) const {
1135*5ffd83dbSDimitry Andric     return size() ==
1136*5ffd83dbSDimitry Andric                static_cast<size_t>(std::distance(other.begin(), other.end())) &&
1137*5ffd83dbSDimitry Andric            std::equal(begin(), end(), other.begin());
1138*5ffd83dbSDimitry Andric   }
1139*5ffd83dbSDimitry Andric   template <typename OtherT> bool operator!=(const OtherT &other) const {
1140*5ffd83dbSDimitry Andric     return !(*this == other);
1141*5ffd83dbSDimitry Andric   }
1142*5ffd83dbSDimitry Andric 
1143*5ffd83dbSDimitry Andric   /// Return the size of this range.
1144*5ffd83dbSDimitry Andric   size_t size() const { return count; }
1145*5ffd83dbSDimitry Andric 
1146*5ffd83dbSDimitry Andric   /// Return if the range is empty.
1147*5ffd83dbSDimitry Andric   bool empty() const { return size() == 0; }
1148*5ffd83dbSDimitry Andric 
1149*5ffd83dbSDimitry Andric   /// Drop the first N elements, and keep M elements.
1150*5ffd83dbSDimitry Andric   DerivedT slice(size_t n, size_t m) const {
1151*5ffd83dbSDimitry Andric     assert(n + m <= size() && "invalid size specifiers");
1152*5ffd83dbSDimitry Andric     return DerivedT(offset_base(base, n), m);
1153*5ffd83dbSDimitry Andric   }
1154*5ffd83dbSDimitry Andric 
1155*5ffd83dbSDimitry Andric   /// Drop the first n elements.
1156*5ffd83dbSDimitry Andric   DerivedT drop_front(size_t n = 1) const {
1157*5ffd83dbSDimitry Andric     assert(size() >= n && "Dropping more elements than exist");
1158*5ffd83dbSDimitry Andric     return slice(n, size() - n);
1159*5ffd83dbSDimitry Andric   }
1160*5ffd83dbSDimitry Andric   /// Drop the last n elements.
1161*5ffd83dbSDimitry Andric   DerivedT drop_back(size_t n = 1) const {
1162*5ffd83dbSDimitry Andric     assert(size() >= n && "Dropping more elements than exist");
1163*5ffd83dbSDimitry Andric     return DerivedT(base, size() - n);
1164*5ffd83dbSDimitry Andric   }
1165*5ffd83dbSDimitry Andric 
1166*5ffd83dbSDimitry Andric   /// Take the first n elements.
1167*5ffd83dbSDimitry Andric   DerivedT take_front(size_t n = 1) const {
1168*5ffd83dbSDimitry Andric     return n < size() ? drop_back(size() - n)
1169*5ffd83dbSDimitry Andric                       : static_cast<const DerivedT &>(*this);
1170*5ffd83dbSDimitry Andric   }
1171*5ffd83dbSDimitry Andric 
1172*5ffd83dbSDimitry Andric   /// Take the last n elements.
1173*5ffd83dbSDimitry Andric   DerivedT take_back(size_t n = 1) const {
1174*5ffd83dbSDimitry Andric     return n < size() ? drop_front(size() - n)
1175*5ffd83dbSDimitry Andric                       : static_cast<const DerivedT &>(*this);
1176*5ffd83dbSDimitry Andric   }
1177*5ffd83dbSDimitry Andric 
1178*5ffd83dbSDimitry Andric   /// Allow conversion to any type accepting an iterator_range.
1179*5ffd83dbSDimitry Andric   template <typename RangeT, typename = std::enable_if_t<std::is_constructible<
1180*5ffd83dbSDimitry Andric                                  RangeT, iterator_range<iterator>>::value>>
1181*5ffd83dbSDimitry Andric   operator RangeT() const {
1182*5ffd83dbSDimitry Andric     return RangeT(iterator_range<iterator>(*this));
1183*5ffd83dbSDimitry Andric   }
1184*5ffd83dbSDimitry Andric 
1185*5ffd83dbSDimitry Andric   /// Returns the base of this range.
1186*5ffd83dbSDimitry Andric   const BaseT &getBase() const { return base; }
1187*5ffd83dbSDimitry Andric 
1188*5ffd83dbSDimitry Andric private:
1189*5ffd83dbSDimitry Andric   /// Offset the given base by the given amount.
1190*5ffd83dbSDimitry Andric   static BaseT offset_base(const BaseT &base, size_t n) {
1191*5ffd83dbSDimitry Andric     return n == 0 ? base : DerivedT::offset_base(base, n);
1192*5ffd83dbSDimitry Andric   }
1193*5ffd83dbSDimitry Andric 
1194*5ffd83dbSDimitry Andric protected:
1195*5ffd83dbSDimitry Andric   indexed_accessor_range_base(const indexed_accessor_range_base &) = default;
1196*5ffd83dbSDimitry Andric   indexed_accessor_range_base(indexed_accessor_range_base &&) = default;
1197*5ffd83dbSDimitry Andric   indexed_accessor_range_base &
1198*5ffd83dbSDimitry Andric   operator=(const indexed_accessor_range_base &) = default;
1199*5ffd83dbSDimitry Andric 
1200*5ffd83dbSDimitry Andric   /// The base that owns the provided range of values.
1201*5ffd83dbSDimitry Andric   BaseT base;
1202*5ffd83dbSDimitry Andric   /// The size from the owning range.
1203*5ffd83dbSDimitry Andric   ptrdiff_t count;
1204*5ffd83dbSDimitry Andric };
1205*5ffd83dbSDimitry Andric } // end namespace detail
1206*5ffd83dbSDimitry Andric 
1207*5ffd83dbSDimitry Andric /// This class provides an implementation of a range of
1208*5ffd83dbSDimitry Andric /// indexed_accessor_iterators where the base is not indexable. Ranges with
1209*5ffd83dbSDimitry Andric /// bases that are offsetable should derive from indexed_accessor_range_base
1210*5ffd83dbSDimitry Andric /// instead. Derived range classes are expected to implement the following
1211*5ffd83dbSDimitry Andric /// static method:
1212*5ffd83dbSDimitry Andric ///   * ReferenceT dereference(const BaseT &base, ptrdiff_t index)
1213*5ffd83dbSDimitry Andric ///     - Dereference an iterator pointing to a parent base at the given index.
1214*5ffd83dbSDimitry Andric template <typename DerivedT, typename BaseT, typename T,
1215*5ffd83dbSDimitry Andric           typename PointerT = T *, typename ReferenceT = T &>
1216*5ffd83dbSDimitry Andric class indexed_accessor_range
1217*5ffd83dbSDimitry Andric     : public detail::indexed_accessor_range_base<
1218*5ffd83dbSDimitry Andric           DerivedT, std::pair<BaseT, ptrdiff_t>, T, PointerT, ReferenceT> {
1219*5ffd83dbSDimitry Andric public:
1220*5ffd83dbSDimitry Andric   indexed_accessor_range(BaseT base, ptrdiff_t startIndex, ptrdiff_t count)
1221*5ffd83dbSDimitry Andric       : detail::indexed_accessor_range_base<
1222*5ffd83dbSDimitry Andric             DerivedT, std::pair<BaseT, ptrdiff_t>, T, PointerT, ReferenceT>(
1223*5ffd83dbSDimitry Andric             std::make_pair(base, startIndex), count) {}
1224*5ffd83dbSDimitry Andric   using detail::indexed_accessor_range_base<
1225*5ffd83dbSDimitry Andric       DerivedT, std::pair<BaseT, ptrdiff_t>, T, PointerT,
1226*5ffd83dbSDimitry Andric       ReferenceT>::indexed_accessor_range_base;
1227*5ffd83dbSDimitry Andric 
1228*5ffd83dbSDimitry Andric   /// Returns the current base of the range.
1229*5ffd83dbSDimitry Andric   const BaseT &getBase() const { return this->base.first; }
1230*5ffd83dbSDimitry Andric 
1231*5ffd83dbSDimitry Andric   /// Returns the current start index of the range.
1232*5ffd83dbSDimitry Andric   ptrdiff_t getStartIndex() const { return this->base.second; }
1233*5ffd83dbSDimitry Andric 
1234*5ffd83dbSDimitry Andric   /// See `detail::indexed_accessor_range_base` for details.
1235*5ffd83dbSDimitry Andric   static std::pair<BaseT, ptrdiff_t>
1236*5ffd83dbSDimitry Andric   offset_base(const std::pair<BaseT, ptrdiff_t> &base, ptrdiff_t index) {
1237*5ffd83dbSDimitry Andric     // We encode the internal base as a pair of the derived base and a start
1238*5ffd83dbSDimitry Andric     // index into the derived base.
1239*5ffd83dbSDimitry Andric     return std::make_pair(base.first, base.second + index);
1240*5ffd83dbSDimitry Andric   }
1241*5ffd83dbSDimitry Andric   /// See `detail::indexed_accessor_range_base` for details.
1242*5ffd83dbSDimitry Andric   static ReferenceT
1243*5ffd83dbSDimitry Andric   dereference_iterator(const std::pair<BaseT, ptrdiff_t> &base,
1244*5ffd83dbSDimitry Andric                        ptrdiff_t index) {
1245*5ffd83dbSDimitry Andric     return DerivedT::dereference(base.first, base.second + index);
1246*5ffd83dbSDimitry Andric   }
1247*5ffd83dbSDimitry Andric };
1248*5ffd83dbSDimitry Andric 
1249*5ffd83dbSDimitry Andric /// Given a container of pairs, return a range over the second elements.
1250*5ffd83dbSDimitry Andric template <typename ContainerTy> auto make_second_range(ContainerTy &&c) {
1251*5ffd83dbSDimitry Andric   return llvm::map_range(
1252*5ffd83dbSDimitry Andric       std::forward<ContainerTy>(c),
1253*5ffd83dbSDimitry Andric       [](decltype((*std::begin(c))) elt) -> decltype((elt.second)) {
1254*5ffd83dbSDimitry Andric         return elt.second;
1255*5ffd83dbSDimitry Andric       });
1256*5ffd83dbSDimitry Andric }
1257*5ffd83dbSDimitry Andric 
12580b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12590b57cec5SDimitry Andric //     Extra additions to <utility>
12600b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12610b57cec5SDimitry Andric 
12620b57cec5SDimitry Andric /// Function object to check whether the first component of a std::pair
12630b57cec5SDimitry Andric /// compares less than the first component of another std::pair.
12640b57cec5SDimitry Andric struct less_first {
12650b57cec5SDimitry Andric   template <typename T> bool operator()(const T &lhs, const T &rhs) const {
12660b57cec5SDimitry Andric     return lhs.first < rhs.first;
12670b57cec5SDimitry Andric   }
12680b57cec5SDimitry Andric };
12690b57cec5SDimitry Andric 
12700b57cec5SDimitry Andric /// Function object to check whether the second component of a std::pair
12710b57cec5SDimitry Andric /// compares less than the second component of another std::pair.
12720b57cec5SDimitry Andric struct less_second {
12730b57cec5SDimitry Andric   template <typename T> bool operator()(const T &lhs, const T &rhs) const {
12740b57cec5SDimitry Andric     return lhs.second < rhs.second;
12750b57cec5SDimitry Andric   }
12760b57cec5SDimitry Andric };
12770b57cec5SDimitry Andric 
12780b57cec5SDimitry Andric /// \brief Function object to apply a binary function to the first component of
12790b57cec5SDimitry Andric /// a std::pair.
12800b57cec5SDimitry Andric template<typename FuncTy>
12810b57cec5SDimitry Andric struct on_first {
12820b57cec5SDimitry Andric   FuncTy func;
12830b57cec5SDimitry Andric 
12840b57cec5SDimitry Andric   template <typename T>
1285*5ffd83dbSDimitry Andric   decltype(auto) operator()(const T &lhs, const T &rhs) const {
12860b57cec5SDimitry Andric     return func(lhs.first, rhs.first);
12870b57cec5SDimitry Andric   }
12880b57cec5SDimitry Andric };
12890b57cec5SDimitry Andric 
12900b57cec5SDimitry Andric /// Utility type to build an inheritance chain that makes it easy to rank
12910b57cec5SDimitry Andric /// overload candidates.
12920b57cec5SDimitry Andric template <int N> struct rank : rank<N - 1> {};
12930b57cec5SDimitry Andric template <> struct rank<0> {};
12940b57cec5SDimitry Andric 
12950b57cec5SDimitry Andric /// traits class for checking whether type T is one of any of the given
12960b57cec5SDimitry Andric /// types in the variadic list.
12970b57cec5SDimitry Andric template <typename T, typename... Ts> struct is_one_of {
12980b57cec5SDimitry Andric   static const bool value = false;
12990b57cec5SDimitry Andric };
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric template <typename T, typename U, typename... Ts>
13020b57cec5SDimitry Andric struct is_one_of<T, U, Ts...> {
13030b57cec5SDimitry Andric   static const bool value =
13040b57cec5SDimitry Andric       std::is_same<T, U>::value || is_one_of<T, Ts...>::value;
13050b57cec5SDimitry Andric };
13060b57cec5SDimitry Andric 
13070b57cec5SDimitry Andric /// traits class for checking whether type T is a base class for all
13080b57cec5SDimitry Andric ///  the given types in the variadic list.
13090b57cec5SDimitry Andric template <typename T, typename... Ts> struct are_base_of {
13100b57cec5SDimitry Andric   static const bool value = true;
13110b57cec5SDimitry Andric };
13120b57cec5SDimitry Andric 
13130b57cec5SDimitry Andric template <typename T, typename U, typename... Ts>
13140b57cec5SDimitry Andric struct are_base_of<T, U, Ts...> {
13150b57cec5SDimitry Andric   static const bool value =
13160b57cec5SDimitry Andric       std::is_base_of<T, U>::value && are_base_of<T, Ts...>::value;
13170b57cec5SDimitry Andric };
13180b57cec5SDimitry Andric 
13190b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13200b57cec5SDimitry Andric //     Extra additions for arrays
13210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13220b57cec5SDimitry Andric 
1323*5ffd83dbSDimitry Andric // We have a copy here so that LLVM behaves the same when using different
1324*5ffd83dbSDimitry Andric // standard libraries.
1325*5ffd83dbSDimitry Andric template <class Iterator, class RNG>
1326*5ffd83dbSDimitry Andric void shuffle(Iterator first, Iterator last, RNG &&g) {
1327*5ffd83dbSDimitry Andric   // It would be better to use a std::uniform_int_distribution,
1328*5ffd83dbSDimitry Andric   // but that would be stdlib dependent.
1329*5ffd83dbSDimitry Andric   for (auto size = last - first; size > 1; ++first, (void)--size)
1330*5ffd83dbSDimitry Andric     std::iter_swap(first, first + g() % size);
1331*5ffd83dbSDimitry Andric }
1332*5ffd83dbSDimitry Andric 
13330b57cec5SDimitry Andric /// Find the length of an array.
13340b57cec5SDimitry Andric template <class T, std::size_t N>
13350b57cec5SDimitry Andric constexpr inline size_t array_lengthof(T (&)[N]) {
13360b57cec5SDimitry Andric   return N;
13370b57cec5SDimitry Andric }
13380b57cec5SDimitry Andric 
13390b57cec5SDimitry Andric /// Adapt std::less<T> for array_pod_sort.
13400b57cec5SDimitry Andric template<typename T>
13410b57cec5SDimitry Andric inline int array_pod_sort_comparator(const void *P1, const void *P2) {
13420b57cec5SDimitry Andric   if (std::less<T>()(*reinterpret_cast<const T*>(P1),
13430b57cec5SDimitry Andric                      *reinterpret_cast<const T*>(P2)))
13440b57cec5SDimitry Andric     return -1;
13450b57cec5SDimitry Andric   if (std::less<T>()(*reinterpret_cast<const T*>(P2),
13460b57cec5SDimitry Andric                      *reinterpret_cast<const T*>(P1)))
13470b57cec5SDimitry Andric     return 1;
13480b57cec5SDimitry Andric   return 0;
13490b57cec5SDimitry Andric }
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric /// get_array_pod_sort_comparator - This is an internal helper function used to
13520b57cec5SDimitry Andric /// get type deduction of T right.
13530b57cec5SDimitry Andric template<typename T>
13540b57cec5SDimitry Andric inline int (*get_array_pod_sort_comparator(const T &))
13550b57cec5SDimitry Andric              (const void*, const void*) {
13560b57cec5SDimitry Andric   return array_pod_sort_comparator<T>;
13570b57cec5SDimitry Andric }
13580b57cec5SDimitry Andric 
1359480093f4SDimitry Andric #ifdef EXPENSIVE_CHECKS
1360480093f4SDimitry Andric namespace detail {
1361480093f4SDimitry Andric 
1362480093f4SDimitry Andric inline unsigned presortShuffleEntropy() {
1363480093f4SDimitry Andric   static unsigned Result(std::random_device{}());
1364480093f4SDimitry Andric   return Result;
1365480093f4SDimitry Andric }
1366480093f4SDimitry Andric 
1367480093f4SDimitry Andric template <class IteratorTy>
1368480093f4SDimitry Andric inline void presortShuffle(IteratorTy Start, IteratorTy End) {
1369480093f4SDimitry Andric   std::mt19937 Generator(presortShuffleEntropy());
1370480093f4SDimitry Andric   std::shuffle(Start, End, Generator);
1371480093f4SDimitry Andric }
1372480093f4SDimitry Andric 
1373480093f4SDimitry Andric } // end namespace detail
1374480093f4SDimitry Andric #endif
1375480093f4SDimitry Andric 
13760b57cec5SDimitry Andric /// array_pod_sort - This sorts an array with the specified start and end
13770b57cec5SDimitry Andric /// extent.  This is just like std::sort, except that it calls qsort instead of
13780b57cec5SDimitry Andric /// using an inlined template.  qsort is slightly slower than std::sort, but
13790b57cec5SDimitry Andric /// most sorts are not performance critical in LLVM and std::sort has to be
13800b57cec5SDimitry Andric /// template instantiated for each type, leading to significant measured code
13810b57cec5SDimitry Andric /// bloat.  This function should generally be used instead of std::sort where
13820b57cec5SDimitry Andric /// possible.
13830b57cec5SDimitry Andric ///
13840b57cec5SDimitry Andric /// This function assumes that you have simple POD-like types that can be
13850b57cec5SDimitry Andric /// compared with std::less and can be moved with memcpy.  If this isn't true,
13860b57cec5SDimitry Andric /// you should use std::sort.
13870b57cec5SDimitry Andric ///
13880b57cec5SDimitry Andric /// NOTE: If qsort_r were portable, we could allow a custom comparator and
13890b57cec5SDimitry Andric /// default to std::less.
13900b57cec5SDimitry Andric template<class IteratorTy>
13910b57cec5SDimitry Andric inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
13920b57cec5SDimitry Andric   // Don't inefficiently call qsort with one element or trigger undefined
13930b57cec5SDimitry Andric   // behavior with an empty sequence.
13940b57cec5SDimitry Andric   auto NElts = End - Start;
13950b57cec5SDimitry Andric   if (NElts <= 1) return;
13960b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
1397480093f4SDimitry Andric   detail::presortShuffle<IteratorTy>(Start, End);
13980b57cec5SDimitry Andric #endif
13990b57cec5SDimitry Andric   qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start));
14000b57cec5SDimitry Andric }
14010b57cec5SDimitry Andric 
14020b57cec5SDimitry Andric template <class IteratorTy>
14030b57cec5SDimitry Andric inline void array_pod_sort(
14040b57cec5SDimitry Andric     IteratorTy Start, IteratorTy End,
14050b57cec5SDimitry Andric     int (*Compare)(
14060b57cec5SDimitry Andric         const typename std::iterator_traits<IteratorTy>::value_type *,
14070b57cec5SDimitry Andric         const typename std::iterator_traits<IteratorTy>::value_type *)) {
14080b57cec5SDimitry Andric   // Don't inefficiently call qsort with one element or trigger undefined
14090b57cec5SDimitry Andric   // behavior with an empty sequence.
14100b57cec5SDimitry Andric   auto NElts = End - Start;
14110b57cec5SDimitry Andric   if (NElts <= 1) return;
14120b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
1413480093f4SDimitry Andric   detail::presortShuffle<IteratorTy>(Start, End);
14140b57cec5SDimitry Andric #endif
14150b57cec5SDimitry Andric   qsort(&*Start, NElts, sizeof(*Start),
14160b57cec5SDimitry Andric         reinterpret_cast<int (*)(const void *, const void *)>(Compare));
14170b57cec5SDimitry Andric }
14180b57cec5SDimitry Andric 
1419*5ffd83dbSDimitry Andric namespace detail {
1420*5ffd83dbSDimitry Andric template <typename T>
1421*5ffd83dbSDimitry Andric // We can use qsort if the iterator type is a pointer and the underlying value
1422*5ffd83dbSDimitry Andric // is trivially copyable.
1423*5ffd83dbSDimitry Andric using sort_trivially_copyable = conjunction<
1424*5ffd83dbSDimitry Andric     std::is_pointer<T>,
1425*5ffd83dbSDimitry Andric     is_trivially_copyable<typename std::iterator_traits<T>::value_type>>;
1426*5ffd83dbSDimitry Andric } // namespace detail
1427*5ffd83dbSDimitry Andric 
14280b57cec5SDimitry Andric // Provide wrappers to std::sort which shuffle the elements before sorting
14290b57cec5SDimitry Andric // to help uncover non-deterministic behavior (PR35135).
1430*5ffd83dbSDimitry Andric template <typename IteratorTy,
1431*5ffd83dbSDimitry Andric           std::enable_if_t<!detail::sort_trivially_copyable<IteratorTy>::value,
1432*5ffd83dbSDimitry Andric                            int> = 0>
14330b57cec5SDimitry Andric inline void sort(IteratorTy Start, IteratorTy End) {
14340b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
1435480093f4SDimitry Andric   detail::presortShuffle<IteratorTy>(Start, End);
14360b57cec5SDimitry Andric #endif
14370b57cec5SDimitry Andric   std::sort(Start, End);
14380b57cec5SDimitry Andric }
14390b57cec5SDimitry Andric 
1440*5ffd83dbSDimitry Andric // Forward trivially copyable types to array_pod_sort. This avoids a large
1441*5ffd83dbSDimitry Andric // amount of code bloat for a minor performance hit.
1442*5ffd83dbSDimitry Andric template <typename IteratorTy,
1443*5ffd83dbSDimitry Andric           std::enable_if_t<detail::sort_trivially_copyable<IteratorTy>::value,
1444*5ffd83dbSDimitry Andric                            int> = 0>
1445*5ffd83dbSDimitry Andric inline void sort(IteratorTy Start, IteratorTy End) {
1446*5ffd83dbSDimitry Andric   array_pod_sort(Start, End);
1447*5ffd83dbSDimitry Andric }
1448*5ffd83dbSDimitry Andric 
14490b57cec5SDimitry Andric template <typename Container> inline void sort(Container &&C) {
14500b57cec5SDimitry Andric   llvm::sort(adl_begin(C), adl_end(C));
14510b57cec5SDimitry Andric }
14520b57cec5SDimitry Andric 
14530b57cec5SDimitry Andric template <typename IteratorTy, typename Compare>
14540b57cec5SDimitry Andric inline void sort(IteratorTy Start, IteratorTy End, Compare Comp) {
14550b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
1456480093f4SDimitry Andric   detail::presortShuffle<IteratorTy>(Start, End);
14570b57cec5SDimitry Andric #endif
14580b57cec5SDimitry Andric   std::sort(Start, End, Comp);
14590b57cec5SDimitry Andric }
14600b57cec5SDimitry Andric 
14610b57cec5SDimitry Andric template <typename Container, typename Compare>
14620b57cec5SDimitry Andric inline void sort(Container &&C, Compare Comp) {
14630b57cec5SDimitry Andric   llvm::sort(adl_begin(C), adl_end(C), Comp);
14640b57cec5SDimitry Andric }
14650b57cec5SDimitry Andric 
14660b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14670b57cec5SDimitry Andric //     Extra additions to <algorithm>
14680b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric /// Get the size of a range. This is a wrapper function around std::distance
14710b57cec5SDimitry Andric /// which is only enabled when the operation is O(1).
14720b57cec5SDimitry Andric template <typename R>
1473*5ffd83dbSDimitry Andric auto size(R &&Range,
1474*5ffd83dbSDimitry Andric           std::enable_if_t<std::is_same<typename std::iterator_traits<decltype(
14750b57cec5SDimitry Andric                                             Range.begin())>::iterator_category,
14760b57cec5SDimitry Andric                                         std::random_access_iterator_tag>::value,
1477*5ffd83dbSDimitry Andric                            void> * = nullptr) {
14780b57cec5SDimitry Andric   return std::distance(Range.begin(), Range.end());
14790b57cec5SDimitry Andric }
14800b57cec5SDimitry Andric 
14810b57cec5SDimitry Andric /// Provide wrappers to std::for_each which take ranges instead of having to
14820b57cec5SDimitry Andric /// pass begin/end explicitly.
14830b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
14840b57cec5SDimitry Andric UnaryPredicate for_each(R &&Range, UnaryPredicate P) {
14850b57cec5SDimitry Andric   return std::for_each(adl_begin(Range), adl_end(Range), P);
14860b57cec5SDimitry Andric }
14870b57cec5SDimitry Andric 
14880b57cec5SDimitry Andric /// Provide wrappers to std::all_of which take ranges instead of having to pass
14890b57cec5SDimitry Andric /// begin/end explicitly.
14900b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
14910b57cec5SDimitry Andric bool all_of(R &&Range, UnaryPredicate P) {
14920b57cec5SDimitry Andric   return std::all_of(adl_begin(Range), adl_end(Range), P);
14930b57cec5SDimitry Andric }
14940b57cec5SDimitry Andric 
14950b57cec5SDimitry Andric /// Provide wrappers to std::any_of which take ranges instead of having to pass
14960b57cec5SDimitry Andric /// begin/end explicitly.
14970b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
14980b57cec5SDimitry Andric bool any_of(R &&Range, UnaryPredicate P) {
14990b57cec5SDimitry Andric   return std::any_of(adl_begin(Range), adl_end(Range), P);
15000b57cec5SDimitry Andric }
15010b57cec5SDimitry Andric 
15020b57cec5SDimitry Andric /// Provide wrappers to std::none_of which take ranges instead of having to pass
15030b57cec5SDimitry Andric /// begin/end explicitly.
15040b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
15050b57cec5SDimitry Andric bool none_of(R &&Range, UnaryPredicate P) {
15060b57cec5SDimitry Andric   return std::none_of(adl_begin(Range), adl_end(Range), P);
15070b57cec5SDimitry Andric }
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric /// Provide wrappers to std::find which take ranges instead of having to pass
15100b57cec5SDimitry Andric /// begin/end explicitly.
1511*5ffd83dbSDimitry Andric template <typename R, typename T> auto find(R &&Range, const T &Val) {
15120b57cec5SDimitry Andric   return std::find(adl_begin(Range), adl_end(Range), Val);
15130b57cec5SDimitry Andric }
15140b57cec5SDimitry Andric 
15150b57cec5SDimitry Andric /// Provide wrappers to std::find_if which take ranges instead of having to pass
15160b57cec5SDimitry Andric /// begin/end explicitly.
15170b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1518*5ffd83dbSDimitry Andric auto find_if(R &&Range, UnaryPredicate P) {
15190b57cec5SDimitry Andric   return std::find_if(adl_begin(Range), adl_end(Range), P);
15200b57cec5SDimitry Andric }
15210b57cec5SDimitry Andric 
15220b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1523*5ffd83dbSDimitry Andric auto find_if_not(R &&Range, UnaryPredicate P) {
15240b57cec5SDimitry Andric   return std::find_if_not(adl_begin(Range), adl_end(Range), P);
15250b57cec5SDimitry Andric }
15260b57cec5SDimitry Andric 
15270b57cec5SDimitry Andric /// Provide wrappers to std::remove_if which take ranges instead of having to
15280b57cec5SDimitry Andric /// pass begin/end explicitly.
15290b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1530*5ffd83dbSDimitry Andric auto remove_if(R &&Range, UnaryPredicate P) {
15310b57cec5SDimitry Andric   return std::remove_if(adl_begin(Range), adl_end(Range), P);
15320b57cec5SDimitry Andric }
15330b57cec5SDimitry Andric 
15340b57cec5SDimitry Andric /// Provide wrappers to std::copy_if which take ranges instead of having to
15350b57cec5SDimitry Andric /// pass begin/end explicitly.
15360b57cec5SDimitry Andric template <typename R, typename OutputIt, typename UnaryPredicate>
15370b57cec5SDimitry Andric OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) {
15380b57cec5SDimitry Andric   return std::copy_if(adl_begin(Range), adl_end(Range), Out, P);
15390b57cec5SDimitry Andric }
15400b57cec5SDimitry Andric 
15410b57cec5SDimitry Andric template <typename R, typename OutputIt>
15420b57cec5SDimitry Andric OutputIt copy(R &&Range, OutputIt Out) {
15430b57cec5SDimitry Andric   return std::copy(adl_begin(Range), adl_end(Range), Out);
15440b57cec5SDimitry Andric }
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric /// Wrapper function around std::find to detect if an element exists
15470b57cec5SDimitry Andric /// in a container.
15480b57cec5SDimitry Andric template <typename R, typename E>
15490b57cec5SDimitry Andric bool is_contained(R &&Range, const E &Element) {
15500b57cec5SDimitry Andric   return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range);
15510b57cec5SDimitry Andric }
15520b57cec5SDimitry Andric 
1553*5ffd83dbSDimitry Andric /// Wrapper function around std::is_sorted to check if elements in a range \p R
1554*5ffd83dbSDimitry Andric /// are sorted with respect to a comparator \p C.
1555*5ffd83dbSDimitry Andric template <typename R, typename Compare> bool is_sorted(R &&Range, Compare C) {
1556*5ffd83dbSDimitry Andric   return std::is_sorted(adl_begin(Range), adl_end(Range), C);
1557*5ffd83dbSDimitry Andric }
1558*5ffd83dbSDimitry Andric 
1559*5ffd83dbSDimitry Andric /// Wrapper function around std::is_sorted to check if elements in a range \p R
1560*5ffd83dbSDimitry Andric /// are sorted in non-descending order.
1561*5ffd83dbSDimitry Andric template <typename R> bool is_sorted(R &&Range) {
1562*5ffd83dbSDimitry Andric   return std::is_sorted(adl_begin(Range), adl_end(Range));
1563*5ffd83dbSDimitry Andric }
1564*5ffd83dbSDimitry Andric 
15650b57cec5SDimitry Andric /// Wrapper function around std::count to count the number of times an element
15660b57cec5SDimitry Andric /// \p Element occurs in the given range \p Range.
1567*5ffd83dbSDimitry Andric template <typename R, typename E> auto count(R &&Range, const E &Element) {
15680b57cec5SDimitry Andric   return std::count(adl_begin(Range), adl_end(Range), Element);
15690b57cec5SDimitry Andric }
15700b57cec5SDimitry Andric 
15710b57cec5SDimitry Andric /// Wrapper function around std::count_if to count the number of times an
15720b57cec5SDimitry Andric /// element satisfying a given predicate occurs in a range.
15730b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1574*5ffd83dbSDimitry Andric auto count_if(R &&Range, UnaryPredicate P) {
15750b57cec5SDimitry Andric   return std::count_if(adl_begin(Range), adl_end(Range), P);
15760b57cec5SDimitry Andric }
15770b57cec5SDimitry Andric 
15780b57cec5SDimitry Andric /// Wrapper function around std::transform to apply a function to a range and
15790b57cec5SDimitry Andric /// store the result elsewhere.
15800b57cec5SDimitry Andric template <typename R, typename OutputIt, typename UnaryPredicate>
15810b57cec5SDimitry Andric OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P) {
15820b57cec5SDimitry Andric   return std::transform(adl_begin(Range), adl_end(Range), d_first, P);
15830b57cec5SDimitry Andric }
15840b57cec5SDimitry Andric 
15850b57cec5SDimitry Andric /// Provide wrappers to std::partition which take ranges instead of having to
15860b57cec5SDimitry Andric /// pass begin/end explicitly.
15870b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1588*5ffd83dbSDimitry Andric auto partition(R &&Range, UnaryPredicate P) {
15890b57cec5SDimitry Andric   return std::partition(adl_begin(Range), adl_end(Range), P);
15900b57cec5SDimitry Andric }
15910b57cec5SDimitry Andric 
15920b57cec5SDimitry Andric /// Provide wrappers to std::lower_bound which take ranges instead of having to
15930b57cec5SDimitry Andric /// pass begin/end explicitly.
1594*5ffd83dbSDimitry Andric template <typename R, typename T> auto lower_bound(R &&Range, T &&Value) {
15950b57cec5SDimitry Andric   return std::lower_bound(adl_begin(Range), adl_end(Range),
15960b57cec5SDimitry Andric                           std::forward<T>(Value));
15970b57cec5SDimitry Andric }
15980b57cec5SDimitry Andric 
15990b57cec5SDimitry Andric template <typename R, typename T, typename Compare>
1600*5ffd83dbSDimitry Andric auto lower_bound(R &&Range, T &&Value, Compare C) {
16010b57cec5SDimitry Andric   return std::lower_bound(adl_begin(Range), adl_end(Range),
16020b57cec5SDimitry Andric                           std::forward<T>(Value), C);
16030b57cec5SDimitry Andric }
16040b57cec5SDimitry Andric 
16050b57cec5SDimitry Andric /// Provide wrappers to std::upper_bound which take ranges instead of having to
16060b57cec5SDimitry Andric /// pass begin/end explicitly.
1607*5ffd83dbSDimitry Andric template <typename R, typename T> auto upper_bound(R &&Range, T &&Value) {
16080b57cec5SDimitry Andric   return std::upper_bound(adl_begin(Range), adl_end(Range),
16090b57cec5SDimitry Andric                           std::forward<T>(Value));
16100b57cec5SDimitry Andric }
16110b57cec5SDimitry Andric 
16120b57cec5SDimitry Andric template <typename R, typename T, typename Compare>
1613*5ffd83dbSDimitry Andric auto upper_bound(R &&Range, T &&Value, Compare C) {
16140b57cec5SDimitry Andric   return std::upper_bound(adl_begin(Range), adl_end(Range),
16150b57cec5SDimitry Andric                           std::forward<T>(Value), C);
16160b57cec5SDimitry Andric }
16170b57cec5SDimitry Andric 
16180b57cec5SDimitry Andric template <typename R>
16190b57cec5SDimitry Andric void stable_sort(R &&Range) {
16200b57cec5SDimitry Andric   std::stable_sort(adl_begin(Range), adl_end(Range));
16210b57cec5SDimitry Andric }
16220b57cec5SDimitry Andric 
16230b57cec5SDimitry Andric template <typename R, typename Compare>
16240b57cec5SDimitry Andric void stable_sort(R &&Range, Compare C) {
16250b57cec5SDimitry Andric   std::stable_sort(adl_begin(Range), adl_end(Range), C);
16260b57cec5SDimitry Andric }
16270b57cec5SDimitry Andric 
16280b57cec5SDimitry Andric /// Binary search for the first iterator in a range where a predicate is false.
16290b57cec5SDimitry Andric /// Requires that C is always true below some limit, and always false above it.
16300b57cec5SDimitry Andric template <typename R, typename Predicate,
16310b57cec5SDimitry Andric           typename Val = decltype(*adl_begin(std::declval<R>()))>
1632*5ffd83dbSDimitry Andric auto partition_point(R &&Range, Predicate P) {
16330b57cec5SDimitry Andric   return std::partition_point(adl_begin(Range), adl_end(Range), P);
16340b57cec5SDimitry Andric }
16350b57cec5SDimitry Andric 
16360b57cec5SDimitry Andric /// Wrapper function around std::equal to detect if all elements
16370b57cec5SDimitry Andric /// in a container are same.
16380b57cec5SDimitry Andric template <typename R>
16390b57cec5SDimitry Andric bool is_splat(R &&Range) {
16400b57cec5SDimitry Andric   size_t range_size = size(Range);
16410b57cec5SDimitry Andric   return range_size != 0 && (range_size == 1 ||
16420b57cec5SDimitry Andric          std::equal(adl_begin(Range) + 1, adl_end(Range), adl_begin(Range)));
16430b57cec5SDimitry Andric }
16440b57cec5SDimitry Andric 
16450b57cec5SDimitry Andric /// Provide a container algorithm similar to C++ Library Fundamentals v2's
16460b57cec5SDimitry Andric /// `erase_if` which is equivalent to:
16470b57cec5SDimitry Andric ///
16480b57cec5SDimitry Andric ///   C.erase(remove_if(C, pred), C.end());
16490b57cec5SDimitry Andric ///
16500b57cec5SDimitry Andric /// This version works for any container with an erase method call accepting
16510b57cec5SDimitry Andric /// two iterators.
16520b57cec5SDimitry Andric template <typename Container, typename UnaryPredicate>
16530b57cec5SDimitry Andric void erase_if(Container &C, UnaryPredicate P) {
16540b57cec5SDimitry Andric   C.erase(remove_if(C, P), C.end());
16550b57cec5SDimitry Andric }
16560b57cec5SDimitry Andric 
16570b57cec5SDimitry Andric /// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
16580b57cec5SDimitry Andric /// the range [ValIt, ValEnd) (which is not from the same container).
16590b57cec5SDimitry Andric template<typename Container, typename RandomAccessIterator>
16600b57cec5SDimitry Andric void replace(Container &Cont, typename Container::iterator ContIt,
16610b57cec5SDimitry Andric              typename Container::iterator ContEnd, RandomAccessIterator ValIt,
16620b57cec5SDimitry Andric              RandomAccessIterator ValEnd) {
16630b57cec5SDimitry Andric   while (true) {
16640b57cec5SDimitry Andric     if (ValIt == ValEnd) {
16650b57cec5SDimitry Andric       Cont.erase(ContIt, ContEnd);
16660b57cec5SDimitry Andric       return;
16670b57cec5SDimitry Andric     } else if (ContIt == ContEnd) {
16680b57cec5SDimitry Andric       Cont.insert(ContIt, ValIt, ValEnd);
16690b57cec5SDimitry Andric       return;
16700b57cec5SDimitry Andric     }
16710b57cec5SDimitry Andric     *ContIt++ = *ValIt++;
16720b57cec5SDimitry Andric   }
16730b57cec5SDimitry Andric }
16740b57cec5SDimitry Andric 
16750b57cec5SDimitry Andric /// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
16760b57cec5SDimitry Andric /// the range R.
16770b57cec5SDimitry Andric template<typename Container, typename Range = std::initializer_list<
16780b57cec5SDimitry Andric                                  typename Container::value_type>>
16790b57cec5SDimitry Andric void replace(Container &Cont, typename Container::iterator ContIt,
16800b57cec5SDimitry Andric              typename Container::iterator ContEnd, Range R) {
16810b57cec5SDimitry Andric   replace(Cont, ContIt, ContEnd, R.begin(), R.end());
16820b57cec5SDimitry Andric }
16830b57cec5SDimitry Andric 
1684*5ffd83dbSDimitry Andric /// An STL-style algorithm similar to std::for_each that applies a second
1685*5ffd83dbSDimitry Andric /// functor between every pair of elements.
1686*5ffd83dbSDimitry Andric ///
1687*5ffd83dbSDimitry Andric /// This provides the control flow logic to, for example, print a
1688*5ffd83dbSDimitry Andric /// comma-separated list:
1689*5ffd83dbSDimitry Andric /// \code
1690*5ffd83dbSDimitry Andric ///   interleave(names.begin(), names.end(),
1691*5ffd83dbSDimitry Andric ///              [&](StringRef name) { os << name; },
1692*5ffd83dbSDimitry Andric ///              [&] { os << ", "; });
1693*5ffd83dbSDimitry Andric /// \endcode
1694*5ffd83dbSDimitry Andric template <typename ForwardIterator, typename UnaryFunctor,
1695*5ffd83dbSDimitry Andric           typename NullaryFunctor,
1696*5ffd83dbSDimitry Andric           typename = typename std::enable_if<
1697*5ffd83dbSDimitry Andric               !std::is_constructible<StringRef, UnaryFunctor>::value &&
1698*5ffd83dbSDimitry Andric               !std::is_constructible<StringRef, NullaryFunctor>::value>::type>
1699*5ffd83dbSDimitry Andric inline void interleave(ForwardIterator begin, ForwardIterator end,
1700*5ffd83dbSDimitry Andric                        UnaryFunctor each_fn, NullaryFunctor between_fn) {
1701*5ffd83dbSDimitry Andric   if (begin == end)
1702*5ffd83dbSDimitry Andric     return;
1703*5ffd83dbSDimitry Andric   each_fn(*begin);
1704*5ffd83dbSDimitry Andric   ++begin;
1705*5ffd83dbSDimitry Andric   for (; begin != end; ++begin) {
1706*5ffd83dbSDimitry Andric     between_fn();
1707*5ffd83dbSDimitry Andric     each_fn(*begin);
1708*5ffd83dbSDimitry Andric   }
1709*5ffd83dbSDimitry Andric }
1710*5ffd83dbSDimitry Andric 
1711*5ffd83dbSDimitry Andric template <typename Container, typename UnaryFunctor, typename NullaryFunctor,
1712*5ffd83dbSDimitry Andric           typename = typename std::enable_if<
1713*5ffd83dbSDimitry Andric               !std::is_constructible<StringRef, UnaryFunctor>::value &&
1714*5ffd83dbSDimitry Andric               !std::is_constructible<StringRef, NullaryFunctor>::value>::type>
1715*5ffd83dbSDimitry Andric inline void interleave(const Container &c, UnaryFunctor each_fn,
1716*5ffd83dbSDimitry Andric                        NullaryFunctor between_fn) {
1717*5ffd83dbSDimitry Andric   interleave(c.begin(), c.end(), each_fn, between_fn);
1718*5ffd83dbSDimitry Andric }
1719*5ffd83dbSDimitry Andric 
1720*5ffd83dbSDimitry Andric /// Overload of interleave for the common case of string separator.
1721*5ffd83dbSDimitry Andric template <typename Container, typename UnaryFunctor, typename StreamT,
1722*5ffd83dbSDimitry Andric           typename T = detail::ValueOfRange<Container>>
1723*5ffd83dbSDimitry Andric inline void interleave(const Container &c, StreamT &os, UnaryFunctor each_fn,
1724*5ffd83dbSDimitry Andric                        const StringRef &separator) {
1725*5ffd83dbSDimitry Andric   interleave(c.begin(), c.end(), each_fn, [&] { os << separator; });
1726*5ffd83dbSDimitry Andric }
1727*5ffd83dbSDimitry Andric template <typename Container, typename StreamT,
1728*5ffd83dbSDimitry Andric           typename T = detail::ValueOfRange<Container>>
1729*5ffd83dbSDimitry Andric inline void interleave(const Container &c, StreamT &os,
1730*5ffd83dbSDimitry Andric                        const StringRef &separator) {
1731*5ffd83dbSDimitry Andric   interleave(
1732*5ffd83dbSDimitry Andric       c, os, [&](const T &a) { os << a; }, separator);
1733*5ffd83dbSDimitry Andric }
1734*5ffd83dbSDimitry Andric 
1735*5ffd83dbSDimitry Andric template <typename Container, typename UnaryFunctor, typename StreamT,
1736*5ffd83dbSDimitry Andric           typename T = detail::ValueOfRange<Container>>
1737*5ffd83dbSDimitry Andric inline void interleaveComma(const Container &c, StreamT &os,
1738*5ffd83dbSDimitry Andric                             UnaryFunctor each_fn) {
1739*5ffd83dbSDimitry Andric   interleave(c, os, each_fn, ", ");
1740*5ffd83dbSDimitry Andric }
1741*5ffd83dbSDimitry Andric template <typename Container, typename StreamT,
1742*5ffd83dbSDimitry Andric           typename T = detail::ValueOfRange<Container>>
1743*5ffd83dbSDimitry Andric inline void interleaveComma(const Container &c, StreamT &os) {
1744*5ffd83dbSDimitry Andric   interleaveComma(c, os, [&](const T &a) { os << a; });
1745*5ffd83dbSDimitry Andric }
1746*5ffd83dbSDimitry Andric 
17470b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
17480b57cec5SDimitry Andric //     Extra additions to <memory>
17490b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
17500b57cec5SDimitry Andric 
17510b57cec5SDimitry Andric struct FreeDeleter {
17520b57cec5SDimitry Andric   void operator()(void* v) {
17530b57cec5SDimitry Andric     ::free(v);
17540b57cec5SDimitry Andric   }
17550b57cec5SDimitry Andric };
17560b57cec5SDimitry Andric 
17570b57cec5SDimitry Andric template<typename First, typename Second>
17580b57cec5SDimitry Andric struct pair_hash {
17590b57cec5SDimitry Andric   size_t operator()(const std::pair<First, Second> &P) const {
17600b57cec5SDimitry Andric     return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
17610b57cec5SDimitry Andric   }
17620b57cec5SDimitry Andric };
17630b57cec5SDimitry Andric 
17640b57cec5SDimitry Andric /// Binary functor that adapts to any other binary functor after dereferencing
17650b57cec5SDimitry Andric /// operands.
17660b57cec5SDimitry Andric template <typename T> struct deref {
17670b57cec5SDimitry Andric   T func;
17680b57cec5SDimitry Andric 
17690b57cec5SDimitry Andric   // Could be further improved to cope with non-derivable functors and
17700b57cec5SDimitry Andric   // non-binary functors (should be a variadic template member function
17710b57cec5SDimitry Andric   // operator()).
1772*5ffd83dbSDimitry Andric   template <typename A, typename B> auto operator()(A &lhs, B &rhs) const {
17730b57cec5SDimitry Andric     assert(lhs);
17740b57cec5SDimitry Andric     assert(rhs);
17750b57cec5SDimitry Andric     return func(*lhs, *rhs);
17760b57cec5SDimitry Andric   }
17770b57cec5SDimitry Andric };
17780b57cec5SDimitry Andric 
17790b57cec5SDimitry Andric namespace detail {
17800b57cec5SDimitry Andric 
17810b57cec5SDimitry Andric template <typename R> class enumerator_iter;
17820b57cec5SDimitry Andric 
17830b57cec5SDimitry Andric template <typename R> struct result_pair {
17840b57cec5SDimitry Andric   using value_reference =
17850b57cec5SDimitry Andric       typename std::iterator_traits<IterOfRange<R>>::reference;
17860b57cec5SDimitry Andric 
17870b57cec5SDimitry Andric   friend class enumerator_iter<R>;
17880b57cec5SDimitry Andric 
17890b57cec5SDimitry Andric   result_pair() = default;
17900b57cec5SDimitry Andric   result_pair(std::size_t Index, IterOfRange<R> Iter)
17910b57cec5SDimitry Andric       : Index(Index), Iter(Iter) {}
17920b57cec5SDimitry Andric 
1793480093f4SDimitry Andric   result_pair<R>(const result_pair<R> &Other)
1794480093f4SDimitry Andric       : Index(Other.Index), Iter(Other.Iter) {}
17950b57cec5SDimitry Andric   result_pair<R> &operator=(const result_pair<R> &Other) {
17960b57cec5SDimitry Andric     Index = Other.Index;
17970b57cec5SDimitry Andric     Iter = Other.Iter;
17980b57cec5SDimitry Andric     return *this;
17990b57cec5SDimitry Andric   }
18000b57cec5SDimitry Andric 
18010b57cec5SDimitry Andric   std::size_t index() const { return Index; }
18020b57cec5SDimitry Andric   const value_reference value() const { return *Iter; }
18030b57cec5SDimitry Andric   value_reference value() { return *Iter; }
18040b57cec5SDimitry Andric 
18050b57cec5SDimitry Andric private:
18060b57cec5SDimitry Andric   std::size_t Index = std::numeric_limits<std::size_t>::max();
18070b57cec5SDimitry Andric   IterOfRange<R> Iter;
18080b57cec5SDimitry Andric };
18090b57cec5SDimitry Andric 
18100b57cec5SDimitry Andric template <typename R>
18110b57cec5SDimitry Andric class enumerator_iter
18120b57cec5SDimitry Andric     : public iterator_facade_base<
18130b57cec5SDimitry Andric           enumerator_iter<R>, std::forward_iterator_tag, result_pair<R>,
18140b57cec5SDimitry Andric           typename std::iterator_traits<IterOfRange<R>>::difference_type,
18150b57cec5SDimitry Andric           typename std::iterator_traits<IterOfRange<R>>::pointer,
18160b57cec5SDimitry Andric           typename std::iterator_traits<IterOfRange<R>>::reference> {
18170b57cec5SDimitry Andric   using result_type = result_pair<R>;
18180b57cec5SDimitry Andric 
18190b57cec5SDimitry Andric public:
18200b57cec5SDimitry Andric   explicit enumerator_iter(IterOfRange<R> EndIter)
18210b57cec5SDimitry Andric       : Result(std::numeric_limits<size_t>::max(), EndIter) {}
18220b57cec5SDimitry Andric 
18230b57cec5SDimitry Andric   enumerator_iter(std::size_t Index, IterOfRange<R> Iter)
18240b57cec5SDimitry Andric       : Result(Index, Iter) {}
18250b57cec5SDimitry Andric 
18260b57cec5SDimitry Andric   result_type &operator*() { return Result; }
18270b57cec5SDimitry Andric   const result_type &operator*() const { return Result; }
18280b57cec5SDimitry Andric 
18290b57cec5SDimitry Andric   enumerator_iter<R> &operator++() {
18300b57cec5SDimitry Andric     assert(Result.Index != std::numeric_limits<size_t>::max());
18310b57cec5SDimitry Andric     ++Result.Iter;
18320b57cec5SDimitry Andric     ++Result.Index;
18330b57cec5SDimitry Andric     return *this;
18340b57cec5SDimitry Andric   }
18350b57cec5SDimitry Andric 
18360b57cec5SDimitry Andric   bool operator==(const enumerator_iter<R> &RHS) const {
18370b57cec5SDimitry Andric     // Don't compare indices here, only iterators.  It's possible for an end
18380b57cec5SDimitry Andric     // iterator to have different indices depending on whether it was created
18390b57cec5SDimitry Andric     // by calling std::end() versus incrementing a valid iterator.
18400b57cec5SDimitry Andric     return Result.Iter == RHS.Result.Iter;
18410b57cec5SDimitry Andric   }
18420b57cec5SDimitry Andric 
1843480093f4SDimitry Andric   enumerator_iter<R>(const enumerator_iter<R> &Other) : Result(Other.Result) {}
18440b57cec5SDimitry Andric   enumerator_iter<R> &operator=(const enumerator_iter<R> &Other) {
18450b57cec5SDimitry Andric     Result = Other.Result;
18460b57cec5SDimitry Andric     return *this;
18470b57cec5SDimitry Andric   }
18480b57cec5SDimitry Andric 
18490b57cec5SDimitry Andric private:
18500b57cec5SDimitry Andric   result_type Result;
18510b57cec5SDimitry Andric };
18520b57cec5SDimitry Andric 
18530b57cec5SDimitry Andric template <typename R> class enumerator {
18540b57cec5SDimitry Andric public:
18550b57cec5SDimitry Andric   explicit enumerator(R &&Range) : TheRange(std::forward<R>(Range)) {}
18560b57cec5SDimitry Andric 
18570b57cec5SDimitry Andric   enumerator_iter<R> begin() {
18580b57cec5SDimitry Andric     return enumerator_iter<R>(0, std::begin(TheRange));
18590b57cec5SDimitry Andric   }
18600b57cec5SDimitry Andric 
18610b57cec5SDimitry Andric   enumerator_iter<R> end() {
18620b57cec5SDimitry Andric     return enumerator_iter<R>(std::end(TheRange));
18630b57cec5SDimitry Andric   }
18640b57cec5SDimitry Andric 
18650b57cec5SDimitry Andric private:
18660b57cec5SDimitry Andric   R TheRange;
18670b57cec5SDimitry Andric };
18680b57cec5SDimitry Andric 
18690b57cec5SDimitry Andric } // end namespace detail
18700b57cec5SDimitry Andric 
18710b57cec5SDimitry Andric /// Given an input range, returns a new range whose values are are pair (A,B)
18720b57cec5SDimitry Andric /// such that A is the 0-based index of the item in the sequence, and B is
18730b57cec5SDimitry Andric /// the value from the original sequence.  Example:
18740b57cec5SDimitry Andric ///
18750b57cec5SDimitry Andric /// std::vector<char> Items = {'A', 'B', 'C', 'D'};
18760b57cec5SDimitry Andric /// for (auto X : enumerate(Items)) {
18770b57cec5SDimitry Andric ///   printf("Item %d - %c\n", X.index(), X.value());
18780b57cec5SDimitry Andric /// }
18790b57cec5SDimitry Andric ///
18800b57cec5SDimitry Andric /// Output:
18810b57cec5SDimitry Andric ///   Item 0 - A
18820b57cec5SDimitry Andric ///   Item 1 - B
18830b57cec5SDimitry Andric ///   Item 2 - C
18840b57cec5SDimitry Andric ///   Item 3 - D
18850b57cec5SDimitry Andric ///
18860b57cec5SDimitry Andric template <typename R> detail::enumerator<R> enumerate(R &&TheRange) {
18870b57cec5SDimitry Andric   return detail::enumerator<R>(std::forward<R>(TheRange));
18880b57cec5SDimitry Andric }
18890b57cec5SDimitry Andric 
18900b57cec5SDimitry Andric namespace detail {
18910b57cec5SDimitry Andric 
18920b57cec5SDimitry Andric template <typename F, typename Tuple, std::size_t... I>
1893*5ffd83dbSDimitry Andric decltype(auto) apply_tuple_impl(F &&f, Tuple &&t, std::index_sequence<I...>) {
18940b57cec5SDimitry Andric   return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
18950b57cec5SDimitry Andric }
18960b57cec5SDimitry Andric 
18970b57cec5SDimitry Andric } // end namespace detail
18980b57cec5SDimitry Andric 
18990b57cec5SDimitry Andric /// Given an input tuple (a1, a2, ..., an), pass the arguments of the
19000b57cec5SDimitry Andric /// tuple variadically to f as if by calling f(a1, a2, ..., an) and
19010b57cec5SDimitry Andric /// return the result.
19020b57cec5SDimitry Andric template <typename F, typename Tuple>
1903*5ffd83dbSDimitry Andric decltype(auto) apply_tuple(F &&f, Tuple &&t) {
19048bcb0991SDimitry Andric   using Indices = std::make_index_sequence<
19050b57cec5SDimitry Andric       std::tuple_size<typename std::decay<Tuple>::type>::value>;
19060b57cec5SDimitry Andric 
19070b57cec5SDimitry Andric   return detail::apply_tuple_impl(std::forward<F>(f), std::forward<Tuple>(t),
19080b57cec5SDimitry Andric                                   Indices{});
19090b57cec5SDimitry Andric }
19100b57cec5SDimitry Andric 
19110b57cec5SDimitry Andric /// Return true if the sequence [Begin, End) has exactly N items. Runs in O(N)
19120b57cec5SDimitry Andric /// time. Not meant for use with random-access iterators.
1913*5ffd83dbSDimitry Andric /// Can optionally take a predicate to filter lazily some items.
1914*5ffd83dbSDimitry Andric template<typename IterTy,
1915*5ffd83dbSDimitry Andric          typename Pred = bool (*)(const decltype(*std::declval<IterTy>()) &)>
19160b57cec5SDimitry Andric bool hasNItems(
19170b57cec5SDimitry Andric     IterTy &&Begin, IterTy &&End, unsigned N,
1918*5ffd83dbSDimitry Andric     Pred &&ShouldBeCounted =
1919*5ffd83dbSDimitry Andric         [](const decltype(*std::declval<IterTy>()) &) { return true; },
1920*5ffd83dbSDimitry Andric     std::enable_if_t<
1921*5ffd83dbSDimitry Andric         !std::is_same<typename std::iterator_traits<std::remove_reference_t<
1922*5ffd83dbSDimitry Andric                           decltype(Begin)>>::iterator_category,
19230b57cec5SDimitry Andric                       std::random_access_iterator_tag>::value,
1924*5ffd83dbSDimitry Andric         void> * = nullptr) {
1925*5ffd83dbSDimitry Andric   for (; N; ++Begin) {
19260b57cec5SDimitry Andric     if (Begin == End)
19270b57cec5SDimitry Andric       return false; // Too few.
1928*5ffd83dbSDimitry Andric     N -= ShouldBeCounted(*Begin);
1929*5ffd83dbSDimitry Andric   }
1930*5ffd83dbSDimitry Andric   for (; Begin != End; ++Begin)
1931*5ffd83dbSDimitry Andric     if (ShouldBeCounted(*Begin))
1932*5ffd83dbSDimitry Andric       return false; // Too many.
1933*5ffd83dbSDimitry Andric   return true;
19340b57cec5SDimitry Andric }
19350b57cec5SDimitry Andric 
19360b57cec5SDimitry Andric /// Return true if the sequence [Begin, End) has N or more items. Runs in O(N)
19370b57cec5SDimitry Andric /// time. Not meant for use with random-access iterators.
1938*5ffd83dbSDimitry Andric /// Can optionally take a predicate to lazily filter some items.
1939*5ffd83dbSDimitry Andric template<typename IterTy,
1940*5ffd83dbSDimitry Andric          typename Pred = bool (*)(const decltype(*std::declval<IterTy>()) &)>
19410b57cec5SDimitry Andric bool hasNItemsOrMore(
19420b57cec5SDimitry Andric     IterTy &&Begin, IterTy &&End, unsigned N,
1943*5ffd83dbSDimitry Andric     Pred &&ShouldBeCounted =
1944*5ffd83dbSDimitry Andric         [](const decltype(*std::declval<IterTy>()) &) { return true; },
1945*5ffd83dbSDimitry Andric     std::enable_if_t<
1946*5ffd83dbSDimitry Andric         !std::is_same<typename std::iterator_traits<std::remove_reference_t<
1947*5ffd83dbSDimitry Andric                           decltype(Begin)>>::iterator_category,
19480b57cec5SDimitry Andric                       std::random_access_iterator_tag>::value,
1949*5ffd83dbSDimitry Andric         void> * = nullptr) {
1950*5ffd83dbSDimitry Andric   for (; N; ++Begin) {
19510b57cec5SDimitry Andric     if (Begin == End)
19520b57cec5SDimitry Andric       return false; // Too few.
1953*5ffd83dbSDimitry Andric     N -= ShouldBeCounted(*Begin);
1954*5ffd83dbSDimitry Andric   }
19550b57cec5SDimitry Andric   return true;
19560b57cec5SDimitry Andric }
19570b57cec5SDimitry Andric 
1958*5ffd83dbSDimitry Andric /// Returns true if the sequence [Begin, End) has N or less items. Can
1959*5ffd83dbSDimitry Andric /// optionally take a predicate to lazily filter some items.
1960*5ffd83dbSDimitry Andric template <typename IterTy,
1961*5ffd83dbSDimitry Andric           typename Pred = bool (*)(const decltype(*std::declval<IterTy>()) &)>
1962*5ffd83dbSDimitry Andric bool hasNItemsOrLess(
1963*5ffd83dbSDimitry Andric     IterTy &&Begin, IterTy &&End, unsigned N,
1964*5ffd83dbSDimitry Andric     Pred &&ShouldBeCounted = [](const decltype(*std::declval<IterTy>()) &) {
1965*5ffd83dbSDimitry Andric       return true;
1966*5ffd83dbSDimitry Andric     }) {
1967*5ffd83dbSDimitry Andric   assert(N != std::numeric_limits<unsigned>::max());
1968*5ffd83dbSDimitry Andric   return !hasNItemsOrMore(Begin, End, N + 1, ShouldBeCounted);
1969*5ffd83dbSDimitry Andric }
1970*5ffd83dbSDimitry Andric 
1971*5ffd83dbSDimitry Andric /// Returns true if the given container has exactly N items
1972*5ffd83dbSDimitry Andric template <typename ContainerTy> bool hasNItems(ContainerTy &&C, unsigned N) {
1973*5ffd83dbSDimitry Andric   return hasNItems(std::begin(C), std::end(C), N);
1974*5ffd83dbSDimitry Andric }
1975*5ffd83dbSDimitry Andric 
1976*5ffd83dbSDimitry Andric /// Returns true if the given container has N or more items
1977*5ffd83dbSDimitry Andric template <typename ContainerTy>
1978*5ffd83dbSDimitry Andric bool hasNItemsOrMore(ContainerTy &&C, unsigned N) {
1979*5ffd83dbSDimitry Andric   return hasNItemsOrMore(std::begin(C), std::end(C), N);
1980*5ffd83dbSDimitry Andric }
1981*5ffd83dbSDimitry Andric 
1982*5ffd83dbSDimitry Andric /// Returns true if the given container has N or less items
1983*5ffd83dbSDimitry Andric template <typename ContainerTy>
1984*5ffd83dbSDimitry Andric bool hasNItemsOrLess(ContainerTy &&C, unsigned N) {
1985*5ffd83dbSDimitry Andric   return hasNItemsOrLess(std::begin(C), std::end(C), N);
1986*5ffd83dbSDimitry Andric }
1987*5ffd83dbSDimitry Andric 
19880b57cec5SDimitry Andric /// Returns a raw pointer that represents the same address as the argument.
19890b57cec5SDimitry Andric ///
1990*5ffd83dbSDimitry Andric /// This implementation can be removed once we move to C++20 where it's defined
1991*5ffd83dbSDimitry Andric /// as std::to_address().
19920b57cec5SDimitry Andric ///
19930b57cec5SDimitry Andric /// The std::pointer_traits<>::to_address(p) variations of these overloads has
19940b57cec5SDimitry Andric /// not been implemented.
1995*5ffd83dbSDimitry Andric template <class Ptr> auto to_address(const Ptr &P) { return P.operator->(); }
19960b57cec5SDimitry Andric template <class T> constexpr T *to_address(T *P) { return P; }
19970b57cec5SDimitry Andric 
19980b57cec5SDimitry Andric } // end namespace llvm
19990b57cec5SDimitry Andric 
20000b57cec5SDimitry Andric #endif // LLVM_ADT_STLEXTRAS_H
2001