Home | History | Annotate | Download | only in ADT
      1 //===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains some templates that are useful if you are working with the
     11 // STL at all.
     12 //
     13 // No library is required when using these functions.
     14 //
     15 //===----------------------------------------------------------------------===//
     16 
     17 #ifndef LLVM_ADT_STLEXTRAS_H
     18 #define LLVM_ADT_STLEXTRAS_H
     19 
     20 #include "llvm/Support/Compiler.h"
     21 #include <algorithm> // for std::all_of
     22 #include <cassert>
     23 #include <cstddef> // for std::size_t
     24 #include <cstdlib> // for qsort
     25 #include <functional>
     26 #include <iterator>
     27 #include <memory>
     28 #include <utility> // for std::pair
     29 
     30 namespace llvm {
     31 
     32 //===----------------------------------------------------------------------===//
     33 //     Extra additions to <functional>
     34 //===----------------------------------------------------------------------===//
     35 
     36 template<class Ty>
     37 struct identity : public std::unary_function<Ty, Ty> {
     38   Ty &operator()(Ty &self) const {
     39     return self;
     40   }
     41   const Ty &operator()(const Ty &self) const {
     42     return self;
     43   }
     44 };
     45 
     46 template<class Ty>
     47 struct less_ptr : public std::binary_function<Ty, Ty, bool> {
     48   bool operator()(const Ty* left, const Ty* right) const {
     49     return *left < *right;
     50   }
     51 };
     52 
     53 template<class Ty>
     54 struct greater_ptr : public std::binary_function<Ty, Ty, bool> {
     55   bool operator()(const Ty* left, const Ty* right) const {
     56     return *right < *left;
     57   }
     58 };
     59 
     60 /// An efficient, type-erasing, non-owning reference to a callable. This is
     61 /// intended for use as the type of a function parameter that is not used
     62 /// after the function in question returns.
     63 ///
     64 /// This class does not own the callable, so it is not in general safe to store
     65 /// a function_ref.
     66 template<typename Fn> class function_ref;
     67 
     68 template<typename Ret, typename ...Params>
     69 class function_ref<Ret(Params...)> {
     70   Ret (*callback)(intptr_t callable, Params ...params);
     71   intptr_t callable;
     72 
     73   template<typename Callable>
     74   static Ret callback_fn(intptr_t callable, Params ...params) {
     75     return (*reinterpret_cast<Callable*>(callable))(
     76         std::forward<Params>(params)...);
     77   }
     78 
     79 public:
     80   template <typename Callable>
     81   function_ref(Callable &&callable,
     82                typename std::enable_if<
     83                    !std::is_same<typename std::remove_reference<Callable>::type,
     84                                  function_ref>::value>::type * = nullptr)
     85       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
     86         callable(reinterpret_cast<intptr_t>(&callable)) {}
     87   Ret operator()(Params ...params) const {
     88     return callback(callable, std::forward<Params>(params)...);
     89   }
     90 };
     91 
     92 // deleter - Very very very simple method that is used to invoke operator
     93 // delete on something.  It is used like this:
     94 //
     95 //   for_each(V.begin(), B.end(), deleter<Interval>);
     96 //
     97 template <class T>
     98 inline void deleter(T *Ptr) {
     99   delete Ptr;
    100 }
    101 
    102 
    103 
    104 //===----------------------------------------------------------------------===//
    105 //     Extra additions to <iterator>
    106 //===----------------------------------------------------------------------===//
    107 
    108 // mapped_iterator - This is a simple iterator adapter that causes a function to
    109 // be dereferenced whenever operator* is invoked on the iterator.
    110 //
    111 template <class RootIt, class UnaryFunc>
    112 class mapped_iterator {
    113   RootIt current;
    114   UnaryFunc Fn;
    115 public:
    116   typedef typename std::iterator_traits<RootIt>::iterator_category
    117           iterator_category;
    118   typedef typename std::iterator_traits<RootIt>::difference_type
    119           difference_type;
    120   typedef typename UnaryFunc::result_type value_type;
    121 
    122   typedef void pointer;
    123   //typedef typename UnaryFunc::result_type *pointer;
    124   typedef void reference;        // Can't modify value returned by fn
    125 
    126   typedef RootIt iterator_type;
    127 
    128   inline const RootIt &getCurrent() const { return current; }
    129   inline const UnaryFunc &getFunc() const { return Fn; }
    130 
    131   inline explicit mapped_iterator(const RootIt &I, UnaryFunc F)
    132     : current(I), Fn(F) {}
    133 
    134   inline value_type operator*() const {   // All this work to do this
    135     return Fn(*current);         // little change
    136   }
    137 
    138   mapped_iterator &operator++() {
    139     ++current;
    140     return *this;
    141   }
    142   mapped_iterator &operator--() {
    143     --current;
    144     return *this;
    145   }
    146   mapped_iterator operator++(int) {
    147     mapped_iterator __tmp = *this;
    148     ++current;
    149     return __tmp;
    150   }
    151   mapped_iterator operator--(int) {
    152     mapped_iterator __tmp = *this;
    153     --current;
    154     return __tmp;
    155   }
    156   mapped_iterator operator+(difference_type n) const {
    157     return mapped_iterator(current + n, Fn);
    158   }
    159   mapped_iterator &operator+=(difference_type n) {
    160     current += n;
    161     return *this;
    162   }
    163   mapped_iterator operator-(difference_type n) const {
    164     return mapped_iterator(current - n, Fn);
    165   }
    166   mapped_iterator &operator-=(difference_type n) {
    167     current -= n;
    168     return *this;
    169   }
    170   reference operator[](difference_type n) const { return *(*this + n); }
    171 
    172   bool operator!=(const mapped_iterator &X) const { return !operator==(X); }
    173   bool operator==(const mapped_iterator &X) const {
    174     return current == X.current;
    175   }
    176   bool operator<(const mapped_iterator &X) const { return current < X.current; }
    177 
    178   difference_type operator-(const mapped_iterator &X) const {
    179     return current - X.current;
    180   }
    181 };
    182 
    183 template <class Iterator, class Func>
    184 inline mapped_iterator<Iterator, Func>
    185 operator+(typename mapped_iterator<Iterator, Func>::difference_type N,
    186           const mapped_iterator<Iterator, Func> &X) {
    187   return mapped_iterator<Iterator, Func>(X.getCurrent() - N, X.getFunc());
    188 }
    189 
    190 
    191 // map_iterator - Provide a convenient way to create mapped_iterators, just like
    192 // make_pair is useful for creating pairs...
    193 //
    194 template <class ItTy, class FuncTy>
    195 inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) {
    196   return mapped_iterator<ItTy, FuncTy>(I, F);
    197 }
    198 
    199 /// \brief Metafunction to determine if type T has a member called rbegin().
    200 template <typename T> struct has_rbegin {
    201   template <typename U> static char(&f(const U &, decltype(&U::rbegin)))[1];
    202   static char(&f(...))[2];
    203   const static bool value = sizeof(f(std::declval<T>(), nullptr)) == 1;
    204 };
    205 
    206 // Returns an iterator_range over the given container which iterates in reverse.
    207 // Note that the container must have rbegin()/rend() methods for this to work.
    208 template <typename ContainerTy>
    209 auto reverse(ContainerTy &&C,
    210              typename std::enable_if<has_rbegin<ContainerTy>::value>::type * =
    211                  nullptr) -> decltype(make_range(C.rbegin(), C.rend())) {
    212   return make_range(C.rbegin(), C.rend());
    213 }
    214 
    215 // Returns a std::reverse_iterator wrapped around the given iterator.
    216 template <typename IteratorTy>
    217 std::reverse_iterator<IteratorTy> make_reverse_iterator(IteratorTy It) {
    218   return std::reverse_iterator<IteratorTy>(It);
    219 }
    220 
    221 // Returns an iterator_range over the given container which iterates in reverse.
    222 // Note that the container must have begin()/end() methods which return
    223 // bidirectional iterators for this to work.
    224 template <typename ContainerTy>
    225 auto reverse(
    226     ContainerTy &&C,
    227     typename std::enable_if<!has_rbegin<ContainerTy>::value>::type * = nullptr)
    228     -> decltype(make_range(llvm::make_reverse_iterator(std::end(C)),
    229                            llvm::make_reverse_iterator(std::begin(C)))) {
    230   return make_range(llvm::make_reverse_iterator(std::end(C)),
    231                     llvm::make_reverse_iterator(std::begin(C)));
    232 }
    233 
    234 //===----------------------------------------------------------------------===//
    235 //     Extra additions to <utility>
    236 //===----------------------------------------------------------------------===//
    237 
    238 /// \brief Function object to check whether the first component of a std::pair
    239 /// compares less than the first component of another std::pair.
    240 struct less_first {
    241   template <typename T> bool operator()(const T &lhs, const T &rhs) const {
    242     return lhs.first < rhs.first;
    243   }
    244 };
    245 
    246 /// \brief Function object to check whether the second component of a std::pair
    247 /// compares less than the second component of another std::pair.
    248 struct less_second {
    249   template <typename T> bool operator()(const T &lhs, const T &rhs) const {
    250     return lhs.second < rhs.second;
    251   }
    252 };
    253 
    254 // A subset of N3658. More stuff can be added as-needed.
    255 
    256 /// \brief Represents a compile-time sequence of integers.
    257 template <class T, T... I> struct integer_sequence {
    258   typedef T value_type;
    259 
    260   static LLVM_CONSTEXPR size_t size() { return sizeof...(I); }
    261 };
    262 
    263 /// \brief Alias for the common case of a sequence of size_ts.
    264 template <size_t... I>
    265 struct index_sequence : integer_sequence<std::size_t, I...> {};
    266 
    267 template <std::size_t N, std::size_t... I>
    268 struct build_index_impl : build_index_impl<N - 1, N - 1, I...> {};
    269 template <std::size_t... I>
    270 struct build_index_impl<0, I...> : index_sequence<I...> {};
    271 
    272 /// \brief Creates a compile-time integer sequence for a parameter pack.
    273 template <class... Ts>
    274 struct index_sequence_for : build_index_impl<sizeof...(Ts)> {};
    275 
    276 //===----------------------------------------------------------------------===//
    277 //     Extra additions for arrays
    278 //===----------------------------------------------------------------------===//
    279 
    280 /// Find the length of an array.
    281 template <class T, std::size_t N>
    282 LLVM_CONSTEXPR inline size_t array_lengthof(T (&)[N]) {
    283   return N;
    284 }
    285 
    286 /// Adapt std::less<T> for array_pod_sort.
    287 template<typename T>
    288 inline int array_pod_sort_comparator(const void *P1, const void *P2) {
    289   if (std::less<T>()(*reinterpret_cast<const T*>(P1),
    290                      *reinterpret_cast<const T*>(P2)))
    291     return -1;
    292   if (std::less<T>()(*reinterpret_cast<const T*>(P2),
    293                      *reinterpret_cast<const T*>(P1)))
    294     return 1;
    295   return 0;
    296 }
    297 
    298 /// get_array_pod_sort_comparator - This is an internal helper function used to
    299 /// get type deduction of T right.
    300 template<typename T>
    301 inline int (*get_array_pod_sort_comparator(const T &))
    302              (const void*, const void*) {
    303   return array_pod_sort_comparator<T>;
    304 }
    305 
    306 
    307 /// array_pod_sort - This sorts an array with the specified start and end
    308 /// extent.  This is just like std::sort, except that it calls qsort instead of
    309 /// using an inlined template.  qsort is slightly slower than std::sort, but
    310 /// most sorts are not performance critical in LLVM and std::sort has to be
    311 /// template instantiated for each type, leading to significant measured code
    312 /// bloat.  This function should generally be used instead of std::sort where
    313 /// possible.
    314 ///
    315 /// This function assumes that you have simple POD-like types that can be
    316 /// compared with std::less and can be moved with memcpy.  If this isn't true,
    317 /// you should use std::sort.
    318 ///
    319 /// NOTE: If qsort_r were portable, we could allow a custom comparator and
    320 /// default to std::less.
    321 template<class IteratorTy>
    322 inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
    323   // Don't inefficiently call qsort with one element or trigger undefined
    324   // behavior with an empty sequence.
    325   auto NElts = End - Start;
    326   if (NElts <= 1) return;
    327   qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start));
    328 }
    329 
    330 template <class IteratorTy>
    331 inline void array_pod_sort(
    332     IteratorTy Start, IteratorTy End,
    333     int (*Compare)(
    334         const typename std::iterator_traits<IteratorTy>::value_type *,
    335         const typename std::iterator_traits<IteratorTy>::value_type *)) {
    336   // Don't inefficiently call qsort with one element or trigger undefined
    337   // behavior with an empty sequence.
    338   auto NElts = End - Start;
    339   if (NElts <= 1) return;
    340   qsort(&*Start, NElts, sizeof(*Start),
    341         reinterpret_cast<int (*)(const void *, const void *)>(Compare));
    342 }
    343 
    344 //===----------------------------------------------------------------------===//
    345 //     Extra additions to <algorithm>
    346 //===----------------------------------------------------------------------===//
    347 
    348 /// For a container of pointers, deletes the pointers and then clears the
    349 /// container.
    350 template<typename Container>
    351 void DeleteContainerPointers(Container &C) {
    352   for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
    353     delete *I;
    354   C.clear();
    355 }
    356 
    357 /// In a container of pairs (usually a map) whose second element is a pointer,
    358 /// deletes the second elements and then clears the container.
    359 template<typename Container>
    360 void DeleteContainerSeconds(Container &C) {
    361   for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
    362     delete I->second;
    363   C.clear();
    364 }
    365 
    366 /// Provide wrappers to std::all_of which take ranges instead of having to pass
    367 /// begin/end explicitly.
    368 template<typename R, class UnaryPredicate>
    369 bool all_of(R &&Range, UnaryPredicate &&P) {
    370   return std::all_of(Range.begin(), Range.end(),
    371                      std::forward<UnaryPredicate>(P));
    372 }
    373 
    374 /// Provide wrappers to std::any_of which take ranges instead of having to pass
    375 /// begin/end explicitly.
    376 template <typename R, class UnaryPredicate>
    377 bool any_of(R &&Range, UnaryPredicate &&P) {
    378   return std::any_of(Range.begin(), Range.end(),
    379                      std::forward<UnaryPredicate>(P));
    380 }
    381 
    382 /// Provide wrappers to std::find which take ranges instead of having to pass
    383 /// begin/end explicitly.
    384 template<typename R, class T>
    385 auto find(R &&Range, const T &val) -> decltype(Range.begin()) {
    386   return std::find(Range.begin(), Range.end(), val);
    387 }
    388 
    389 //===----------------------------------------------------------------------===//
    390 //     Extra additions to <memory>
    391 //===----------------------------------------------------------------------===//
    392 
    393 // Implement make_unique according to N3656.
    394 
    395 /// \brief Constructs a `new T()` with the given args and returns a
    396 ///        `unique_ptr<T>` which owns the object.
    397 ///
    398 /// Example:
    399 ///
    400 ///     auto p = make_unique<int>();
    401 ///     auto p = make_unique<std::tuple<int, int>>(0, 1);
    402 template <class T, class... Args>
    403 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    404 make_unique(Args &&... args) {
    405   return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
    406 }
    407 
    408 /// \brief Constructs a `new T[n]` with the given args and returns a
    409 ///        `unique_ptr<T[]>` which owns the object.
    410 ///
    411 /// \param n size of the new array.
    412 ///
    413 /// Example:
    414 ///
    415 ///     auto p = make_unique<int[]>(2); // value-initializes the array with 0's.
    416 template <class T>
    417 typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
    418                         std::unique_ptr<T>>::type
    419 make_unique(size_t n) {
    420   return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
    421 }
    422 
    423 /// This function isn't used and is only here to provide better compile errors.
    424 template <class T, class... Args>
    425 typename std::enable_if<std::extent<T>::value != 0>::type
    426 make_unique(Args &&...) = delete;
    427 
    428 struct FreeDeleter {
    429   void operator()(void* v) {
    430     ::free(v);
    431   }
    432 };
    433 
    434 template<typename First, typename Second>
    435 struct pair_hash {
    436   size_t operator()(const std::pair<First, Second> &P) const {
    437     return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
    438   }
    439 };
    440 
    441 /// A functor like C++14's std::less<void> in its absence.
    442 struct less {
    443   template <typename A, typename B> bool operator()(A &&a, B &&b) const {
    444     return std::forward<A>(a) < std::forward<B>(b);
    445   }
    446 };
    447 
    448 /// A functor like C++14's std::equal<void> in its absence.
    449 struct equal {
    450   template <typename A, typename B> bool operator()(A &&a, B &&b) const {
    451     return std::forward<A>(a) == std::forward<B>(b);
    452   }
    453 };
    454 
    455 /// Binary functor that adapts to any other binary functor after dereferencing
    456 /// operands.
    457 template <typename T> struct deref {
    458   T func;
    459   // Could be further improved to cope with non-derivable functors and
    460   // non-binary functors (should be a variadic template member function
    461   // operator()).
    462   template <typename A, typename B>
    463   auto operator()(A &lhs, B &rhs) const -> decltype(func(*lhs, *rhs)) {
    464     assert(lhs);
    465     assert(rhs);
    466     return func(*lhs, *rhs);
    467   }
    468 };
    469 
    470 } // End llvm namespace
    471 
    472 #endif
    473