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