xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ADT/STLExtras.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This file contains some templates that are useful if you are working with the
10*0b57cec5SDimitry Andric // STL at all.
11*0b57cec5SDimitry Andric //
12*0b57cec5SDimitry Andric // No library is required when using these functions.
13*0b57cec5SDimitry Andric //
14*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric #ifndef LLVM_ADT_STLEXTRAS_H
17*0b57cec5SDimitry Andric #define LLVM_ADT_STLEXTRAS_H
18*0b57cec5SDimitry Andric 
19*0b57cec5SDimitry Andric #include "llvm/ADT/Optional.h"
20*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
21*0b57cec5SDimitry Andric #include "llvm/ADT/iterator.h"
22*0b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
23*0b57cec5SDimitry Andric #include "llvm/Config/abi-breaking.h"
24*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
25*0b57cec5SDimitry Andric #include <algorithm>
26*0b57cec5SDimitry Andric #include <cassert>
27*0b57cec5SDimitry Andric #include <cstddef>
28*0b57cec5SDimitry Andric #include <cstdint>
29*0b57cec5SDimitry Andric #include <cstdlib>
30*0b57cec5SDimitry Andric #include <functional>
31*0b57cec5SDimitry Andric #include <initializer_list>
32*0b57cec5SDimitry Andric #include <iterator>
33*0b57cec5SDimitry Andric #include <limits>
34*0b57cec5SDimitry Andric #include <memory>
35*0b57cec5SDimitry Andric #include <tuple>
36*0b57cec5SDimitry Andric #include <type_traits>
37*0b57cec5SDimitry Andric #include <utility>
38*0b57cec5SDimitry Andric 
39*0b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
40*0b57cec5SDimitry Andric #include <random> // for std::mt19937
41*0b57cec5SDimitry Andric #endif
42*0b57cec5SDimitry Andric 
43*0b57cec5SDimitry Andric namespace llvm {
44*0b57cec5SDimitry Andric 
45*0b57cec5SDimitry Andric // Only used by compiler if both template types are the same.  Useful when
46*0b57cec5SDimitry Andric // using SFINAE to test for the existence of member functions.
47*0b57cec5SDimitry Andric template <typename T, T> struct SameType;
48*0b57cec5SDimitry Andric 
49*0b57cec5SDimitry Andric namespace detail {
50*0b57cec5SDimitry Andric 
51*0b57cec5SDimitry Andric template <typename RangeT>
52*0b57cec5SDimitry Andric using IterOfRange = decltype(std::begin(std::declval<RangeT &>()));
53*0b57cec5SDimitry Andric 
54*0b57cec5SDimitry Andric template <typename RangeT>
55*0b57cec5SDimitry Andric using ValueOfRange = typename std::remove_reference<decltype(
56*0b57cec5SDimitry Andric     *std::begin(std::declval<RangeT &>()))>::type;
57*0b57cec5SDimitry Andric 
58*0b57cec5SDimitry Andric } // end namespace detail
59*0b57cec5SDimitry Andric 
60*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
61*0b57cec5SDimitry Andric //     Extra additions to <type_traits>
62*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
63*0b57cec5SDimitry Andric 
64*0b57cec5SDimitry Andric template <typename T>
65*0b57cec5SDimitry Andric struct negation : std::integral_constant<bool, !bool(T::value)> {};
66*0b57cec5SDimitry Andric 
67*0b57cec5SDimitry Andric template <typename...> struct conjunction : std::true_type {};
68*0b57cec5SDimitry Andric template <typename B1> struct conjunction<B1> : B1 {};
69*0b57cec5SDimitry Andric template <typename B1, typename... Bn>
70*0b57cec5SDimitry Andric struct conjunction<B1, Bn...>
71*0b57cec5SDimitry Andric     : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
72*0b57cec5SDimitry Andric 
73*0b57cec5SDimitry Andric template <typename T> struct make_const_ptr {
74*0b57cec5SDimitry Andric   using type =
75*0b57cec5SDimitry Andric       typename std::add_pointer<typename std::add_const<T>::type>::type;
76*0b57cec5SDimitry Andric };
77*0b57cec5SDimitry Andric 
78*0b57cec5SDimitry Andric template <typename T> struct make_const_ref {
79*0b57cec5SDimitry Andric   using type = typename std::add_lvalue_reference<
80*0b57cec5SDimitry Andric       typename std::add_const<T>::type>::type;
81*0b57cec5SDimitry Andric };
82*0b57cec5SDimitry Andric 
83*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
84*0b57cec5SDimitry Andric //     Extra additions to <functional>
85*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
86*0b57cec5SDimitry Andric 
87*0b57cec5SDimitry Andric template <class Ty> struct identity {
88*0b57cec5SDimitry Andric   using argument_type = Ty;
89*0b57cec5SDimitry Andric 
90*0b57cec5SDimitry Andric   Ty &operator()(Ty &self) const {
91*0b57cec5SDimitry Andric     return self;
92*0b57cec5SDimitry Andric   }
93*0b57cec5SDimitry Andric   const Ty &operator()(const Ty &self) const {
94*0b57cec5SDimitry Andric     return self;
95*0b57cec5SDimitry Andric   }
96*0b57cec5SDimitry Andric };
97*0b57cec5SDimitry Andric 
98*0b57cec5SDimitry Andric template <class Ty> struct less_ptr {
99*0b57cec5SDimitry Andric   bool operator()(const Ty* left, const Ty* right) const {
100*0b57cec5SDimitry Andric     return *left < *right;
101*0b57cec5SDimitry Andric   }
102*0b57cec5SDimitry Andric };
103*0b57cec5SDimitry Andric 
104*0b57cec5SDimitry Andric template <class Ty> struct greater_ptr {
105*0b57cec5SDimitry Andric   bool operator()(const Ty* left, const Ty* right) const {
106*0b57cec5SDimitry Andric     return *right < *left;
107*0b57cec5SDimitry Andric   }
108*0b57cec5SDimitry Andric };
109*0b57cec5SDimitry Andric 
110*0b57cec5SDimitry Andric /// An efficient, type-erasing, non-owning reference to a callable. This is
111*0b57cec5SDimitry Andric /// intended for use as the type of a function parameter that is not used
112*0b57cec5SDimitry Andric /// after the function in question returns.
113*0b57cec5SDimitry Andric ///
114*0b57cec5SDimitry Andric /// This class does not own the callable, so it is not in general safe to store
115*0b57cec5SDimitry Andric /// a function_ref.
116*0b57cec5SDimitry Andric template<typename Fn> class function_ref;
117*0b57cec5SDimitry Andric 
118*0b57cec5SDimitry Andric template<typename Ret, typename ...Params>
119*0b57cec5SDimitry Andric class function_ref<Ret(Params...)> {
120*0b57cec5SDimitry Andric   Ret (*callback)(intptr_t callable, Params ...params) = nullptr;
121*0b57cec5SDimitry Andric   intptr_t callable;
122*0b57cec5SDimitry Andric 
123*0b57cec5SDimitry Andric   template<typename Callable>
124*0b57cec5SDimitry Andric   static Ret callback_fn(intptr_t callable, Params ...params) {
125*0b57cec5SDimitry Andric     return (*reinterpret_cast<Callable*>(callable))(
126*0b57cec5SDimitry Andric         std::forward<Params>(params)...);
127*0b57cec5SDimitry Andric   }
128*0b57cec5SDimitry Andric 
129*0b57cec5SDimitry Andric public:
130*0b57cec5SDimitry Andric   function_ref() = default;
131*0b57cec5SDimitry Andric   function_ref(std::nullptr_t) {}
132*0b57cec5SDimitry Andric 
133*0b57cec5SDimitry Andric   template <typename Callable>
134*0b57cec5SDimitry Andric   function_ref(Callable &&callable,
135*0b57cec5SDimitry Andric                typename std::enable_if<
136*0b57cec5SDimitry Andric                    !std::is_same<typename std::remove_reference<Callable>::type,
137*0b57cec5SDimitry Andric                                  function_ref>::value>::type * = nullptr)
138*0b57cec5SDimitry Andric       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
139*0b57cec5SDimitry Andric         callable(reinterpret_cast<intptr_t>(&callable)) {}
140*0b57cec5SDimitry Andric 
141*0b57cec5SDimitry Andric   Ret operator()(Params ...params) const {
142*0b57cec5SDimitry Andric     return callback(callable, std::forward<Params>(params)...);
143*0b57cec5SDimitry Andric   }
144*0b57cec5SDimitry Andric 
145*0b57cec5SDimitry Andric   operator bool() const { return callback; }
146*0b57cec5SDimitry Andric };
147*0b57cec5SDimitry Andric 
148*0b57cec5SDimitry Andric // deleter - Very very very simple method that is used to invoke operator
149*0b57cec5SDimitry Andric // delete on something.  It is used like this:
150*0b57cec5SDimitry Andric //
151*0b57cec5SDimitry Andric //   for_each(V.begin(), B.end(), deleter<Interval>);
152*0b57cec5SDimitry Andric template <class T>
153*0b57cec5SDimitry Andric inline void deleter(T *Ptr) {
154*0b57cec5SDimitry Andric   delete Ptr;
155*0b57cec5SDimitry Andric }
156*0b57cec5SDimitry Andric 
157*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
158*0b57cec5SDimitry Andric //     Extra additions to <iterator>
159*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
160*0b57cec5SDimitry Andric 
161*0b57cec5SDimitry Andric namespace adl_detail {
162*0b57cec5SDimitry Andric 
163*0b57cec5SDimitry Andric using std::begin;
164*0b57cec5SDimitry Andric 
165*0b57cec5SDimitry Andric template <typename ContainerTy>
166*0b57cec5SDimitry Andric auto adl_begin(ContainerTy &&container)
167*0b57cec5SDimitry Andric     -> decltype(begin(std::forward<ContainerTy>(container))) {
168*0b57cec5SDimitry Andric   return begin(std::forward<ContainerTy>(container));
169*0b57cec5SDimitry Andric }
170*0b57cec5SDimitry Andric 
171*0b57cec5SDimitry Andric using std::end;
172*0b57cec5SDimitry Andric 
173*0b57cec5SDimitry Andric template <typename ContainerTy>
174*0b57cec5SDimitry Andric auto adl_end(ContainerTy &&container)
175*0b57cec5SDimitry Andric     -> decltype(end(std::forward<ContainerTy>(container))) {
176*0b57cec5SDimitry Andric   return end(std::forward<ContainerTy>(container));
177*0b57cec5SDimitry Andric }
178*0b57cec5SDimitry Andric 
179*0b57cec5SDimitry Andric using std::swap;
180*0b57cec5SDimitry Andric 
181*0b57cec5SDimitry Andric template <typename T>
182*0b57cec5SDimitry Andric void adl_swap(T &&lhs, T &&rhs) noexcept(noexcept(swap(std::declval<T>(),
183*0b57cec5SDimitry Andric                                                        std::declval<T>()))) {
184*0b57cec5SDimitry Andric   swap(std::forward<T>(lhs), std::forward<T>(rhs));
185*0b57cec5SDimitry Andric }
186*0b57cec5SDimitry Andric 
187*0b57cec5SDimitry Andric } // end namespace adl_detail
188*0b57cec5SDimitry Andric 
189*0b57cec5SDimitry Andric template <typename ContainerTy>
190*0b57cec5SDimitry Andric auto adl_begin(ContainerTy &&container)
191*0b57cec5SDimitry Andric     -> decltype(adl_detail::adl_begin(std::forward<ContainerTy>(container))) {
192*0b57cec5SDimitry Andric   return adl_detail::adl_begin(std::forward<ContainerTy>(container));
193*0b57cec5SDimitry Andric }
194*0b57cec5SDimitry Andric 
195*0b57cec5SDimitry Andric template <typename ContainerTy>
196*0b57cec5SDimitry Andric auto adl_end(ContainerTy &&container)
197*0b57cec5SDimitry Andric     -> decltype(adl_detail::adl_end(std::forward<ContainerTy>(container))) {
198*0b57cec5SDimitry Andric   return adl_detail::adl_end(std::forward<ContainerTy>(container));
199*0b57cec5SDimitry Andric }
200*0b57cec5SDimitry Andric 
201*0b57cec5SDimitry Andric template <typename T>
202*0b57cec5SDimitry Andric void adl_swap(T &&lhs, T &&rhs) noexcept(
203*0b57cec5SDimitry Andric     noexcept(adl_detail::adl_swap(std::declval<T>(), std::declval<T>()))) {
204*0b57cec5SDimitry Andric   adl_detail::adl_swap(std::forward<T>(lhs), std::forward<T>(rhs));
205*0b57cec5SDimitry Andric }
206*0b57cec5SDimitry Andric 
207*0b57cec5SDimitry Andric /// Test whether \p RangeOrContainer is empty. Similar to C++17 std::empty.
208*0b57cec5SDimitry Andric template <typename T>
209*0b57cec5SDimitry Andric constexpr bool empty(const T &RangeOrContainer) {
210*0b57cec5SDimitry Andric   return adl_begin(RangeOrContainer) == adl_end(RangeOrContainer);
211*0b57cec5SDimitry Andric }
212*0b57cec5SDimitry Andric 
213*0b57cec5SDimitry Andric // mapped_iterator - This is a simple iterator adapter that causes a function to
214*0b57cec5SDimitry Andric // be applied whenever operator* is invoked on the iterator.
215*0b57cec5SDimitry Andric 
216*0b57cec5SDimitry Andric template <typename ItTy, typename FuncTy,
217*0b57cec5SDimitry Andric           typename FuncReturnTy =
218*0b57cec5SDimitry Andric             decltype(std::declval<FuncTy>()(*std::declval<ItTy>()))>
219*0b57cec5SDimitry Andric class mapped_iterator
220*0b57cec5SDimitry Andric     : public iterator_adaptor_base<
221*0b57cec5SDimitry Andric              mapped_iterator<ItTy, FuncTy>, ItTy,
222*0b57cec5SDimitry Andric              typename std::iterator_traits<ItTy>::iterator_category,
223*0b57cec5SDimitry Andric              typename std::remove_reference<FuncReturnTy>::type> {
224*0b57cec5SDimitry Andric public:
225*0b57cec5SDimitry Andric   mapped_iterator(ItTy U, FuncTy F)
226*0b57cec5SDimitry Andric     : mapped_iterator::iterator_adaptor_base(std::move(U)), F(std::move(F)) {}
227*0b57cec5SDimitry Andric 
228*0b57cec5SDimitry Andric   ItTy getCurrent() { return this->I; }
229*0b57cec5SDimitry Andric 
230*0b57cec5SDimitry Andric   FuncReturnTy operator*() { return F(*this->I); }
231*0b57cec5SDimitry Andric 
232*0b57cec5SDimitry Andric private:
233*0b57cec5SDimitry Andric   FuncTy F;
234*0b57cec5SDimitry Andric };
235*0b57cec5SDimitry Andric 
236*0b57cec5SDimitry Andric // map_iterator - Provide a convenient way to create mapped_iterators, just like
237*0b57cec5SDimitry Andric // make_pair is useful for creating pairs...
238*0b57cec5SDimitry Andric template <class ItTy, class FuncTy>
239*0b57cec5SDimitry Andric inline mapped_iterator<ItTy, FuncTy> map_iterator(ItTy I, FuncTy F) {
240*0b57cec5SDimitry Andric   return mapped_iterator<ItTy, FuncTy>(std::move(I), std::move(F));
241*0b57cec5SDimitry Andric }
242*0b57cec5SDimitry Andric 
243*0b57cec5SDimitry Andric template <class ContainerTy, class FuncTy>
244*0b57cec5SDimitry Andric auto map_range(ContainerTy &&C, FuncTy F)
245*0b57cec5SDimitry Andric     -> decltype(make_range(map_iterator(C.begin(), F),
246*0b57cec5SDimitry Andric                            map_iterator(C.end(), F))) {
247*0b57cec5SDimitry Andric   return make_range(map_iterator(C.begin(), F), map_iterator(C.end(), F));
248*0b57cec5SDimitry Andric }
249*0b57cec5SDimitry Andric 
250*0b57cec5SDimitry Andric /// Helper to determine if type T has a member called rbegin().
251*0b57cec5SDimitry Andric template <typename Ty> class has_rbegin_impl {
252*0b57cec5SDimitry Andric   using yes = char[1];
253*0b57cec5SDimitry Andric   using no = char[2];
254*0b57cec5SDimitry Andric 
255*0b57cec5SDimitry Andric   template <typename Inner>
256*0b57cec5SDimitry Andric   static yes& test(Inner *I, decltype(I->rbegin()) * = nullptr);
257*0b57cec5SDimitry Andric 
258*0b57cec5SDimitry Andric   template <typename>
259*0b57cec5SDimitry Andric   static no& test(...);
260*0b57cec5SDimitry Andric 
261*0b57cec5SDimitry Andric public:
262*0b57cec5SDimitry Andric   static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
263*0b57cec5SDimitry Andric };
264*0b57cec5SDimitry Andric 
265*0b57cec5SDimitry Andric /// Metafunction to determine if T& or T has a member called rbegin().
266*0b57cec5SDimitry Andric template <typename Ty>
267*0b57cec5SDimitry Andric struct has_rbegin : has_rbegin_impl<typename std::remove_reference<Ty>::type> {
268*0b57cec5SDimitry Andric };
269*0b57cec5SDimitry Andric 
270*0b57cec5SDimitry Andric // Returns an iterator_range over the given container which iterates in reverse.
271*0b57cec5SDimitry Andric // Note that the container must have rbegin()/rend() methods for this to work.
272*0b57cec5SDimitry Andric template <typename ContainerTy>
273*0b57cec5SDimitry Andric auto reverse(ContainerTy &&C,
274*0b57cec5SDimitry Andric              typename std::enable_if<has_rbegin<ContainerTy>::value>::type * =
275*0b57cec5SDimitry Andric                  nullptr) -> decltype(make_range(C.rbegin(), C.rend())) {
276*0b57cec5SDimitry Andric   return make_range(C.rbegin(), C.rend());
277*0b57cec5SDimitry Andric }
278*0b57cec5SDimitry Andric 
279*0b57cec5SDimitry Andric // Returns a std::reverse_iterator wrapped around the given iterator.
280*0b57cec5SDimitry Andric template <typename IteratorTy>
281*0b57cec5SDimitry Andric std::reverse_iterator<IteratorTy> make_reverse_iterator(IteratorTy It) {
282*0b57cec5SDimitry Andric   return std::reverse_iterator<IteratorTy>(It);
283*0b57cec5SDimitry Andric }
284*0b57cec5SDimitry Andric 
285*0b57cec5SDimitry Andric // Returns an iterator_range over the given container which iterates in reverse.
286*0b57cec5SDimitry Andric // Note that the container must have begin()/end() methods which return
287*0b57cec5SDimitry Andric // bidirectional iterators for this to work.
288*0b57cec5SDimitry Andric template <typename ContainerTy>
289*0b57cec5SDimitry Andric auto reverse(
290*0b57cec5SDimitry Andric     ContainerTy &&C,
291*0b57cec5SDimitry Andric     typename std::enable_if<!has_rbegin<ContainerTy>::value>::type * = nullptr)
292*0b57cec5SDimitry Andric     -> decltype(make_range(llvm::make_reverse_iterator(std::end(C)),
293*0b57cec5SDimitry Andric                            llvm::make_reverse_iterator(std::begin(C)))) {
294*0b57cec5SDimitry Andric   return make_range(llvm::make_reverse_iterator(std::end(C)),
295*0b57cec5SDimitry Andric                     llvm::make_reverse_iterator(std::begin(C)));
296*0b57cec5SDimitry Andric }
297*0b57cec5SDimitry Andric 
298*0b57cec5SDimitry Andric /// An iterator adaptor that filters the elements of given inner iterators.
299*0b57cec5SDimitry Andric ///
300*0b57cec5SDimitry Andric /// The predicate parameter should be a callable object that accepts the wrapped
301*0b57cec5SDimitry Andric /// iterator's reference type and returns a bool. When incrementing or
302*0b57cec5SDimitry Andric /// decrementing the iterator, it will call the predicate on each element and
303*0b57cec5SDimitry Andric /// skip any where it returns false.
304*0b57cec5SDimitry Andric ///
305*0b57cec5SDimitry Andric /// \code
306*0b57cec5SDimitry Andric ///   int A[] = { 1, 2, 3, 4 };
307*0b57cec5SDimitry Andric ///   auto R = make_filter_range(A, [](int N) { return N % 2 == 1; });
308*0b57cec5SDimitry Andric ///   // R contains { 1, 3 }.
309*0b57cec5SDimitry Andric /// \endcode
310*0b57cec5SDimitry Andric ///
311*0b57cec5SDimitry Andric /// Note: filter_iterator_base implements support for forward iteration.
312*0b57cec5SDimitry Andric /// filter_iterator_impl exists to provide support for bidirectional iteration,
313*0b57cec5SDimitry Andric /// conditional on whether the wrapped iterator supports it.
314*0b57cec5SDimitry Andric template <typename WrappedIteratorT, typename PredicateT, typename IterTag>
315*0b57cec5SDimitry Andric class filter_iterator_base
316*0b57cec5SDimitry Andric     : public iterator_adaptor_base<
317*0b57cec5SDimitry Andric           filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>,
318*0b57cec5SDimitry Andric           WrappedIteratorT,
319*0b57cec5SDimitry Andric           typename std::common_type<
320*0b57cec5SDimitry Andric               IterTag, typename std::iterator_traits<
321*0b57cec5SDimitry Andric                            WrappedIteratorT>::iterator_category>::type> {
322*0b57cec5SDimitry Andric   using BaseT = iterator_adaptor_base<
323*0b57cec5SDimitry Andric       filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>,
324*0b57cec5SDimitry Andric       WrappedIteratorT,
325*0b57cec5SDimitry Andric       typename std::common_type<
326*0b57cec5SDimitry Andric           IterTag, typename std::iterator_traits<
327*0b57cec5SDimitry Andric                        WrappedIteratorT>::iterator_category>::type>;
328*0b57cec5SDimitry Andric 
329*0b57cec5SDimitry Andric protected:
330*0b57cec5SDimitry Andric   WrappedIteratorT End;
331*0b57cec5SDimitry Andric   PredicateT Pred;
332*0b57cec5SDimitry Andric 
333*0b57cec5SDimitry Andric   void findNextValid() {
334*0b57cec5SDimitry Andric     while (this->I != End && !Pred(*this->I))
335*0b57cec5SDimitry Andric       BaseT::operator++();
336*0b57cec5SDimitry Andric   }
337*0b57cec5SDimitry Andric 
338*0b57cec5SDimitry Andric   // Construct the iterator. The begin iterator needs to know where the end
339*0b57cec5SDimitry Andric   // is, so that it can properly stop when it gets there. The end iterator only
340*0b57cec5SDimitry Andric   // needs the predicate to support bidirectional iteration.
341*0b57cec5SDimitry Andric   filter_iterator_base(WrappedIteratorT Begin, WrappedIteratorT End,
342*0b57cec5SDimitry Andric                        PredicateT Pred)
343*0b57cec5SDimitry Andric       : BaseT(Begin), End(End), Pred(Pred) {
344*0b57cec5SDimitry Andric     findNextValid();
345*0b57cec5SDimitry Andric   }
346*0b57cec5SDimitry Andric 
347*0b57cec5SDimitry Andric public:
348*0b57cec5SDimitry Andric   using BaseT::operator++;
349*0b57cec5SDimitry Andric 
350*0b57cec5SDimitry Andric   filter_iterator_base &operator++() {
351*0b57cec5SDimitry Andric     BaseT::operator++();
352*0b57cec5SDimitry Andric     findNextValid();
353*0b57cec5SDimitry Andric     return *this;
354*0b57cec5SDimitry Andric   }
355*0b57cec5SDimitry Andric };
356*0b57cec5SDimitry Andric 
357*0b57cec5SDimitry Andric /// Specialization of filter_iterator_base for forward iteration only.
358*0b57cec5SDimitry Andric template <typename WrappedIteratorT, typename PredicateT,
359*0b57cec5SDimitry Andric           typename IterTag = std::forward_iterator_tag>
360*0b57cec5SDimitry Andric class filter_iterator_impl
361*0b57cec5SDimitry Andric     : public filter_iterator_base<WrappedIteratorT, PredicateT, IterTag> {
362*0b57cec5SDimitry Andric   using BaseT = filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>;
363*0b57cec5SDimitry Andric 
364*0b57cec5SDimitry Andric public:
365*0b57cec5SDimitry Andric   filter_iterator_impl(WrappedIteratorT Begin, WrappedIteratorT End,
366*0b57cec5SDimitry Andric                        PredicateT Pred)
367*0b57cec5SDimitry Andric       : BaseT(Begin, End, Pred) {}
368*0b57cec5SDimitry Andric };
369*0b57cec5SDimitry Andric 
370*0b57cec5SDimitry Andric /// Specialization of filter_iterator_base for bidirectional iteration.
371*0b57cec5SDimitry Andric template <typename WrappedIteratorT, typename PredicateT>
372*0b57cec5SDimitry Andric class filter_iterator_impl<WrappedIteratorT, PredicateT,
373*0b57cec5SDimitry Andric                            std::bidirectional_iterator_tag>
374*0b57cec5SDimitry Andric     : public filter_iterator_base<WrappedIteratorT, PredicateT,
375*0b57cec5SDimitry Andric                                   std::bidirectional_iterator_tag> {
376*0b57cec5SDimitry Andric   using BaseT = filter_iterator_base<WrappedIteratorT, PredicateT,
377*0b57cec5SDimitry Andric                                      std::bidirectional_iterator_tag>;
378*0b57cec5SDimitry Andric   void findPrevValid() {
379*0b57cec5SDimitry Andric     while (!this->Pred(*this->I))
380*0b57cec5SDimitry Andric       BaseT::operator--();
381*0b57cec5SDimitry Andric   }
382*0b57cec5SDimitry Andric 
383*0b57cec5SDimitry Andric public:
384*0b57cec5SDimitry Andric   using BaseT::operator--;
385*0b57cec5SDimitry Andric 
386*0b57cec5SDimitry Andric   filter_iterator_impl(WrappedIteratorT Begin, WrappedIteratorT End,
387*0b57cec5SDimitry Andric                        PredicateT Pred)
388*0b57cec5SDimitry Andric       : BaseT(Begin, End, Pred) {}
389*0b57cec5SDimitry Andric 
390*0b57cec5SDimitry Andric   filter_iterator_impl &operator--() {
391*0b57cec5SDimitry Andric     BaseT::operator--();
392*0b57cec5SDimitry Andric     findPrevValid();
393*0b57cec5SDimitry Andric     return *this;
394*0b57cec5SDimitry Andric   }
395*0b57cec5SDimitry Andric };
396*0b57cec5SDimitry Andric 
397*0b57cec5SDimitry Andric namespace detail {
398*0b57cec5SDimitry Andric 
399*0b57cec5SDimitry Andric template <bool is_bidirectional> struct fwd_or_bidi_tag_impl {
400*0b57cec5SDimitry Andric   using type = std::forward_iterator_tag;
401*0b57cec5SDimitry Andric };
402*0b57cec5SDimitry Andric 
403*0b57cec5SDimitry Andric template <> struct fwd_or_bidi_tag_impl<true> {
404*0b57cec5SDimitry Andric   using type = std::bidirectional_iterator_tag;
405*0b57cec5SDimitry Andric };
406*0b57cec5SDimitry Andric 
407*0b57cec5SDimitry Andric /// Helper which sets its type member to forward_iterator_tag if the category
408*0b57cec5SDimitry Andric /// of \p IterT does not derive from bidirectional_iterator_tag, and to
409*0b57cec5SDimitry Andric /// bidirectional_iterator_tag otherwise.
410*0b57cec5SDimitry Andric template <typename IterT> struct fwd_or_bidi_tag {
411*0b57cec5SDimitry Andric   using type = typename fwd_or_bidi_tag_impl<std::is_base_of<
412*0b57cec5SDimitry Andric       std::bidirectional_iterator_tag,
413*0b57cec5SDimitry Andric       typename std::iterator_traits<IterT>::iterator_category>::value>::type;
414*0b57cec5SDimitry Andric };
415*0b57cec5SDimitry Andric 
416*0b57cec5SDimitry Andric } // namespace detail
417*0b57cec5SDimitry Andric 
418*0b57cec5SDimitry Andric /// Defines filter_iterator to a suitable specialization of
419*0b57cec5SDimitry Andric /// filter_iterator_impl, based on the underlying iterator's category.
420*0b57cec5SDimitry Andric template <typename WrappedIteratorT, typename PredicateT>
421*0b57cec5SDimitry Andric using filter_iterator = filter_iterator_impl<
422*0b57cec5SDimitry Andric     WrappedIteratorT, PredicateT,
423*0b57cec5SDimitry Andric     typename detail::fwd_or_bidi_tag<WrappedIteratorT>::type>;
424*0b57cec5SDimitry Andric 
425*0b57cec5SDimitry Andric /// Convenience function that takes a range of elements and a predicate,
426*0b57cec5SDimitry Andric /// and return a new filter_iterator range.
427*0b57cec5SDimitry Andric ///
428*0b57cec5SDimitry Andric /// FIXME: Currently if RangeT && is a rvalue reference to a temporary, the
429*0b57cec5SDimitry Andric /// lifetime of that temporary is not kept by the returned range object, and the
430*0b57cec5SDimitry Andric /// temporary is going to be dropped on the floor after the make_iterator_range
431*0b57cec5SDimitry Andric /// full expression that contains this function call.
432*0b57cec5SDimitry Andric template <typename RangeT, typename PredicateT>
433*0b57cec5SDimitry Andric iterator_range<filter_iterator<detail::IterOfRange<RangeT>, PredicateT>>
434*0b57cec5SDimitry Andric make_filter_range(RangeT &&Range, PredicateT Pred) {
435*0b57cec5SDimitry Andric   using FilterIteratorT =
436*0b57cec5SDimitry Andric       filter_iterator<detail::IterOfRange<RangeT>, PredicateT>;
437*0b57cec5SDimitry Andric   return make_range(
438*0b57cec5SDimitry Andric       FilterIteratorT(std::begin(std::forward<RangeT>(Range)),
439*0b57cec5SDimitry Andric                       std::end(std::forward<RangeT>(Range)), Pred),
440*0b57cec5SDimitry Andric       FilterIteratorT(std::end(std::forward<RangeT>(Range)),
441*0b57cec5SDimitry Andric                       std::end(std::forward<RangeT>(Range)), Pred));
442*0b57cec5SDimitry Andric }
443*0b57cec5SDimitry Andric 
444*0b57cec5SDimitry Andric /// A pseudo-iterator adaptor that is designed to implement "early increment"
445*0b57cec5SDimitry Andric /// style loops.
446*0b57cec5SDimitry Andric ///
447*0b57cec5SDimitry Andric /// This is *not a normal iterator* and should almost never be used directly. It
448*0b57cec5SDimitry Andric /// is intended primarily to be used with range based for loops and some range
449*0b57cec5SDimitry Andric /// algorithms.
450*0b57cec5SDimitry Andric ///
451*0b57cec5SDimitry Andric /// The iterator isn't quite an `OutputIterator` or an `InputIterator` but
452*0b57cec5SDimitry Andric /// somewhere between them. The constraints of these iterators are:
453*0b57cec5SDimitry Andric ///
454*0b57cec5SDimitry Andric /// - On construction or after being incremented, it is comparable and
455*0b57cec5SDimitry Andric ///   dereferencable. It is *not* incrementable.
456*0b57cec5SDimitry Andric /// - After being dereferenced, it is neither comparable nor dereferencable, it
457*0b57cec5SDimitry Andric ///   is only incrementable.
458*0b57cec5SDimitry Andric ///
459*0b57cec5SDimitry Andric /// This means you can only dereference the iterator once, and you can only
460*0b57cec5SDimitry Andric /// increment it once between dereferences.
461*0b57cec5SDimitry Andric template <typename WrappedIteratorT>
462*0b57cec5SDimitry Andric class early_inc_iterator_impl
463*0b57cec5SDimitry Andric     : public iterator_adaptor_base<early_inc_iterator_impl<WrappedIteratorT>,
464*0b57cec5SDimitry Andric                                    WrappedIteratorT, std::input_iterator_tag> {
465*0b57cec5SDimitry Andric   using BaseT =
466*0b57cec5SDimitry Andric       iterator_adaptor_base<early_inc_iterator_impl<WrappedIteratorT>,
467*0b57cec5SDimitry Andric                             WrappedIteratorT, std::input_iterator_tag>;
468*0b57cec5SDimitry Andric 
469*0b57cec5SDimitry Andric   using PointerT = typename std::iterator_traits<WrappedIteratorT>::pointer;
470*0b57cec5SDimitry Andric 
471*0b57cec5SDimitry Andric protected:
472*0b57cec5SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
473*0b57cec5SDimitry Andric   bool IsEarlyIncremented = false;
474*0b57cec5SDimitry Andric #endif
475*0b57cec5SDimitry Andric 
476*0b57cec5SDimitry Andric public:
477*0b57cec5SDimitry Andric   early_inc_iterator_impl(WrappedIteratorT I) : BaseT(I) {}
478*0b57cec5SDimitry Andric 
479*0b57cec5SDimitry Andric   using BaseT::operator*;
480*0b57cec5SDimitry Andric   typename BaseT::reference operator*() {
481*0b57cec5SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
482*0b57cec5SDimitry Andric     assert(!IsEarlyIncremented && "Cannot dereference twice!");
483*0b57cec5SDimitry Andric     IsEarlyIncremented = true;
484*0b57cec5SDimitry Andric #endif
485*0b57cec5SDimitry Andric     return *(this->I)++;
486*0b57cec5SDimitry Andric   }
487*0b57cec5SDimitry Andric 
488*0b57cec5SDimitry Andric   using BaseT::operator++;
489*0b57cec5SDimitry Andric   early_inc_iterator_impl &operator++() {
490*0b57cec5SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
491*0b57cec5SDimitry Andric     assert(IsEarlyIncremented && "Cannot increment before dereferencing!");
492*0b57cec5SDimitry Andric     IsEarlyIncremented = false;
493*0b57cec5SDimitry Andric #endif
494*0b57cec5SDimitry Andric     return *this;
495*0b57cec5SDimitry Andric   }
496*0b57cec5SDimitry Andric 
497*0b57cec5SDimitry Andric   using BaseT::operator==;
498*0b57cec5SDimitry Andric   bool operator==(const early_inc_iterator_impl &RHS) const {
499*0b57cec5SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
500*0b57cec5SDimitry Andric     assert(!IsEarlyIncremented && "Cannot compare after dereferencing!");
501*0b57cec5SDimitry Andric #endif
502*0b57cec5SDimitry Andric     return BaseT::operator==(RHS);
503*0b57cec5SDimitry Andric   }
504*0b57cec5SDimitry Andric };
505*0b57cec5SDimitry Andric 
506*0b57cec5SDimitry Andric /// Make a range that does early increment to allow mutation of the underlying
507*0b57cec5SDimitry Andric /// range without disrupting iteration.
508*0b57cec5SDimitry Andric ///
509*0b57cec5SDimitry Andric /// The underlying iterator will be incremented immediately after it is
510*0b57cec5SDimitry Andric /// dereferenced, allowing deletion of the current node or insertion of nodes to
511*0b57cec5SDimitry Andric /// not disrupt iteration provided they do not invalidate the *next* iterator --
512*0b57cec5SDimitry Andric /// the current iterator can be invalidated.
513*0b57cec5SDimitry Andric ///
514*0b57cec5SDimitry Andric /// This requires a very exact pattern of use that is only really suitable to
515*0b57cec5SDimitry Andric /// range based for loops and other range algorithms that explicitly guarantee
516*0b57cec5SDimitry Andric /// to dereference exactly once each element, and to increment exactly once each
517*0b57cec5SDimitry Andric /// element.
518*0b57cec5SDimitry Andric template <typename RangeT>
519*0b57cec5SDimitry Andric iterator_range<early_inc_iterator_impl<detail::IterOfRange<RangeT>>>
520*0b57cec5SDimitry Andric make_early_inc_range(RangeT &&Range) {
521*0b57cec5SDimitry Andric   using EarlyIncIteratorT =
522*0b57cec5SDimitry Andric       early_inc_iterator_impl<detail::IterOfRange<RangeT>>;
523*0b57cec5SDimitry Andric   return make_range(EarlyIncIteratorT(std::begin(std::forward<RangeT>(Range))),
524*0b57cec5SDimitry Andric                     EarlyIncIteratorT(std::end(std::forward<RangeT>(Range))));
525*0b57cec5SDimitry Andric }
526*0b57cec5SDimitry Andric 
527*0b57cec5SDimitry Andric // forward declarations required by zip_shortest/zip_first/zip_longest
528*0b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
529*0b57cec5SDimitry Andric bool all_of(R &&range, UnaryPredicate P);
530*0b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
531*0b57cec5SDimitry Andric bool any_of(R &&range, UnaryPredicate P);
532*0b57cec5SDimitry Andric 
533*0b57cec5SDimitry Andric template <size_t... I> struct index_sequence;
534*0b57cec5SDimitry Andric 
535*0b57cec5SDimitry Andric template <class... Ts> struct index_sequence_for;
536*0b57cec5SDimitry Andric 
537*0b57cec5SDimitry Andric namespace detail {
538*0b57cec5SDimitry Andric 
539*0b57cec5SDimitry Andric using std::declval;
540*0b57cec5SDimitry Andric 
541*0b57cec5SDimitry Andric // We have to alias this since inlining the actual type at the usage site
542*0b57cec5SDimitry Andric // in the parameter list of iterator_facade_base<> below ICEs MSVC 2017.
543*0b57cec5SDimitry Andric template<typename... Iters> struct ZipTupleType {
544*0b57cec5SDimitry Andric   using type = std::tuple<decltype(*declval<Iters>())...>;
545*0b57cec5SDimitry Andric };
546*0b57cec5SDimitry Andric 
547*0b57cec5SDimitry Andric template <typename ZipType, typename... Iters>
548*0b57cec5SDimitry Andric using zip_traits = iterator_facade_base<
549*0b57cec5SDimitry Andric     ZipType, typename std::common_type<std::bidirectional_iterator_tag,
550*0b57cec5SDimitry Andric                                        typename std::iterator_traits<
551*0b57cec5SDimitry Andric                                            Iters>::iterator_category...>::type,
552*0b57cec5SDimitry Andric     // ^ TODO: Implement random access methods.
553*0b57cec5SDimitry Andric     typename ZipTupleType<Iters...>::type,
554*0b57cec5SDimitry Andric     typename std::iterator_traits<typename std::tuple_element<
555*0b57cec5SDimitry Andric         0, std::tuple<Iters...>>::type>::difference_type,
556*0b57cec5SDimitry Andric     // ^ FIXME: This follows boost::make_zip_iterator's assumption that all
557*0b57cec5SDimitry Andric     // inner iterators have the same difference_type. It would fail if, for
558*0b57cec5SDimitry Andric     // instance, the second field's difference_type were non-numeric while the
559*0b57cec5SDimitry Andric     // first is.
560*0b57cec5SDimitry Andric     typename ZipTupleType<Iters...>::type *,
561*0b57cec5SDimitry Andric     typename ZipTupleType<Iters...>::type>;
562*0b57cec5SDimitry Andric 
563*0b57cec5SDimitry Andric template <typename ZipType, typename... Iters>
564*0b57cec5SDimitry Andric struct zip_common : public zip_traits<ZipType, Iters...> {
565*0b57cec5SDimitry Andric   using Base = zip_traits<ZipType, Iters...>;
566*0b57cec5SDimitry Andric   using value_type = typename Base::value_type;
567*0b57cec5SDimitry Andric 
568*0b57cec5SDimitry Andric   std::tuple<Iters...> iterators;
569*0b57cec5SDimitry Andric 
570*0b57cec5SDimitry Andric protected:
571*0b57cec5SDimitry Andric   template <size_t... Ns> value_type deref(index_sequence<Ns...>) const {
572*0b57cec5SDimitry Andric     return value_type(*std::get<Ns>(iterators)...);
573*0b57cec5SDimitry Andric   }
574*0b57cec5SDimitry Andric 
575*0b57cec5SDimitry Andric   template <size_t... Ns>
576*0b57cec5SDimitry Andric   decltype(iterators) tup_inc(index_sequence<Ns...>) const {
577*0b57cec5SDimitry Andric     return std::tuple<Iters...>(std::next(std::get<Ns>(iterators))...);
578*0b57cec5SDimitry Andric   }
579*0b57cec5SDimitry Andric 
580*0b57cec5SDimitry Andric   template <size_t... Ns>
581*0b57cec5SDimitry Andric   decltype(iterators) tup_dec(index_sequence<Ns...>) const {
582*0b57cec5SDimitry Andric     return std::tuple<Iters...>(std::prev(std::get<Ns>(iterators))...);
583*0b57cec5SDimitry Andric   }
584*0b57cec5SDimitry Andric 
585*0b57cec5SDimitry Andric public:
586*0b57cec5SDimitry Andric   zip_common(Iters &&... ts) : iterators(std::forward<Iters>(ts)...) {}
587*0b57cec5SDimitry Andric 
588*0b57cec5SDimitry Andric   value_type operator*() { return deref(index_sequence_for<Iters...>{}); }
589*0b57cec5SDimitry Andric 
590*0b57cec5SDimitry Andric   const value_type operator*() const {
591*0b57cec5SDimitry Andric     return deref(index_sequence_for<Iters...>{});
592*0b57cec5SDimitry Andric   }
593*0b57cec5SDimitry Andric 
594*0b57cec5SDimitry Andric   ZipType &operator++() {
595*0b57cec5SDimitry Andric     iterators = tup_inc(index_sequence_for<Iters...>{});
596*0b57cec5SDimitry Andric     return *reinterpret_cast<ZipType *>(this);
597*0b57cec5SDimitry Andric   }
598*0b57cec5SDimitry Andric 
599*0b57cec5SDimitry Andric   ZipType &operator--() {
600*0b57cec5SDimitry Andric     static_assert(Base::IsBidirectional,
601*0b57cec5SDimitry Andric                   "All inner iterators must be at least bidirectional.");
602*0b57cec5SDimitry Andric     iterators = tup_dec(index_sequence_for<Iters...>{});
603*0b57cec5SDimitry Andric     return *reinterpret_cast<ZipType *>(this);
604*0b57cec5SDimitry Andric   }
605*0b57cec5SDimitry Andric };
606*0b57cec5SDimitry Andric 
607*0b57cec5SDimitry Andric template <typename... Iters>
608*0b57cec5SDimitry Andric struct zip_first : public zip_common<zip_first<Iters...>, Iters...> {
609*0b57cec5SDimitry Andric   using Base = zip_common<zip_first<Iters...>, Iters...>;
610*0b57cec5SDimitry Andric 
611*0b57cec5SDimitry Andric   bool operator==(const zip_first<Iters...> &other) const {
612*0b57cec5SDimitry Andric     return std::get<0>(this->iterators) == std::get<0>(other.iterators);
613*0b57cec5SDimitry Andric   }
614*0b57cec5SDimitry Andric 
615*0b57cec5SDimitry Andric   zip_first(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
616*0b57cec5SDimitry Andric };
617*0b57cec5SDimitry Andric 
618*0b57cec5SDimitry Andric template <typename... Iters>
619*0b57cec5SDimitry Andric class zip_shortest : public zip_common<zip_shortest<Iters...>, Iters...> {
620*0b57cec5SDimitry Andric   template <size_t... Ns>
621*0b57cec5SDimitry Andric   bool test(const zip_shortest<Iters...> &other, index_sequence<Ns...>) const {
622*0b57cec5SDimitry Andric     return all_of(std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
623*0b57cec5SDimitry Andric                                               std::get<Ns>(other.iterators)...},
624*0b57cec5SDimitry Andric                   identity<bool>{});
625*0b57cec5SDimitry Andric   }
626*0b57cec5SDimitry Andric 
627*0b57cec5SDimitry Andric public:
628*0b57cec5SDimitry Andric   using Base = zip_common<zip_shortest<Iters...>, Iters...>;
629*0b57cec5SDimitry Andric 
630*0b57cec5SDimitry Andric   zip_shortest(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
631*0b57cec5SDimitry Andric 
632*0b57cec5SDimitry Andric   bool operator==(const zip_shortest<Iters...> &other) const {
633*0b57cec5SDimitry Andric     return !test(other, index_sequence_for<Iters...>{});
634*0b57cec5SDimitry Andric   }
635*0b57cec5SDimitry Andric };
636*0b57cec5SDimitry Andric 
637*0b57cec5SDimitry Andric template <template <typename...> class ItType, typename... Args> class zippy {
638*0b57cec5SDimitry Andric public:
639*0b57cec5SDimitry Andric   using iterator = ItType<decltype(std::begin(std::declval<Args>()))...>;
640*0b57cec5SDimitry Andric   using iterator_category = typename iterator::iterator_category;
641*0b57cec5SDimitry Andric   using value_type = typename iterator::value_type;
642*0b57cec5SDimitry Andric   using difference_type = typename iterator::difference_type;
643*0b57cec5SDimitry Andric   using pointer = typename iterator::pointer;
644*0b57cec5SDimitry Andric   using reference = typename iterator::reference;
645*0b57cec5SDimitry Andric 
646*0b57cec5SDimitry Andric private:
647*0b57cec5SDimitry Andric   std::tuple<Args...> ts;
648*0b57cec5SDimitry Andric 
649*0b57cec5SDimitry Andric   template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) const {
650*0b57cec5SDimitry Andric     return iterator(std::begin(std::get<Ns>(ts))...);
651*0b57cec5SDimitry Andric   }
652*0b57cec5SDimitry Andric   template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) const {
653*0b57cec5SDimitry Andric     return iterator(std::end(std::get<Ns>(ts))...);
654*0b57cec5SDimitry Andric   }
655*0b57cec5SDimitry Andric 
656*0b57cec5SDimitry Andric public:
657*0b57cec5SDimitry Andric   zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
658*0b57cec5SDimitry Andric 
659*0b57cec5SDimitry Andric   iterator begin() const { return begin_impl(index_sequence_for<Args...>{}); }
660*0b57cec5SDimitry Andric   iterator end() const { return end_impl(index_sequence_for<Args...>{}); }
661*0b57cec5SDimitry Andric };
662*0b57cec5SDimitry Andric 
663*0b57cec5SDimitry Andric } // end namespace detail
664*0b57cec5SDimitry Andric 
665*0b57cec5SDimitry Andric /// zip iterator for two or more iteratable types.
666*0b57cec5SDimitry Andric template <typename T, typename U, typename... Args>
667*0b57cec5SDimitry Andric detail::zippy<detail::zip_shortest, T, U, Args...> zip(T &&t, U &&u,
668*0b57cec5SDimitry Andric                                                        Args &&... args) {
669*0b57cec5SDimitry Andric   return detail::zippy<detail::zip_shortest, T, U, Args...>(
670*0b57cec5SDimitry Andric       std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
671*0b57cec5SDimitry Andric }
672*0b57cec5SDimitry Andric 
673*0b57cec5SDimitry Andric /// zip iterator that, for the sake of efficiency, assumes the first iteratee to
674*0b57cec5SDimitry Andric /// be the shortest.
675*0b57cec5SDimitry Andric template <typename T, typename U, typename... Args>
676*0b57cec5SDimitry Andric detail::zippy<detail::zip_first, T, U, Args...> zip_first(T &&t, U &&u,
677*0b57cec5SDimitry Andric                                                           Args &&... args) {
678*0b57cec5SDimitry Andric   return detail::zippy<detail::zip_first, T, U, Args...>(
679*0b57cec5SDimitry Andric       std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
680*0b57cec5SDimitry Andric }
681*0b57cec5SDimitry Andric 
682*0b57cec5SDimitry Andric namespace detail {
683*0b57cec5SDimitry Andric template <typename Iter>
684*0b57cec5SDimitry Andric static Iter next_or_end(const Iter &I, const Iter &End) {
685*0b57cec5SDimitry Andric   if (I == End)
686*0b57cec5SDimitry Andric     return End;
687*0b57cec5SDimitry Andric   return std::next(I);
688*0b57cec5SDimitry Andric }
689*0b57cec5SDimitry Andric 
690*0b57cec5SDimitry Andric template <typename Iter>
691*0b57cec5SDimitry Andric static auto deref_or_none(const Iter &I, const Iter &End)
692*0b57cec5SDimitry Andric     -> llvm::Optional<typename std::remove_const<
693*0b57cec5SDimitry Andric         typename std::remove_reference<decltype(*I)>::type>::type> {
694*0b57cec5SDimitry Andric   if (I == End)
695*0b57cec5SDimitry Andric     return None;
696*0b57cec5SDimitry Andric   return *I;
697*0b57cec5SDimitry Andric }
698*0b57cec5SDimitry Andric 
699*0b57cec5SDimitry Andric template <typename Iter> struct ZipLongestItemType {
700*0b57cec5SDimitry Andric   using type =
701*0b57cec5SDimitry Andric       llvm::Optional<typename std::remove_const<typename std::remove_reference<
702*0b57cec5SDimitry Andric           decltype(*std::declval<Iter>())>::type>::type>;
703*0b57cec5SDimitry Andric };
704*0b57cec5SDimitry Andric 
705*0b57cec5SDimitry Andric template <typename... Iters> struct ZipLongestTupleType {
706*0b57cec5SDimitry Andric   using type = std::tuple<typename ZipLongestItemType<Iters>::type...>;
707*0b57cec5SDimitry Andric };
708*0b57cec5SDimitry Andric 
709*0b57cec5SDimitry Andric template <typename... Iters>
710*0b57cec5SDimitry Andric class zip_longest_iterator
711*0b57cec5SDimitry Andric     : public iterator_facade_base<
712*0b57cec5SDimitry Andric           zip_longest_iterator<Iters...>,
713*0b57cec5SDimitry Andric           typename std::common_type<
714*0b57cec5SDimitry Andric               std::forward_iterator_tag,
715*0b57cec5SDimitry Andric               typename std::iterator_traits<Iters>::iterator_category...>::type,
716*0b57cec5SDimitry Andric           typename ZipLongestTupleType<Iters...>::type,
717*0b57cec5SDimitry Andric           typename std::iterator_traits<typename std::tuple_element<
718*0b57cec5SDimitry Andric               0, std::tuple<Iters...>>::type>::difference_type,
719*0b57cec5SDimitry Andric           typename ZipLongestTupleType<Iters...>::type *,
720*0b57cec5SDimitry Andric           typename ZipLongestTupleType<Iters...>::type> {
721*0b57cec5SDimitry Andric public:
722*0b57cec5SDimitry Andric   using value_type = typename ZipLongestTupleType<Iters...>::type;
723*0b57cec5SDimitry Andric 
724*0b57cec5SDimitry Andric private:
725*0b57cec5SDimitry Andric   std::tuple<Iters...> iterators;
726*0b57cec5SDimitry Andric   std::tuple<Iters...> end_iterators;
727*0b57cec5SDimitry Andric 
728*0b57cec5SDimitry Andric   template <size_t... Ns>
729*0b57cec5SDimitry Andric   bool test(const zip_longest_iterator<Iters...> &other,
730*0b57cec5SDimitry Andric             index_sequence<Ns...>) const {
731*0b57cec5SDimitry Andric     return llvm::any_of(
732*0b57cec5SDimitry Andric         std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
733*0b57cec5SDimitry Andric                                     std::get<Ns>(other.iterators)...},
734*0b57cec5SDimitry Andric         identity<bool>{});
735*0b57cec5SDimitry Andric   }
736*0b57cec5SDimitry Andric 
737*0b57cec5SDimitry Andric   template <size_t... Ns> value_type deref(index_sequence<Ns...>) const {
738*0b57cec5SDimitry Andric     return value_type(
739*0b57cec5SDimitry Andric         deref_or_none(std::get<Ns>(iterators), std::get<Ns>(end_iterators))...);
740*0b57cec5SDimitry Andric   }
741*0b57cec5SDimitry Andric 
742*0b57cec5SDimitry Andric   template <size_t... Ns>
743*0b57cec5SDimitry Andric   decltype(iterators) tup_inc(index_sequence<Ns...>) const {
744*0b57cec5SDimitry Andric     return std::tuple<Iters...>(
745*0b57cec5SDimitry Andric         next_or_end(std::get<Ns>(iterators), std::get<Ns>(end_iterators))...);
746*0b57cec5SDimitry Andric   }
747*0b57cec5SDimitry Andric 
748*0b57cec5SDimitry Andric public:
749*0b57cec5SDimitry Andric   zip_longest_iterator(std::pair<Iters &&, Iters &&>... ts)
750*0b57cec5SDimitry Andric       : iterators(std::forward<Iters>(ts.first)...),
751*0b57cec5SDimitry Andric         end_iterators(std::forward<Iters>(ts.second)...) {}
752*0b57cec5SDimitry Andric 
753*0b57cec5SDimitry Andric   value_type operator*() { return deref(index_sequence_for<Iters...>{}); }
754*0b57cec5SDimitry Andric 
755*0b57cec5SDimitry Andric   value_type operator*() const { return deref(index_sequence_for<Iters...>{}); }
756*0b57cec5SDimitry Andric 
757*0b57cec5SDimitry Andric   zip_longest_iterator<Iters...> &operator++() {
758*0b57cec5SDimitry Andric     iterators = tup_inc(index_sequence_for<Iters...>{});
759*0b57cec5SDimitry Andric     return *this;
760*0b57cec5SDimitry Andric   }
761*0b57cec5SDimitry Andric 
762*0b57cec5SDimitry Andric   bool operator==(const zip_longest_iterator<Iters...> &other) const {
763*0b57cec5SDimitry Andric     return !test(other, index_sequence_for<Iters...>{});
764*0b57cec5SDimitry Andric   }
765*0b57cec5SDimitry Andric };
766*0b57cec5SDimitry Andric 
767*0b57cec5SDimitry Andric template <typename... Args> class zip_longest_range {
768*0b57cec5SDimitry Andric public:
769*0b57cec5SDimitry Andric   using iterator =
770*0b57cec5SDimitry Andric       zip_longest_iterator<decltype(adl_begin(std::declval<Args>()))...>;
771*0b57cec5SDimitry Andric   using iterator_category = typename iterator::iterator_category;
772*0b57cec5SDimitry Andric   using value_type = typename iterator::value_type;
773*0b57cec5SDimitry Andric   using difference_type = typename iterator::difference_type;
774*0b57cec5SDimitry Andric   using pointer = typename iterator::pointer;
775*0b57cec5SDimitry Andric   using reference = typename iterator::reference;
776*0b57cec5SDimitry Andric 
777*0b57cec5SDimitry Andric private:
778*0b57cec5SDimitry Andric   std::tuple<Args...> ts;
779*0b57cec5SDimitry Andric 
780*0b57cec5SDimitry Andric   template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) const {
781*0b57cec5SDimitry Andric     return iterator(std::make_pair(adl_begin(std::get<Ns>(ts)),
782*0b57cec5SDimitry Andric                                    adl_end(std::get<Ns>(ts)))...);
783*0b57cec5SDimitry Andric   }
784*0b57cec5SDimitry Andric 
785*0b57cec5SDimitry Andric   template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) const {
786*0b57cec5SDimitry Andric     return iterator(std::make_pair(adl_end(std::get<Ns>(ts)),
787*0b57cec5SDimitry Andric                                    adl_end(std::get<Ns>(ts)))...);
788*0b57cec5SDimitry Andric   }
789*0b57cec5SDimitry Andric 
790*0b57cec5SDimitry Andric public:
791*0b57cec5SDimitry Andric   zip_longest_range(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
792*0b57cec5SDimitry Andric 
793*0b57cec5SDimitry Andric   iterator begin() const { return begin_impl(index_sequence_for<Args...>{}); }
794*0b57cec5SDimitry Andric   iterator end() const { return end_impl(index_sequence_for<Args...>{}); }
795*0b57cec5SDimitry Andric };
796*0b57cec5SDimitry Andric } // namespace detail
797*0b57cec5SDimitry Andric 
798*0b57cec5SDimitry Andric /// Iterate over two or more iterators at the same time. Iteration continues
799*0b57cec5SDimitry Andric /// until all iterators reach the end. The llvm::Optional only contains a value
800*0b57cec5SDimitry Andric /// if the iterator has not reached the end.
801*0b57cec5SDimitry Andric template <typename T, typename U, typename... Args>
802*0b57cec5SDimitry Andric detail::zip_longest_range<T, U, Args...> zip_longest(T &&t, U &&u,
803*0b57cec5SDimitry Andric                                                      Args &&... args) {
804*0b57cec5SDimitry Andric   return detail::zip_longest_range<T, U, Args...>(
805*0b57cec5SDimitry Andric       std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
806*0b57cec5SDimitry Andric }
807*0b57cec5SDimitry Andric 
808*0b57cec5SDimitry Andric /// Iterator wrapper that concatenates sequences together.
809*0b57cec5SDimitry Andric ///
810*0b57cec5SDimitry Andric /// This can concatenate different iterators, even with different types, into
811*0b57cec5SDimitry Andric /// a single iterator provided the value types of all the concatenated
812*0b57cec5SDimitry Andric /// iterators expose `reference` and `pointer` types that can be converted to
813*0b57cec5SDimitry Andric /// `ValueT &` and `ValueT *` respectively. It doesn't support more
814*0b57cec5SDimitry Andric /// interesting/customized pointer or reference types.
815*0b57cec5SDimitry Andric ///
816*0b57cec5SDimitry Andric /// Currently this only supports forward or higher iterator categories as
817*0b57cec5SDimitry Andric /// inputs and always exposes a forward iterator interface.
818*0b57cec5SDimitry Andric template <typename ValueT, typename... IterTs>
819*0b57cec5SDimitry Andric class concat_iterator
820*0b57cec5SDimitry Andric     : public iterator_facade_base<concat_iterator<ValueT, IterTs...>,
821*0b57cec5SDimitry Andric                                   std::forward_iterator_tag, ValueT> {
822*0b57cec5SDimitry Andric   using BaseT = typename concat_iterator::iterator_facade_base;
823*0b57cec5SDimitry Andric 
824*0b57cec5SDimitry Andric   /// We store both the current and end iterators for each concatenated
825*0b57cec5SDimitry Andric   /// sequence in a tuple of pairs.
826*0b57cec5SDimitry Andric   ///
827*0b57cec5SDimitry Andric   /// Note that something like iterator_range seems nice at first here, but the
828*0b57cec5SDimitry Andric   /// range properties are of little benefit and end up getting in the way
829*0b57cec5SDimitry Andric   /// because we need to do mutation on the current iterators.
830*0b57cec5SDimitry Andric   std::tuple<IterTs...> Begins;
831*0b57cec5SDimitry Andric   std::tuple<IterTs...> Ends;
832*0b57cec5SDimitry Andric 
833*0b57cec5SDimitry Andric   /// Attempts to increment a specific iterator.
834*0b57cec5SDimitry Andric   ///
835*0b57cec5SDimitry Andric   /// Returns true if it was able to increment the iterator. Returns false if
836*0b57cec5SDimitry Andric   /// the iterator is already at the end iterator.
837*0b57cec5SDimitry Andric   template <size_t Index> bool incrementHelper() {
838*0b57cec5SDimitry Andric     auto &Begin = std::get<Index>(Begins);
839*0b57cec5SDimitry Andric     auto &End = std::get<Index>(Ends);
840*0b57cec5SDimitry Andric     if (Begin == End)
841*0b57cec5SDimitry Andric       return false;
842*0b57cec5SDimitry Andric 
843*0b57cec5SDimitry Andric     ++Begin;
844*0b57cec5SDimitry Andric     return true;
845*0b57cec5SDimitry Andric   }
846*0b57cec5SDimitry Andric 
847*0b57cec5SDimitry Andric   /// Increments the first non-end iterator.
848*0b57cec5SDimitry Andric   ///
849*0b57cec5SDimitry Andric   /// It is an error to call this with all iterators at the end.
850*0b57cec5SDimitry Andric   template <size_t... Ns> void increment(index_sequence<Ns...>) {
851*0b57cec5SDimitry Andric     // Build a sequence of functions to increment each iterator if possible.
852*0b57cec5SDimitry Andric     bool (concat_iterator::*IncrementHelperFns[])() = {
853*0b57cec5SDimitry Andric         &concat_iterator::incrementHelper<Ns>...};
854*0b57cec5SDimitry Andric 
855*0b57cec5SDimitry Andric     // Loop over them, and stop as soon as we succeed at incrementing one.
856*0b57cec5SDimitry Andric     for (auto &IncrementHelperFn : IncrementHelperFns)
857*0b57cec5SDimitry Andric       if ((this->*IncrementHelperFn)())
858*0b57cec5SDimitry Andric         return;
859*0b57cec5SDimitry Andric 
860*0b57cec5SDimitry Andric     llvm_unreachable("Attempted to increment an end concat iterator!");
861*0b57cec5SDimitry Andric   }
862*0b57cec5SDimitry Andric 
863*0b57cec5SDimitry Andric   /// Returns null if the specified iterator is at the end. Otherwise,
864*0b57cec5SDimitry Andric   /// dereferences the iterator and returns the address of the resulting
865*0b57cec5SDimitry Andric   /// reference.
866*0b57cec5SDimitry Andric   template <size_t Index> ValueT *getHelper() const {
867*0b57cec5SDimitry Andric     auto &Begin = std::get<Index>(Begins);
868*0b57cec5SDimitry Andric     auto &End = std::get<Index>(Ends);
869*0b57cec5SDimitry Andric     if (Begin == End)
870*0b57cec5SDimitry Andric       return nullptr;
871*0b57cec5SDimitry Andric 
872*0b57cec5SDimitry Andric     return &*Begin;
873*0b57cec5SDimitry Andric   }
874*0b57cec5SDimitry Andric 
875*0b57cec5SDimitry Andric   /// Finds the first non-end iterator, dereferences, and returns the resulting
876*0b57cec5SDimitry Andric   /// reference.
877*0b57cec5SDimitry Andric   ///
878*0b57cec5SDimitry Andric   /// It is an error to call this with all iterators at the end.
879*0b57cec5SDimitry Andric   template <size_t... Ns> ValueT &get(index_sequence<Ns...>) const {
880*0b57cec5SDimitry Andric     // Build a sequence of functions to get from iterator if possible.
881*0b57cec5SDimitry Andric     ValueT *(concat_iterator::*GetHelperFns[])() const = {
882*0b57cec5SDimitry Andric         &concat_iterator::getHelper<Ns>...};
883*0b57cec5SDimitry Andric 
884*0b57cec5SDimitry Andric     // Loop over them, and return the first result we find.
885*0b57cec5SDimitry Andric     for (auto &GetHelperFn : GetHelperFns)
886*0b57cec5SDimitry Andric       if (ValueT *P = (this->*GetHelperFn)())
887*0b57cec5SDimitry Andric         return *P;
888*0b57cec5SDimitry Andric 
889*0b57cec5SDimitry Andric     llvm_unreachable("Attempted to get a pointer from an end concat iterator!");
890*0b57cec5SDimitry Andric   }
891*0b57cec5SDimitry Andric 
892*0b57cec5SDimitry Andric public:
893*0b57cec5SDimitry Andric   /// Constructs an iterator from a squence of ranges.
894*0b57cec5SDimitry Andric   ///
895*0b57cec5SDimitry Andric   /// We need the full range to know how to switch between each of the
896*0b57cec5SDimitry Andric   /// iterators.
897*0b57cec5SDimitry Andric   template <typename... RangeTs>
898*0b57cec5SDimitry Andric   explicit concat_iterator(RangeTs &&... Ranges)
899*0b57cec5SDimitry Andric       : Begins(std::begin(Ranges)...), Ends(std::end(Ranges)...) {}
900*0b57cec5SDimitry Andric 
901*0b57cec5SDimitry Andric   using BaseT::operator++;
902*0b57cec5SDimitry Andric 
903*0b57cec5SDimitry Andric   concat_iterator &operator++() {
904*0b57cec5SDimitry Andric     increment(index_sequence_for<IterTs...>());
905*0b57cec5SDimitry Andric     return *this;
906*0b57cec5SDimitry Andric   }
907*0b57cec5SDimitry Andric 
908*0b57cec5SDimitry Andric   ValueT &operator*() const { return get(index_sequence_for<IterTs...>()); }
909*0b57cec5SDimitry Andric 
910*0b57cec5SDimitry Andric   bool operator==(const concat_iterator &RHS) const {
911*0b57cec5SDimitry Andric     return Begins == RHS.Begins && Ends == RHS.Ends;
912*0b57cec5SDimitry Andric   }
913*0b57cec5SDimitry Andric };
914*0b57cec5SDimitry Andric 
915*0b57cec5SDimitry Andric namespace detail {
916*0b57cec5SDimitry Andric 
917*0b57cec5SDimitry Andric /// Helper to store a sequence of ranges being concatenated and access them.
918*0b57cec5SDimitry Andric ///
919*0b57cec5SDimitry Andric /// This is designed to facilitate providing actual storage when temporaries
920*0b57cec5SDimitry Andric /// are passed into the constructor such that we can use it as part of range
921*0b57cec5SDimitry Andric /// based for loops.
922*0b57cec5SDimitry Andric template <typename ValueT, typename... RangeTs> class concat_range {
923*0b57cec5SDimitry Andric public:
924*0b57cec5SDimitry Andric   using iterator =
925*0b57cec5SDimitry Andric       concat_iterator<ValueT,
926*0b57cec5SDimitry Andric                       decltype(std::begin(std::declval<RangeTs &>()))...>;
927*0b57cec5SDimitry Andric 
928*0b57cec5SDimitry Andric private:
929*0b57cec5SDimitry Andric   std::tuple<RangeTs...> Ranges;
930*0b57cec5SDimitry Andric 
931*0b57cec5SDimitry Andric   template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) {
932*0b57cec5SDimitry Andric     return iterator(std::get<Ns>(Ranges)...);
933*0b57cec5SDimitry Andric   }
934*0b57cec5SDimitry Andric   template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) {
935*0b57cec5SDimitry Andric     return iterator(make_range(std::end(std::get<Ns>(Ranges)),
936*0b57cec5SDimitry Andric                                std::end(std::get<Ns>(Ranges)))...);
937*0b57cec5SDimitry Andric   }
938*0b57cec5SDimitry Andric 
939*0b57cec5SDimitry Andric public:
940*0b57cec5SDimitry Andric   concat_range(RangeTs &&... Ranges)
941*0b57cec5SDimitry Andric       : Ranges(std::forward<RangeTs>(Ranges)...) {}
942*0b57cec5SDimitry Andric 
943*0b57cec5SDimitry Andric   iterator begin() { return begin_impl(index_sequence_for<RangeTs...>{}); }
944*0b57cec5SDimitry Andric   iterator end() { return end_impl(index_sequence_for<RangeTs...>{}); }
945*0b57cec5SDimitry Andric };
946*0b57cec5SDimitry Andric 
947*0b57cec5SDimitry Andric } // end namespace detail
948*0b57cec5SDimitry Andric 
949*0b57cec5SDimitry Andric /// Concatenated range across two or more ranges.
950*0b57cec5SDimitry Andric ///
951*0b57cec5SDimitry Andric /// The desired value type must be explicitly specified.
952*0b57cec5SDimitry Andric template <typename ValueT, typename... RangeTs>
953*0b57cec5SDimitry Andric detail::concat_range<ValueT, RangeTs...> concat(RangeTs &&... Ranges) {
954*0b57cec5SDimitry Andric   static_assert(sizeof...(RangeTs) > 1,
955*0b57cec5SDimitry Andric                 "Need more than one range to concatenate!");
956*0b57cec5SDimitry Andric   return detail::concat_range<ValueT, RangeTs...>(
957*0b57cec5SDimitry Andric       std::forward<RangeTs>(Ranges)...);
958*0b57cec5SDimitry Andric }
959*0b57cec5SDimitry Andric 
960*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
961*0b57cec5SDimitry Andric //     Extra additions to <utility>
962*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
963*0b57cec5SDimitry Andric 
964*0b57cec5SDimitry Andric /// Function object to check whether the first component of a std::pair
965*0b57cec5SDimitry Andric /// compares less than the first component of another std::pair.
966*0b57cec5SDimitry Andric struct less_first {
967*0b57cec5SDimitry Andric   template <typename T> bool operator()(const T &lhs, const T &rhs) const {
968*0b57cec5SDimitry Andric     return lhs.first < rhs.first;
969*0b57cec5SDimitry Andric   }
970*0b57cec5SDimitry Andric };
971*0b57cec5SDimitry Andric 
972*0b57cec5SDimitry Andric /// Function object to check whether the second component of a std::pair
973*0b57cec5SDimitry Andric /// compares less than the second component of another std::pair.
974*0b57cec5SDimitry Andric struct less_second {
975*0b57cec5SDimitry Andric   template <typename T> bool operator()(const T &lhs, const T &rhs) const {
976*0b57cec5SDimitry Andric     return lhs.second < rhs.second;
977*0b57cec5SDimitry Andric   }
978*0b57cec5SDimitry Andric };
979*0b57cec5SDimitry Andric 
980*0b57cec5SDimitry Andric /// \brief Function object to apply a binary function to the first component of
981*0b57cec5SDimitry Andric /// a std::pair.
982*0b57cec5SDimitry Andric template<typename FuncTy>
983*0b57cec5SDimitry Andric struct on_first {
984*0b57cec5SDimitry Andric   FuncTy func;
985*0b57cec5SDimitry Andric 
986*0b57cec5SDimitry Andric   template <typename T>
987*0b57cec5SDimitry Andric   auto operator()(const T &lhs, const T &rhs) const
988*0b57cec5SDimitry Andric       -> decltype(func(lhs.first, rhs.first)) {
989*0b57cec5SDimitry Andric     return func(lhs.first, rhs.first);
990*0b57cec5SDimitry Andric   }
991*0b57cec5SDimitry Andric };
992*0b57cec5SDimitry Andric 
993*0b57cec5SDimitry Andric // A subset of N3658. More stuff can be added as-needed.
994*0b57cec5SDimitry Andric 
995*0b57cec5SDimitry Andric /// Represents a compile-time sequence of integers.
996*0b57cec5SDimitry Andric template <class T, T... I> struct integer_sequence {
997*0b57cec5SDimitry Andric   using value_type = T;
998*0b57cec5SDimitry Andric 
999*0b57cec5SDimitry Andric   static constexpr size_t size() { return sizeof...(I); }
1000*0b57cec5SDimitry Andric };
1001*0b57cec5SDimitry Andric 
1002*0b57cec5SDimitry Andric /// Alias for the common case of a sequence of size_ts.
1003*0b57cec5SDimitry Andric template <size_t... I>
1004*0b57cec5SDimitry Andric struct index_sequence : integer_sequence<std::size_t, I...> {};
1005*0b57cec5SDimitry Andric 
1006*0b57cec5SDimitry Andric template <std::size_t N, std::size_t... I>
1007*0b57cec5SDimitry Andric struct build_index_impl : build_index_impl<N - 1, N - 1, I...> {};
1008*0b57cec5SDimitry Andric template <std::size_t... I>
1009*0b57cec5SDimitry Andric struct build_index_impl<0, I...> : index_sequence<I...> {};
1010*0b57cec5SDimitry Andric 
1011*0b57cec5SDimitry Andric /// Creates a compile-time integer sequence for a parameter pack.
1012*0b57cec5SDimitry Andric template <class... Ts>
1013*0b57cec5SDimitry Andric struct index_sequence_for : build_index_impl<sizeof...(Ts)> {};
1014*0b57cec5SDimitry Andric 
1015*0b57cec5SDimitry Andric /// Utility type to build an inheritance chain that makes it easy to rank
1016*0b57cec5SDimitry Andric /// overload candidates.
1017*0b57cec5SDimitry Andric template <int N> struct rank : rank<N - 1> {};
1018*0b57cec5SDimitry Andric template <> struct rank<0> {};
1019*0b57cec5SDimitry Andric 
1020*0b57cec5SDimitry Andric /// traits class for checking whether type T is one of any of the given
1021*0b57cec5SDimitry Andric /// types in the variadic list.
1022*0b57cec5SDimitry Andric template <typename T, typename... Ts> struct is_one_of {
1023*0b57cec5SDimitry Andric   static const bool value = false;
1024*0b57cec5SDimitry Andric };
1025*0b57cec5SDimitry Andric 
1026*0b57cec5SDimitry Andric template <typename T, typename U, typename... Ts>
1027*0b57cec5SDimitry Andric struct is_one_of<T, U, Ts...> {
1028*0b57cec5SDimitry Andric   static const bool value =
1029*0b57cec5SDimitry Andric       std::is_same<T, U>::value || is_one_of<T, Ts...>::value;
1030*0b57cec5SDimitry Andric };
1031*0b57cec5SDimitry Andric 
1032*0b57cec5SDimitry Andric /// traits class for checking whether type T is a base class for all
1033*0b57cec5SDimitry Andric ///  the given types in the variadic list.
1034*0b57cec5SDimitry Andric template <typename T, typename... Ts> struct are_base_of {
1035*0b57cec5SDimitry Andric   static const bool value = true;
1036*0b57cec5SDimitry Andric };
1037*0b57cec5SDimitry Andric 
1038*0b57cec5SDimitry Andric template <typename T, typename U, typename... Ts>
1039*0b57cec5SDimitry Andric struct are_base_of<T, U, Ts...> {
1040*0b57cec5SDimitry Andric   static const bool value =
1041*0b57cec5SDimitry Andric       std::is_base_of<T, U>::value && are_base_of<T, Ts...>::value;
1042*0b57cec5SDimitry Andric };
1043*0b57cec5SDimitry Andric 
1044*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1045*0b57cec5SDimitry Andric //     Extra additions for arrays
1046*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1047*0b57cec5SDimitry Andric 
1048*0b57cec5SDimitry Andric /// Find the length of an array.
1049*0b57cec5SDimitry Andric template <class T, std::size_t N>
1050*0b57cec5SDimitry Andric constexpr inline size_t array_lengthof(T (&)[N]) {
1051*0b57cec5SDimitry Andric   return N;
1052*0b57cec5SDimitry Andric }
1053*0b57cec5SDimitry Andric 
1054*0b57cec5SDimitry Andric /// Adapt std::less<T> for array_pod_sort.
1055*0b57cec5SDimitry Andric template<typename T>
1056*0b57cec5SDimitry Andric inline int array_pod_sort_comparator(const void *P1, const void *P2) {
1057*0b57cec5SDimitry Andric   if (std::less<T>()(*reinterpret_cast<const T*>(P1),
1058*0b57cec5SDimitry Andric                      *reinterpret_cast<const T*>(P2)))
1059*0b57cec5SDimitry Andric     return -1;
1060*0b57cec5SDimitry Andric   if (std::less<T>()(*reinterpret_cast<const T*>(P2),
1061*0b57cec5SDimitry Andric                      *reinterpret_cast<const T*>(P1)))
1062*0b57cec5SDimitry Andric     return 1;
1063*0b57cec5SDimitry Andric   return 0;
1064*0b57cec5SDimitry Andric }
1065*0b57cec5SDimitry Andric 
1066*0b57cec5SDimitry Andric /// get_array_pod_sort_comparator - This is an internal helper function used to
1067*0b57cec5SDimitry Andric /// get type deduction of T right.
1068*0b57cec5SDimitry Andric template<typename T>
1069*0b57cec5SDimitry Andric inline int (*get_array_pod_sort_comparator(const T &))
1070*0b57cec5SDimitry Andric              (const void*, const void*) {
1071*0b57cec5SDimitry Andric   return array_pod_sort_comparator<T>;
1072*0b57cec5SDimitry Andric }
1073*0b57cec5SDimitry Andric 
1074*0b57cec5SDimitry Andric /// array_pod_sort - This sorts an array with the specified start and end
1075*0b57cec5SDimitry Andric /// extent.  This is just like std::sort, except that it calls qsort instead of
1076*0b57cec5SDimitry Andric /// using an inlined template.  qsort is slightly slower than std::sort, but
1077*0b57cec5SDimitry Andric /// most sorts are not performance critical in LLVM and std::sort has to be
1078*0b57cec5SDimitry Andric /// template instantiated for each type, leading to significant measured code
1079*0b57cec5SDimitry Andric /// bloat.  This function should generally be used instead of std::sort where
1080*0b57cec5SDimitry Andric /// possible.
1081*0b57cec5SDimitry Andric ///
1082*0b57cec5SDimitry Andric /// This function assumes that you have simple POD-like types that can be
1083*0b57cec5SDimitry Andric /// compared with std::less and can be moved with memcpy.  If this isn't true,
1084*0b57cec5SDimitry Andric /// you should use std::sort.
1085*0b57cec5SDimitry Andric ///
1086*0b57cec5SDimitry Andric /// NOTE: If qsort_r were portable, we could allow a custom comparator and
1087*0b57cec5SDimitry Andric /// default to std::less.
1088*0b57cec5SDimitry Andric template<class IteratorTy>
1089*0b57cec5SDimitry Andric inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
1090*0b57cec5SDimitry Andric   // Don't inefficiently call qsort with one element or trigger undefined
1091*0b57cec5SDimitry Andric   // behavior with an empty sequence.
1092*0b57cec5SDimitry Andric   auto NElts = End - Start;
1093*0b57cec5SDimitry Andric   if (NElts <= 1) return;
1094*0b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
1095*0b57cec5SDimitry Andric   std::mt19937 Generator(std::random_device{}());
1096*0b57cec5SDimitry Andric   std::shuffle(Start, End, Generator);
1097*0b57cec5SDimitry Andric #endif
1098*0b57cec5SDimitry Andric   qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start));
1099*0b57cec5SDimitry Andric }
1100*0b57cec5SDimitry Andric 
1101*0b57cec5SDimitry Andric template <class IteratorTy>
1102*0b57cec5SDimitry Andric inline void array_pod_sort(
1103*0b57cec5SDimitry Andric     IteratorTy Start, IteratorTy End,
1104*0b57cec5SDimitry Andric     int (*Compare)(
1105*0b57cec5SDimitry Andric         const typename std::iterator_traits<IteratorTy>::value_type *,
1106*0b57cec5SDimitry Andric         const typename std::iterator_traits<IteratorTy>::value_type *)) {
1107*0b57cec5SDimitry Andric   // Don't inefficiently call qsort with one element or trigger undefined
1108*0b57cec5SDimitry Andric   // behavior with an empty sequence.
1109*0b57cec5SDimitry Andric   auto NElts = End - Start;
1110*0b57cec5SDimitry Andric   if (NElts <= 1) return;
1111*0b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
1112*0b57cec5SDimitry Andric   std::mt19937 Generator(std::random_device{}());
1113*0b57cec5SDimitry Andric   std::shuffle(Start, End, Generator);
1114*0b57cec5SDimitry Andric #endif
1115*0b57cec5SDimitry Andric   qsort(&*Start, NElts, sizeof(*Start),
1116*0b57cec5SDimitry Andric         reinterpret_cast<int (*)(const void *, const void *)>(Compare));
1117*0b57cec5SDimitry Andric }
1118*0b57cec5SDimitry Andric 
1119*0b57cec5SDimitry Andric // Provide wrappers to std::sort which shuffle the elements before sorting
1120*0b57cec5SDimitry Andric // to help uncover non-deterministic behavior (PR35135).
1121*0b57cec5SDimitry Andric template <typename IteratorTy>
1122*0b57cec5SDimitry Andric inline void sort(IteratorTy Start, IteratorTy End) {
1123*0b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
1124*0b57cec5SDimitry Andric   std::mt19937 Generator(std::random_device{}());
1125*0b57cec5SDimitry Andric   std::shuffle(Start, End, Generator);
1126*0b57cec5SDimitry Andric #endif
1127*0b57cec5SDimitry Andric   std::sort(Start, End);
1128*0b57cec5SDimitry Andric }
1129*0b57cec5SDimitry Andric 
1130*0b57cec5SDimitry Andric template <typename Container> inline void sort(Container &&C) {
1131*0b57cec5SDimitry Andric   llvm::sort(adl_begin(C), adl_end(C));
1132*0b57cec5SDimitry Andric }
1133*0b57cec5SDimitry Andric 
1134*0b57cec5SDimitry Andric template <typename IteratorTy, typename Compare>
1135*0b57cec5SDimitry Andric inline void sort(IteratorTy Start, IteratorTy End, Compare Comp) {
1136*0b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
1137*0b57cec5SDimitry Andric   std::mt19937 Generator(std::random_device{}());
1138*0b57cec5SDimitry Andric   std::shuffle(Start, End, Generator);
1139*0b57cec5SDimitry Andric #endif
1140*0b57cec5SDimitry Andric   std::sort(Start, End, Comp);
1141*0b57cec5SDimitry Andric }
1142*0b57cec5SDimitry Andric 
1143*0b57cec5SDimitry Andric template <typename Container, typename Compare>
1144*0b57cec5SDimitry Andric inline void sort(Container &&C, Compare Comp) {
1145*0b57cec5SDimitry Andric   llvm::sort(adl_begin(C), adl_end(C), Comp);
1146*0b57cec5SDimitry Andric }
1147*0b57cec5SDimitry Andric 
1148*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1149*0b57cec5SDimitry Andric //     Extra additions to <algorithm>
1150*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1151*0b57cec5SDimitry Andric 
1152*0b57cec5SDimitry Andric /// For a container of pointers, deletes the pointers and then clears the
1153*0b57cec5SDimitry Andric /// container.
1154*0b57cec5SDimitry Andric template<typename Container>
1155*0b57cec5SDimitry Andric void DeleteContainerPointers(Container &C) {
1156*0b57cec5SDimitry Andric   for (auto V : C)
1157*0b57cec5SDimitry Andric     delete V;
1158*0b57cec5SDimitry Andric   C.clear();
1159*0b57cec5SDimitry Andric }
1160*0b57cec5SDimitry Andric 
1161*0b57cec5SDimitry Andric /// In a container of pairs (usually a map) whose second element is a pointer,
1162*0b57cec5SDimitry Andric /// deletes the second elements and then clears the container.
1163*0b57cec5SDimitry Andric template<typename Container>
1164*0b57cec5SDimitry Andric void DeleteContainerSeconds(Container &C) {
1165*0b57cec5SDimitry Andric   for (auto &V : C)
1166*0b57cec5SDimitry Andric     delete V.second;
1167*0b57cec5SDimitry Andric   C.clear();
1168*0b57cec5SDimitry Andric }
1169*0b57cec5SDimitry Andric 
1170*0b57cec5SDimitry Andric /// Get the size of a range. This is a wrapper function around std::distance
1171*0b57cec5SDimitry Andric /// which is only enabled when the operation is O(1).
1172*0b57cec5SDimitry Andric template <typename R>
1173*0b57cec5SDimitry Andric auto size(R &&Range, typename std::enable_if<
1174*0b57cec5SDimitry Andric                          std::is_same<typename std::iterator_traits<decltype(
1175*0b57cec5SDimitry Andric                                           Range.begin())>::iterator_category,
1176*0b57cec5SDimitry Andric                                       std::random_access_iterator_tag>::value,
1177*0b57cec5SDimitry Andric                          void>::type * = nullptr)
1178*0b57cec5SDimitry Andric     -> decltype(std::distance(Range.begin(), Range.end())) {
1179*0b57cec5SDimitry Andric   return std::distance(Range.begin(), Range.end());
1180*0b57cec5SDimitry Andric }
1181*0b57cec5SDimitry Andric 
1182*0b57cec5SDimitry Andric /// Provide wrappers to std::for_each which take ranges instead of having to
1183*0b57cec5SDimitry Andric /// pass begin/end explicitly.
1184*0b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1185*0b57cec5SDimitry Andric UnaryPredicate for_each(R &&Range, UnaryPredicate P) {
1186*0b57cec5SDimitry Andric   return std::for_each(adl_begin(Range), adl_end(Range), P);
1187*0b57cec5SDimitry Andric }
1188*0b57cec5SDimitry Andric 
1189*0b57cec5SDimitry Andric /// Provide wrappers to std::all_of which take ranges instead of having to pass
1190*0b57cec5SDimitry Andric /// begin/end explicitly.
1191*0b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1192*0b57cec5SDimitry Andric bool all_of(R &&Range, UnaryPredicate P) {
1193*0b57cec5SDimitry Andric   return std::all_of(adl_begin(Range), adl_end(Range), P);
1194*0b57cec5SDimitry Andric }
1195*0b57cec5SDimitry Andric 
1196*0b57cec5SDimitry Andric /// Provide wrappers to std::any_of which take ranges instead of having to pass
1197*0b57cec5SDimitry Andric /// begin/end explicitly.
1198*0b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1199*0b57cec5SDimitry Andric bool any_of(R &&Range, UnaryPredicate P) {
1200*0b57cec5SDimitry Andric   return std::any_of(adl_begin(Range), adl_end(Range), P);
1201*0b57cec5SDimitry Andric }
1202*0b57cec5SDimitry Andric 
1203*0b57cec5SDimitry Andric /// Provide wrappers to std::none_of which take ranges instead of having to pass
1204*0b57cec5SDimitry Andric /// begin/end explicitly.
1205*0b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1206*0b57cec5SDimitry Andric bool none_of(R &&Range, UnaryPredicate P) {
1207*0b57cec5SDimitry Andric   return std::none_of(adl_begin(Range), adl_end(Range), P);
1208*0b57cec5SDimitry Andric }
1209*0b57cec5SDimitry Andric 
1210*0b57cec5SDimitry Andric /// Provide wrappers to std::find which take ranges instead of having to pass
1211*0b57cec5SDimitry Andric /// begin/end explicitly.
1212*0b57cec5SDimitry Andric template <typename R, typename T>
1213*0b57cec5SDimitry Andric auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range)) {
1214*0b57cec5SDimitry Andric   return std::find(adl_begin(Range), adl_end(Range), Val);
1215*0b57cec5SDimitry Andric }
1216*0b57cec5SDimitry Andric 
1217*0b57cec5SDimitry Andric /// Provide wrappers to std::find_if which take ranges instead of having to pass
1218*0b57cec5SDimitry Andric /// begin/end explicitly.
1219*0b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1220*0b57cec5SDimitry Andric auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1221*0b57cec5SDimitry Andric   return std::find_if(adl_begin(Range), adl_end(Range), P);
1222*0b57cec5SDimitry Andric }
1223*0b57cec5SDimitry Andric 
1224*0b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1225*0b57cec5SDimitry Andric auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1226*0b57cec5SDimitry Andric   return std::find_if_not(adl_begin(Range), adl_end(Range), P);
1227*0b57cec5SDimitry Andric }
1228*0b57cec5SDimitry Andric 
1229*0b57cec5SDimitry Andric /// Provide wrappers to std::remove_if which take ranges instead of having to
1230*0b57cec5SDimitry Andric /// pass begin/end explicitly.
1231*0b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1232*0b57cec5SDimitry Andric auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1233*0b57cec5SDimitry Andric   return std::remove_if(adl_begin(Range), adl_end(Range), P);
1234*0b57cec5SDimitry Andric }
1235*0b57cec5SDimitry Andric 
1236*0b57cec5SDimitry Andric /// Provide wrappers to std::copy_if which take ranges instead of having to
1237*0b57cec5SDimitry Andric /// pass begin/end explicitly.
1238*0b57cec5SDimitry Andric template <typename R, typename OutputIt, typename UnaryPredicate>
1239*0b57cec5SDimitry Andric OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) {
1240*0b57cec5SDimitry Andric   return std::copy_if(adl_begin(Range), adl_end(Range), Out, P);
1241*0b57cec5SDimitry Andric }
1242*0b57cec5SDimitry Andric 
1243*0b57cec5SDimitry Andric template <typename R, typename OutputIt>
1244*0b57cec5SDimitry Andric OutputIt copy(R &&Range, OutputIt Out) {
1245*0b57cec5SDimitry Andric   return std::copy(adl_begin(Range), adl_end(Range), Out);
1246*0b57cec5SDimitry Andric }
1247*0b57cec5SDimitry Andric 
1248*0b57cec5SDimitry Andric /// Wrapper function around std::find to detect if an element exists
1249*0b57cec5SDimitry Andric /// in a container.
1250*0b57cec5SDimitry Andric template <typename R, typename E>
1251*0b57cec5SDimitry Andric bool is_contained(R &&Range, const E &Element) {
1252*0b57cec5SDimitry Andric   return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range);
1253*0b57cec5SDimitry Andric }
1254*0b57cec5SDimitry Andric 
1255*0b57cec5SDimitry Andric /// Wrapper function around std::count to count the number of times an element
1256*0b57cec5SDimitry Andric /// \p Element occurs in the given range \p Range.
1257*0b57cec5SDimitry Andric template <typename R, typename E>
1258*0b57cec5SDimitry Andric auto count(R &&Range, const E &Element) ->
1259*0b57cec5SDimitry Andric     typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
1260*0b57cec5SDimitry Andric   return std::count(adl_begin(Range), adl_end(Range), Element);
1261*0b57cec5SDimitry Andric }
1262*0b57cec5SDimitry Andric 
1263*0b57cec5SDimitry Andric /// Wrapper function around std::count_if to count the number of times an
1264*0b57cec5SDimitry Andric /// element satisfying a given predicate occurs in a range.
1265*0b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1266*0b57cec5SDimitry Andric auto count_if(R &&Range, UnaryPredicate P) ->
1267*0b57cec5SDimitry Andric     typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
1268*0b57cec5SDimitry Andric   return std::count_if(adl_begin(Range), adl_end(Range), P);
1269*0b57cec5SDimitry Andric }
1270*0b57cec5SDimitry Andric 
1271*0b57cec5SDimitry Andric /// Wrapper function around std::transform to apply a function to a range and
1272*0b57cec5SDimitry Andric /// store the result elsewhere.
1273*0b57cec5SDimitry Andric template <typename R, typename OutputIt, typename UnaryPredicate>
1274*0b57cec5SDimitry Andric OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P) {
1275*0b57cec5SDimitry Andric   return std::transform(adl_begin(Range), adl_end(Range), d_first, P);
1276*0b57cec5SDimitry Andric }
1277*0b57cec5SDimitry Andric 
1278*0b57cec5SDimitry Andric /// Provide wrappers to std::partition which take ranges instead of having to
1279*0b57cec5SDimitry Andric /// pass begin/end explicitly.
1280*0b57cec5SDimitry Andric template <typename R, typename UnaryPredicate>
1281*0b57cec5SDimitry Andric auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1282*0b57cec5SDimitry Andric   return std::partition(adl_begin(Range), adl_end(Range), P);
1283*0b57cec5SDimitry Andric }
1284*0b57cec5SDimitry Andric 
1285*0b57cec5SDimitry Andric /// Provide wrappers to std::lower_bound which take ranges instead of having to
1286*0b57cec5SDimitry Andric /// pass begin/end explicitly.
1287*0b57cec5SDimitry Andric template <typename R, typename T>
1288*0b57cec5SDimitry Andric auto lower_bound(R &&Range, T &&Value) -> decltype(adl_begin(Range)) {
1289*0b57cec5SDimitry Andric   return std::lower_bound(adl_begin(Range), adl_end(Range),
1290*0b57cec5SDimitry Andric                           std::forward<T>(Value));
1291*0b57cec5SDimitry Andric }
1292*0b57cec5SDimitry Andric 
1293*0b57cec5SDimitry Andric template <typename R, typename T, typename Compare>
1294*0b57cec5SDimitry Andric auto lower_bound(R &&Range, T &&Value, Compare C)
1295*0b57cec5SDimitry Andric     -> decltype(adl_begin(Range)) {
1296*0b57cec5SDimitry Andric   return std::lower_bound(adl_begin(Range), adl_end(Range),
1297*0b57cec5SDimitry Andric                           std::forward<T>(Value), C);
1298*0b57cec5SDimitry Andric }
1299*0b57cec5SDimitry Andric 
1300*0b57cec5SDimitry Andric /// Provide wrappers to std::upper_bound which take ranges instead of having to
1301*0b57cec5SDimitry Andric /// pass begin/end explicitly.
1302*0b57cec5SDimitry Andric template <typename R, typename T>
1303*0b57cec5SDimitry Andric auto upper_bound(R &&Range, T &&Value) -> decltype(adl_begin(Range)) {
1304*0b57cec5SDimitry Andric   return std::upper_bound(adl_begin(Range), adl_end(Range),
1305*0b57cec5SDimitry Andric                           std::forward<T>(Value));
1306*0b57cec5SDimitry Andric }
1307*0b57cec5SDimitry Andric 
1308*0b57cec5SDimitry Andric template <typename R, typename T, typename Compare>
1309*0b57cec5SDimitry Andric auto upper_bound(R &&Range, T &&Value, Compare C)
1310*0b57cec5SDimitry Andric     -> decltype(adl_begin(Range)) {
1311*0b57cec5SDimitry Andric   return std::upper_bound(adl_begin(Range), adl_end(Range),
1312*0b57cec5SDimitry Andric                           std::forward<T>(Value), C);
1313*0b57cec5SDimitry Andric }
1314*0b57cec5SDimitry Andric 
1315*0b57cec5SDimitry Andric template <typename R>
1316*0b57cec5SDimitry Andric void stable_sort(R &&Range) {
1317*0b57cec5SDimitry Andric   std::stable_sort(adl_begin(Range), adl_end(Range));
1318*0b57cec5SDimitry Andric }
1319*0b57cec5SDimitry Andric 
1320*0b57cec5SDimitry Andric template <typename R, typename Compare>
1321*0b57cec5SDimitry Andric void stable_sort(R &&Range, Compare C) {
1322*0b57cec5SDimitry Andric   std::stable_sort(adl_begin(Range), adl_end(Range), C);
1323*0b57cec5SDimitry Andric }
1324*0b57cec5SDimitry Andric 
1325*0b57cec5SDimitry Andric /// Binary search for the first iterator in a range where a predicate is false.
1326*0b57cec5SDimitry Andric /// Requires that C is always true below some limit, and always false above it.
1327*0b57cec5SDimitry Andric template <typename R, typename Predicate,
1328*0b57cec5SDimitry Andric           typename Val = decltype(*adl_begin(std::declval<R>()))>
1329*0b57cec5SDimitry Andric auto partition_point(R &&Range, Predicate P) -> decltype(adl_begin(Range)) {
1330*0b57cec5SDimitry Andric   return std::partition_point(adl_begin(Range), adl_end(Range), P);
1331*0b57cec5SDimitry Andric }
1332*0b57cec5SDimitry Andric 
1333*0b57cec5SDimitry Andric /// Wrapper function around std::equal to detect if all elements
1334*0b57cec5SDimitry Andric /// in a container are same.
1335*0b57cec5SDimitry Andric template <typename R>
1336*0b57cec5SDimitry Andric bool is_splat(R &&Range) {
1337*0b57cec5SDimitry Andric   size_t range_size = size(Range);
1338*0b57cec5SDimitry Andric   return range_size != 0 && (range_size == 1 ||
1339*0b57cec5SDimitry Andric          std::equal(adl_begin(Range) + 1, adl_end(Range), adl_begin(Range)));
1340*0b57cec5SDimitry Andric }
1341*0b57cec5SDimitry Andric 
1342*0b57cec5SDimitry Andric /// Given a range of type R, iterate the entire range and return a
1343*0b57cec5SDimitry Andric /// SmallVector with elements of the vector.  This is useful, for example,
1344*0b57cec5SDimitry Andric /// when you want to iterate a range and then sort the results.
1345*0b57cec5SDimitry Andric template <unsigned Size, typename R>
1346*0b57cec5SDimitry Andric SmallVector<typename std::remove_const<detail::ValueOfRange<R>>::type, Size>
1347*0b57cec5SDimitry Andric to_vector(R &&Range) {
1348*0b57cec5SDimitry Andric   return {adl_begin(Range), adl_end(Range)};
1349*0b57cec5SDimitry Andric }
1350*0b57cec5SDimitry Andric 
1351*0b57cec5SDimitry Andric /// Provide a container algorithm similar to C++ Library Fundamentals v2's
1352*0b57cec5SDimitry Andric /// `erase_if` which is equivalent to:
1353*0b57cec5SDimitry Andric ///
1354*0b57cec5SDimitry Andric ///   C.erase(remove_if(C, pred), C.end());
1355*0b57cec5SDimitry Andric ///
1356*0b57cec5SDimitry Andric /// This version works for any container with an erase method call accepting
1357*0b57cec5SDimitry Andric /// two iterators.
1358*0b57cec5SDimitry Andric template <typename Container, typename UnaryPredicate>
1359*0b57cec5SDimitry Andric void erase_if(Container &C, UnaryPredicate P) {
1360*0b57cec5SDimitry Andric   C.erase(remove_if(C, P), C.end());
1361*0b57cec5SDimitry Andric }
1362*0b57cec5SDimitry Andric 
1363*0b57cec5SDimitry Andric /// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
1364*0b57cec5SDimitry Andric /// the range [ValIt, ValEnd) (which is not from the same container).
1365*0b57cec5SDimitry Andric template<typename Container, typename RandomAccessIterator>
1366*0b57cec5SDimitry Andric void replace(Container &Cont, typename Container::iterator ContIt,
1367*0b57cec5SDimitry Andric              typename Container::iterator ContEnd, RandomAccessIterator ValIt,
1368*0b57cec5SDimitry Andric              RandomAccessIterator ValEnd) {
1369*0b57cec5SDimitry Andric   while (true) {
1370*0b57cec5SDimitry Andric     if (ValIt == ValEnd) {
1371*0b57cec5SDimitry Andric       Cont.erase(ContIt, ContEnd);
1372*0b57cec5SDimitry Andric       return;
1373*0b57cec5SDimitry Andric     } else if (ContIt == ContEnd) {
1374*0b57cec5SDimitry Andric       Cont.insert(ContIt, ValIt, ValEnd);
1375*0b57cec5SDimitry Andric       return;
1376*0b57cec5SDimitry Andric     }
1377*0b57cec5SDimitry Andric     *ContIt++ = *ValIt++;
1378*0b57cec5SDimitry Andric   }
1379*0b57cec5SDimitry Andric }
1380*0b57cec5SDimitry Andric 
1381*0b57cec5SDimitry Andric /// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
1382*0b57cec5SDimitry Andric /// the range R.
1383*0b57cec5SDimitry Andric template<typename Container, typename Range = std::initializer_list<
1384*0b57cec5SDimitry Andric                                  typename Container::value_type>>
1385*0b57cec5SDimitry Andric void replace(Container &Cont, typename Container::iterator ContIt,
1386*0b57cec5SDimitry Andric              typename Container::iterator ContEnd, Range R) {
1387*0b57cec5SDimitry Andric   replace(Cont, ContIt, ContEnd, R.begin(), R.end());
1388*0b57cec5SDimitry Andric }
1389*0b57cec5SDimitry Andric 
1390*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1391*0b57cec5SDimitry Andric //     Extra additions to <memory>
1392*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1393*0b57cec5SDimitry Andric 
1394*0b57cec5SDimitry Andric // Implement make_unique according to N3656.
1395*0b57cec5SDimitry Andric 
1396*0b57cec5SDimitry Andric /// Constructs a `new T()` with the given args and returns a
1397*0b57cec5SDimitry Andric ///        `unique_ptr<T>` which owns the object.
1398*0b57cec5SDimitry Andric ///
1399*0b57cec5SDimitry Andric /// Example:
1400*0b57cec5SDimitry Andric ///
1401*0b57cec5SDimitry Andric ///     auto p = make_unique<int>();
1402*0b57cec5SDimitry Andric ///     auto p = make_unique<std::tuple<int, int>>(0, 1);
1403*0b57cec5SDimitry Andric template <class T, class... Args>
1404*0b57cec5SDimitry Andric typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
1405*0b57cec5SDimitry Andric make_unique(Args &&... args) {
1406*0b57cec5SDimitry Andric   return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
1407*0b57cec5SDimitry Andric }
1408*0b57cec5SDimitry Andric 
1409*0b57cec5SDimitry Andric /// Constructs a `new T[n]` with the given args and returns a
1410*0b57cec5SDimitry Andric ///        `unique_ptr<T[]>` which owns the object.
1411*0b57cec5SDimitry Andric ///
1412*0b57cec5SDimitry Andric /// \param n size of the new array.
1413*0b57cec5SDimitry Andric ///
1414*0b57cec5SDimitry Andric /// Example:
1415*0b57cec5SDimitry Andric ///
1416*0b57cec5SDimitry Andric ///     auto p = make_unique<int[]>(2); // value-initializes the array with 0's.
1417*0b57cec5SDimitry Andric template <class T>
1418*0b57cec5SDimitry Andric typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
1419*0b57cec5SDimitry Andric                         std::unique_ptr<T>>::type
1420*0b57cec5SDimitry Andric make_unique(size_t n) {
1421*0b57cec5SDimitry Andric   return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
1422*0b57cec5SDimitry Andric }
1423*0b57cec5SDimitry Andric 
1424*0b57cec5SDimitry Andric /// This function isn't used and is only here to provide better compile errors.
1425*0b57cec5SDimitry Andric template <class T, class... Args>
1426*0b57cec5SDimitry Andric typename std::enable_if<std::extent<T>::value != 0>::type
1427*0b57cec5SDimitry Andric make_unique(Args &&...) = delete;
1428*0b57cec5SDimitry Andric 
1429*0b57cec5SDimitry Andric struct FreeDeleter {
1430*0b57cec5SDimitry Andric   void operator()(void* v) {
1431*0b57cec5SDimitry Andric     ::free(v);
1432*0b57cec5SDimitry Andric   }
1433*0b57cec5SDimitry Andric };
1434*0b57cec5SDimitry Andric 
1435*0b57cec5SDimitry Andric template<typename First, typename Second>
1436*0b57cec5SDimitry Andric struct pair_hash {
1437*0b57cec5SDimitry Andric   size_t operator()(const std::pair<First, Second> &P) const {
1438*0b57cec5SDimitry Andric     return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
1439*0b57cec5SDimitry Andric   }
1440*0b57cec5SDimitry Andric };
1441*0b57cec5SDimitry Andric 
1442*0b57cec5SDimitry Andric /// A functor like C++14's std::less<void> in its absence.
1443*0b57cec5SDimitry Andric struct less {
1444*0b57cec5SDimitry Andric   template <typename A, typename B> bool operator()(A &&a, B &&b) const {
1445*0b57cec5SDimitry Andric     return std::forward<A>(a) < std::forward<B>(b);
1446*0b57cec5SDimitry Andric   }
1447*0b57cec5SDimitry Andric };
1448*0b57cec5SDimitry Andric 
1449*0b57cec5SDimitry Andric /// A functor like C++14's std::equal<void> in its absence.
1450*0b57cec5SDimitry Andric struct equal {
1451*0b57cec5SDimitry Andric   template <typename A, typename B> bool operator()(A &&a, B &&b) const {
1452*0b57cec5SDimitry Andric     return std::forward<A>(a) == std::forward<B>(b);
1453*0b57cec5SDimitry Andric   }
1454*0b57cec5SDimitry Andric };
1455*0b57cec5SDimitry Andric 
1456*0b57cec5SDimitry Andric /// Binary functor that adapts to any other binary functor after dereferencing
1457*0b57cec5SDimitry Andric /// operands.
1458*0b57cec5SDimitry Andric template <typename T> struct deref {
1459*0b57cec5SDimitry Andric   T func;
1460*0b57cec5SDimitry Andric 
1461*0b57cec5SDimitry Andric   // Could be further improved to cope with non-derivable functors and
1462*0b57cec5SDimitry Andric   // non-binary functors (should be a variadic template member function
1463*0b57cec5SDimitry Andric   // operator()).
1464*0b57cec5SDimitry Andric   template <typename A, typename B>
1465*0b57cec5SDimitry Andric   auto operator()(A &lhs, B &rhs) const -> decltype(func(*lhs, *rhs)) {
1466*0b57cec5SDimitry Andric     assert(lhs);
1467*0b57cec5SDimitry Andric     assert(rhs);
1468*0b57cec5SDimitry Andric     return func(*lhs, *rhs);
1469*0b57cec5SDimitry Andric   }
1470*0b57cec5SDimitry Andric };
1471*0b57cec5SDimitry Andric 
1472*0b57cec5SDimitry Andric namespace detail {
1473*0b57cec5SDimitry Andric 
1474*0b57cec5SDimitry Andric template <typename R> class enumerator_iter;
1475*0b57cec5SDimitry Andric 
1476*0b57cec5SDimitry Andric template <typename R> struct result_pair {
1477*0b57cec5SDimitry Andric   using value_reference =
1478*0b57cec5SDimitry Andric       typename std::iterator_traits<IterOfRange<R>>::reference;
1479*0b57cec5SDimitry Andric 
1480*0b57cec5SDimitry Andric   friend class enumerator_iter<R>;
1481*0b57cec5SDimitry Andric 
1482*0b57cec5SDimitry Andric   result_pair() = default;
1483*0b57cec5SDimitry Andric   result_pair(std::size_t Index, IterOfRange<R> Iter)
1484*0b57cec5SDimitry Andric       : Index(Index), Iter(Iter) {}
1485*0b57cec5SDimitry Andric 
1486*0b57cec5SDimitry Andric   result_pair<R> &operator=(const result_pair<R> &Other) {
1487*0b57cec5SDimitry Andric     Index = Other.Index;
1488*0b57cec5SDimitry Andric     Iter = Other.Iter;
1489*0b57cec5SDimitry Andric     return *this;
1490*0b57cec5SDimitry Andric   }
1491*0b57cec5SDimitry Andric 
1492*0b57cec5SDimitry Andric   std::size_t index() const { return Index; }
1493*0b57cec5SDimitry Andric   const value_reference value() const { return *Iter; }
1494*0b57cec5SDimitry Andric   value_reference value() { return *Iter; }
1495*0b57cec5SDimitry Andric 
1496*0b57cec5SDimitry Andric private:
1497*0b57cec5SDimitry Andric   std::size_t Index = std::numeric_limits<std::size_t>::max();
1498*0b57cec5SDimitry Andric   IterOfRange<R> Iter;
1499*0b57cec5SDimitry Andric };
1500*0b57cec5SDimitry Andric 
1501*0b57cec5SDimitry Andric template <typename R>
1502*0b57cec5SDimitry Andric class enumerator_iter
1503*0b57cec5SDimitry Andric     : public iterator_facade_base<
1504*0b57cec5SDimitry Andric           enumerator_iter<R>, std::forward_iterator_tag, result_pair<R>,
1505*0b57cec5SDimitry Andric           typename std::iterator_traits<IterOfRange<R>>::difference_type,
1506*0b57cec5SDimitry Andric           typename std::iterator_traits<IterOfRange<R>>::pointer,
1507*0b57cec5SDimitry Andric           typename std::iterator_traits<IterOfRange<R>>::reference> {
1508*0b57cec5SDimitry Andric   using result_type = result_pair<R>;
1509*0b57cec5SDimitry Andric 
1510*0b57cec5SDimitry Andric public:
1511*0b57cec5SDimitry Andric   explicit enumerator_iter(IterOfRange<R> EndIter)
1512*0b57cec5SDimitry Andric       : Result(std::numeric_limits<size_t>::max(), EndIter) {}
1513*0b57cec5SDimitry Andric 
1514*0b57cec5SDimitry Andric   enumerator_iter(std::size_t Index, IterOfRange<R> Iter)
1515*0b57cec5SDimitry Andric       : Result(Index, Iter) {}
1516*0b57cec5SDimitry Andric 
1517*0b57cec5SDimitry Andric   result_type &operator*() { return Result; }
1518*0b57cec5SDimitry Andric   const result_type &operator*() const { return Result; }
1519*0b57cec5SDimitry Andric 
1520*0b57cec5SDimitry Andric   enumerator_iter<R> &operator++() {
1521*0b57cec5SDimitry Andric     assert(Result.Index != std::numeric_limits<size_t>::max());
1522*0b57cec5SDimitry Andric     ++Result.Iter;
1523*0b57cec5SDimitry Andric     ++Result.Index;
1524*0b57cec5SDimitry Andric     return *this;
1525*0b57cec5SDimitry Andric   }
1526*0b57cec5SDimitry Andric 
1527*0b57cec5SDimitry Andric   bool operator==(const enumerator_iter<R> &RHS) const {
1528*0b57cec5SDimitry Andric     // Don't compare indices here, only iterators.  It's possible for an end
1529*0b57cec5SDimitry Andric     // iterator to have different indices depending on whether it was created
1530*0b57cec5SDimitry Andric     // by calling std::end() versus incrementing a valid iterator.
1531*0b57cec5SDimitry Andric     return Result.Iter == RHS.Result.Iter;
1532*0b57cec5SDimitry Andric   }
1533*0b57cec5SDimitry Andric 
1534*0b57cec5SDimitry Andric   enumerator_iter<R> &operator=(const enumerator_iter<R> &Other) {
1535*0b57cec5SDimitry Andric     Result = Other.Result;
1536*0b57cec5SDimitry Andric     return *this;
1537*0b57cec5SDimitry Andric   }
1538*0b57cec5SDimitry Andric 
1539*0b57cec5SDimitry Andric private:
1540*0b57cec5SDimitry Andric   result_type Result;
1541*0b57cec5SDimitry Andric };
1542*0b57cec5SDimitry Andric 
1543*0b57cec5SDimitry Andric template <typename R> class enumerator {
1544*0b57cec5SDimitry Andric public:
1545*0b57cec5SDimitry Andric   explicit enumerator(R &&Range) : TheRange(std::forward<R>(Range)) {}
1546*0b57cec5SDimitry Andric 
1547*0b57cec5SDimitry Andric   enumerator_iter<R> begin() {
1548*0b57cec5SDimitry Andric     return enumerator_iter<R>(0, std::begin(TheRange));
1549*0b57cec5SDimitry Andric   }
1550*0b57cec5SDimitry Andric 
1551*0b57cec5SDimitry Andric   enumerator_iter<R> end() {
1552*0b57cec5SDimitry Andric     return enumerator_iter<R>(std::end(TheRange));
1553*0b57cec5SDimitry Andric   }
1554*0b57cec5SDimitry Andric 
1555*0b57cec5SDimitry Andric private:
1556*0b57cec5SDimitry Andric   R TheRange;
1557*0b57cec5SDimitry Andric };
1558*0b57cec5SDimitry Andric 
1559*0b57cec5SDimitry Andric } // end namespace detail
1560*0b57cec5SDimitry Andric 
1561*0b57cec5SDimitry Andric /// Given an input range, returns a new range whose values are are pair (A,B)
1562*0b57cec5SDimitry Andric /// such that A is the 0-based index of the item in the sequence, and B is
1563*0b57cec5SDimitry Andric /// the value from the original sequence.  Example:
1564*0b57cec5SDimitry Andric ///
1565*0b57cec5SDimitry Andric /// std::vector<char> Items = {'A', 'B', 'C', 'D'};
1566*0b57cec5SDimitry Andric /// for (auto X : enumerate(Items)) {
1567*0b57cec5SDimitry Andric ///   printf("Item %d - %c\n", X.index(), X.value());
1568*0b57cec5SDimitry Andric /// }
1569*0b57cec5SDimitry Andric ///
1570*0b57cec5SDimitry Andric /// Output:
1571*0b57cec5SDimitry Andric ///   Item 0 - A
1572*0b57cec5SDimitry Andric ///   Item 1 - B
1573*0b57cec5SDimitry Andric ///   Item 2 - C
1574*0b57cec5SDimitry Andric ///   Item 3 - D
1575*0b57cec5SDimitry Andric ///
1576*0b57cec5SDimitry Andric template <typename R> detail::enumerator<R> enumerate(R &&TheRange) {
1577*0b57cec5SDimitry Andric   return detail::enumerator<R>(std::forward<R>(TheRange));
1578*0b57cec5SDimitry Andric }
1579*0b57cec5SDimitry Andric 
1580*0b57cec5SDimitry Andric namespace detail {
1581*0b57cec5SDimitry Andric 
1582*0b57cec5SDimitry Andric template <typename F, typename Tuple, std::size_t... I>
1583*0b57cec5SDimitry Andric auto apply_tuple_impl(F &&f, Tuple &&t, index_sequence<I...>)
1584*0b57cec5SDimitry Andric     -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...)) {
1585*0b57cec5SDimitry Andric   return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
1586*0b57cec5SDimitry Andric }
1587*0b57cec5SDimitry Andric 
1588*0b57cec5SDimitry Andric } // end namespace detail
1589*0b57cec5SDimitry Andric 
1590*0b57cec5SDimitry Andric /// Given an input tuple (a1, a2, ..., an), pass the arguments of the
1591*0b57cec5SDimitry Andric /// tuple variadically to f as if by calling f(a1, a2, ..., an) and
1592*0b57cec5SDimitry Andric /// return the result.
1593*0b57cec5SDimitry Andric template <typename F, typename Tuple>
1594*0b57cec5SDimitry Andric auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl(
1595*0b57cec5SDimitry Andric     std::forward<F>(f), std::forward<Tuple>(t),
1596*0b57cec5SDimitry Andric     build_index_impl<
1597*0b57cec5SDimitry Andric         std::tuple_size<typename std::decay<Tuple>::type>::value>{})) {
1598*0b57cec5SDimitry Andric   using Indices = build_index_impl<
1599*0b57cec5SDimitry Andric       std::tuple_size<typename std::decay<Tuple>::type>::value>;
1600*0b57cec5SDimitry Andric 
1601*0b57cec5SDimitry Andric   return detail::apply_tuple_impl(std::forward<F>(f), std::forward<Tuple>(t),
1602*0b57cec5SDimitry Andric                                   Indices{});
1603*0b57cec5SDimitry Andric }
1604*0b57cec5SDimitry Andric 
1605*0b57cec5SDimitry Andric /// Return true if the sequence [Begin, End) has exactly N items. Runs in O(N)
1606*0b57cec5SDimitry Andric /// time. Not meant for use with random-access iterators.
1607*0b57cec5SDimitry Andric template <typename IterTy>
1608*0b57cec5SDimitry Andric bool hasNItems(
1609*0b57cec5SDimitry Andric     IterTy &&Begin, IterTy &&End, unsigned N,
1610*0b57cec5SDimitry Andric     typename std::enable_if<
1611*0b57cec5SDimitry Andric         !std::is_same<
1612*0b57cec5SDimitry Andric             typename std::iterator_traits<typename std::remove_reference<
1613*0b57cec5SDimitry Andric                 decltype(Begin)>::type>::iterator_category,
1614*0b57cec5SDimitry Andric             std::random_access_iterator_tag>::value,
1615*0b57cec5SDimitry Andric         void>::type * = nullptr) {
1616*0b57cec5SDimitry Andric   for (; N; --N, ++Begin)
1617*0b57cec5SDimitry Andric     if (Begin == End)
1618*0b57cec5SDimitry Andric       return false; // Too few.
1619*0b57cec5SDimitry Andric   return Begin == End;
1620*0b57cec5SDimitry Andric }
1621*0b57cec5SDimitry Andric 
1622*0b57cec5SDimitry Andric /// Return true if the sequence [Begin, End) has N or more items. Runs in O(N)
1623*0b57cec5SDimitry Andric /// time. Not meant for use with random-access iterators.
1624*0b57cec5SDimitry Andric template <typename IterTy>
1625*0b57cec5SDimitry Andric bool hasNItemsOrMore(
1626*0b57cec5SDimitry Andric     IterTy &&Begin, IterTy &&End, unsigned N,
1627*0b57cec5SDimitry Andric     typename std::enable_if<
1628*0b57cec5SDimitry Andric         !std::is_same<
1629*0b57cec5SDimitry Andric             typename std::iterator_traits<typename std::remove_reference<
1630*0b57cec5SDimitry Andric                 decltype(Begin)>::type>::iterator_category,
1631*0b57cec5SDimitry Andric             std::random_access_iterator_tag>::value,
1632*0b57cec5SDimitry Andric         void>::type * = nullptr) {
1633*0b57cec5SDimitry Andric   for (; N; --N, ++Begin)
1634*0b57cec5SDimitry Andric     if (Begin == End)
1635*0b57cec5SDimitry Andric       return false; // Too few.
1636*0b57cec5SDimitry Andric   return true;
1637*0b57cec5SDimitry Andric }
1638*0b57cec5SDimitry Andric 
1639*0b57cec5SDimitry Andric /// Returns a raw pointer that represents the same address as the argument.
1640*0b57cec5SDimitry Andric ///
1641*0b57cec5SDimitry Andric /// The late bound return should be removed once we move to C++14 to better
1642*0b57cec5SDimitry Andric /// align with the C++20 declaration. Also, this implementation can be removed
1643*0b57cec5SDimitry Andric /// once we move to C++20 where it's defined as std::to_addres()
1644*0b57cec5SDimitry Andric ///
1645*0b57cec5SDimitry Andric /// The std::pointer_traits<>::to_address(p) variations of these overloads has
1646*0b57cec5SDimitry Andric /// not been implemented.
1647*0b57cec5SDimitry Andric template <class Ptr> auto to_address(const Ptr &P) -> decltype(P.operator->()) {
1648*0b57cec5SDimitry Andric   return P.operator->();
1649*0b57cec5SDimitry Andric }
1650*0b57cec5SDimitry Andric template <class T> constexpr T *to_address(T *P) { return P; }
1651*0b57cec5SDimitry Andric 
1652*0b57cec5SDimitry Andric } // end namespace llvm
1653*0b57cec5SDimitry Andric 
1654*0b57cec5SDimitry Andric #endif // LLVM_ADT_STLEXTRAS_H
1655