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 <cstddef> // for std::size_t
     22 #include <cstdlib> // for qsort
     23 #include <functional>
     24 #include <iterator>
     25 #include <memory>
     26 #include <utility> // for std::pair
     27 
     28 namespace llvm {
     29 
     30 //===----------------------------------------------------------------------===//
     31 //     Extra additions to <functional>
     32 //===----------------------------------------------------------------------===//
     33 
     34 template<class Ty>
     35 struct identity : public std::unary_function<Ty, Ty> {
     36   Ty &operator()(Ty &self) const {
     37     return self;
     38   }
     39   const Ty &operator()(const Ty &self) const {
     40     return self;
     41   }
     42 };
     43 
     44 template<class Ty>
     45 struct less_ptr : public std::binary_function<Ty, Ty, bool> {
     46   bool operator()(const Ty* left, const Ty* right) const {
     47     return *left < *right;
     48   }
     49 };
     50 
     51 template<class Ty>
     52 struct greater_ptr : public std::binary_function<Ty, Ty, bool> {
     53   bool operator()(const Ty* left, const Ty* right) const {
     54     return *right < *left;
     55   }
     56 };
     57 
     58 /// An efficient, type-erasing, non-owning reference to a callable. This is
     59 /// intended for use as the type of a function parameter that is not used
     60 /// after the function in question returns.
     61 ///
     62 /// This class does not own the callable, so it is not in general safe to store
     63 /// a function_ref.
     64 template<typename Fn> class function_ref;
     65 
     66 #if LLVM_HAS_VARIADIC_TEMPLATES
     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       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
     83         callable(reinterpret_cast<intptr_t>(&callable)) {}
     84   Ret operator()(Params ...params) const {
     85     return callback(callable, std::forward<Params>(params)...);
     86   }
     87 };
     88 
     89 #else
     90 
     91 template<typename Ret>
     92 class function_ref<Ret()> {
     93   Ret (*callback)(intptr_t callable);
     94   intptr_t callable;
     95 
     96   template<typename Callable>
     97   static Ret callback_fn(intptr_t callable) {
     98     return (*reinterpret_cast<Callable*>(callable))();
     99   }
    100 
    101 public:
    102   template<typename Callable>
    103   function_ref(Callable &&callable)
    104       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
    105         callable(reinterpret_cast<intptr_t>(&callable)) {}
    106   Ret operator()() const { return callback(callable); }
    107 };
    108 
    109 template<typename Ret, typename Param1>
    110 class function_ref<Ret(Param1)> {
    111   Ret (*callback)(intptr_t callable, Param1 param1);
    112   intptr_t callable;
    113 
    114   template<typename Callable>
    115   static Ret callback_fn(intptr_t callable, Param1 param1) {
    116     return (*reinterpret_cast<Callable*>(callable))(
    117         std::forward<Param1>(param1));
    118   }
    119 
    120 public:
    121   template<typename Callable>
    122   function_ref(Callable &&callable)
    123       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
    124         callable(reinterpret_cast<intptr_t>(&callable)) {}
    125   Ret operator()(Param1 param1) {
    126     return callback(callable, std::forward<Param1>(param1));
    127   }
    128 };
    129 
    130 template<typename Ret, typename Param1, typename Param2>
    131 class function_ref<Ret(Param1, Param2)> {
    132   Ret (*callback)(intptr_t callable, Param1 param1, Param2 param2);
    133   intptr_t callable;
    134 
    135   template<typename Callable>
    136   static Ret callback_fn(intptr_t callable, Param1 param1, Param2 param2) {
    137     return (*reinterpret_cast<Callable*>(callable))(
    138         std::forward<Param1>(param1),
    139         std::forward<Param2>(param2));
    140   }
    141 
    142 public:
    143   template<typename Callable>
    144   function_ref(Callable &&callable)
    145       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
    146         callable(reinterpret_cast<intptr_t>(&callable)) {}
    147   Ret operator()(Param1 param1, Param2 param2) {
    148     return callback(callable,
    149                     std::forward<Param1>(param1),
    150                     std::forward<Param2>(param2));
    151   }
    152 };
    153 
    154 template<typename Ret, typename Param1, typename Param2, typename Param3>
    155 class function_ref<Ret(Param1, Param2, Param3)> {
    156   Ret (*callback)(intptr_t callable, Param1 param1, Param2 param2, Param3 param3);
    157   intptr_t callable;
    158 
    159   template<typename Callable>
    160   static Ret callback_fn(intptr_t callable, Param1 param1, Param2 param2,
    161                          Param3 param3) {
    162     return (*reinterpret_cast<Callable*>(callable))(
    163         std::forward<Param1>(param1),
    164         std::forward<Param2>(param2),
    165         std::forward<Param3>(param3));
    166   }
    167 
    168 public:
    169   template<typename Callable>
    170   function_ref(Callable &&callable)
    171       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
    172         callable(reinterpret_cast<intptr_t>(&callable)) {}
    173   Ret operator()(Param1 param1, Param2 param2, Param3 param3) {
    174     return callback(callable,
    175                     std::forward<Param1>(param1),
    176                     std::forward<Param2>(param2),
    177                     std::forward<Param3>(param3));
    178   }
    179 };
    180 
    181 #endif
    182 
    183 // deleter - Very very very simple method that is used to invoke operator
    184 // delete on something.  It is used like this:
    185 //
    186 //   for_each(V.begin(), B.end(), deleter<Interval>);
    187 //
    188 template <class T>
    189 inline void deleter(T *Ptr) {
    190   delete Ptr;
    191 }
    192 
    193 
    194 
    195 //===----------------------------------------------------------------------===//
    196 //     Extra additions to <iterator>
    197 //===----------------------------------------------------------------------===//
    198 
    199 // mapped_iterator - This is a simple iterator adapter that causes a function to
    200 // be dereferenced whenever operator* is invoked on the iterator.
    201 //
    202 template <class RootIt, class UnaryFunc>
    203 class mapped_iterator {
    204   RootIt current;
    205   UnaryFunc Fn;
    206 public:
    207   typedef typename std::iterator_traits<RootIt>::iterator_category
    208           iterator_category;
    209   typedef typename std::iterator_traits<RootIt>::difference_type
    210           difference_type;
    211   typedef typename UnaryFunc::result_type value_type;
    212 
    213   typedef void pointer;
    214   //typedef typename UnaryFunc::result_type *pointer;
    215   typedef void reference;        // Can't modify value returned by fn
    216 
    217   typedef RootIt iterator_type;
    218   typedef mapped_iterator<RootIt, UnaryFunc> _Self;
    219 
    220   inline const RootIt &getCurrent() const { return current; }
    221   inline const UnaryFunc &getFunc() const { return Fn; }
    222 
    223   inline explicit mapped_iterator(const RootIt &I, UnaryFunc F)
    224     : current(I), Fn(F) {}
    225 
    226   inline value_type operator*() const {   // All this work to do this
    227     return Fn(*current);         // little change
    228   }
    229 
    230   _Self& operator++() { ++current; return *this; }
    231   _Self& operator--() { --current; return *this; }
    232   _Self  operator++(int) { _Self __tmp = *this; ++current; return __tmp; }
    233   _Self  operator--(int) { _Self __tmp = *this; --current; return __tmp; }
    234   _Self  operator+    (difference_type n) const {
    235     return _Self(current + n, Fn);
    236   }
    237   _Self& operator+=   (difference_type n) { current += n; return *this; }
    238   _Self  operator-    (difference_type n) const {
    239     return _Self(current - n, Fn);
    240   }
    241   _Self& operator-=   (difference_type n) { current -= n; return *this; }
    242   reference operator[](difference_type n) const { return *(*this + n); }
    243 
    244   inline bool operator!=(const _Self &X) const { return !operator==(X); }
    245   inline bool operator==(const _Self &X) const { return current == X.current; }
    246   inline bool operator< (const _Self &X) const { return current <  X.current; }
    247 
    248   inline difference_type operator-(const _Self &X) const {
    249     return current - X.current;
    250   }
    251 };
    252 
    253 template <class _Iterator, class Func>
    254 inline mapped_iterator<_Iterator, Func>
    255 operator+(typename mapped_iterator<_Iterator, Func>::difference_type N,
    256           const mapped_iterator<_Iterator, Func>& X) {
    257   return mapped_iterator<_Iterator, Func>(X.getCurrent() - N, X.getFunc());
    258 }
    259 
    260 
    261 // map_iterator - Provide a convenient way to create mapped_iterators, just like
    262 // make_pair is useful for creating pairs...
    263 //
    264 template <class ItTy, class FuncTy>
    265 inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) {
    266   return mapped_iterator<ItTy, FuncTy>(I, F);
    267 }
    268 
    269 //===----------------------------------------------------------------------===//
    270 //     Extra additions to <utility>
    271 //===----------------------------------------------------------------------===//
    272 
    273 /// \brief Function object to check whether the first component of a std::pair
    274 /// compares less than the first component of another std::pair.
    275 struct less_first {
    276   template <typename T> bool operator()(const T &lhs, const T &rhs) const {
    277     return lhs.first < rhs.first;
    278   }
    279 };
    280 
    281 /// \brief Function object to check whether the second component of a std::pair
    282 /// compares less than the second component of another std::pair.
    283 struct less_second {
    284   template <typename T> bool operator()(const T &lhs, const T &rhs) const {
    285     return lhs.second < rhs.second;
    286   }
    287 };
    288 
    289 //===----------------------------------------------------------------------===//
    290 //     Extra additions for arrays
    291 //===----------------------------------------------------------------------===//
    292 
    293 /// Find the length of an array.
    294 template <class T, std::size_t N>
    295 LLVM_CONSTEXPR inline size_t array_lengthof(T (&)[N]) {
    296   return N;
    297 }
    298 
    299 /// Adapt std::less<T> for array_pod_sort.
    300 template<typename T>
    301 inline int array_pod_sort_comparator(const void *P1, const void *P2) {
    302   if (std::less<T>()(*reinterpret_cast<const T*>(P1),
    303                      *reinterpret_cast<const T*>(P2)))
    304     return -1;
    305   if (std::less<T>()(*reinterpret_cast<const T*>(P2),
    306                      *reinterpret_cast<const T*>(P1)))
    307     return 1;
    308   return 0;
    309 }
    310 
    311 /// get_array_pod_sort_comparator - This is an internal helper function used to
    312 /// get type deduction of T right.
    313 template<typename T>
    314 inline int (*get_array_pod_sort_comparator(const T &))
    315              (const void*, const void*) {
    316   return array_pod_sort_comparator<T>;
    317 }
    318 
    319 
    320 /// array_pod_sort - This sorts an array with the specified start and end
    321 /// extent.  This is just like std::sort, except that it calls qsort instead of
    322 /// using an inlined template.  qsort is slightly slower than std::sort, but
    323 /// most sorts are not performance critical in LLVM and std::sort has to be
    324 /// template instantiated for each type, leading to significant measured code
    325 /// bloat.  This function should generally be used instead of std::sort where
    326 /// possible.
    327 ///
    328 /// This function assumes that you have simple POD-like types that can be
    329 /// compared with std::less and can be moved with memcpy.  If this isn't true,
    330 /// you should use std::sort.
    331 ///
    332 /// NOTE: If qsort_r were portable, we could allow a custom comparator and
    333 /// default to std::less.
    334 template<class IteratorTy>
    335 inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
    336   // Don't dereference start iterator of empty sequence.
    337   if (Start == End) return;
    338   qsort(&*Start, End-Start, sizeof(*Start),
    339         get_array_pod_sort_comparator(*Start));
    340 }
    341 
    342 template <class IteratorTy>
    343 inline void array_pod_sort(
    344     IteratorTy Start, IteratorTy End,
    345     int (*Compare)(
    346         const typename std::iterator_traits<IteratorTy>::value_type *,
    347         const typename std::iterator_traits<IteratorTy>::value_type *)) {
    348   // Don't dereference start iterator of empty sequence.
    349   if (Start == End) return;
    350   qsort(&*Start, End - Start, sizeof(*Start),
    351         reinterpret_cast<int (*)(const void *, const void *)>(Compare));
    352 }
    353 
    354 //===----------------------------------------------------------------------===//
    355 //     Extra additions to <algorithm>
    356 //===----------------------------------------------------------------------===//
    357 
    358 /// For a container of pointers, deletes the pointers and then clears the
    359 /// container.
    360 template<typename Container>
    361 void DeleteContainerPointers(Container &C) {
    362   for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
    363     delete *I;
    364   C.clear();
    365 }
    366 
    367 /// In a container of pairs (usually a map) whose second element is a pointer,
    368 /// deletes the second elements and then clears the container.
    369 template<typename Container>
    370 void DeleteContainerSeconds(Container &C) {
    371   for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
    372     delete I->second;
    373   C.clear();
    374 }
    375 
    376 //===----------------------------------------------------------------------===//
    377 //     Extra additions to <memory>
    378 //===----------------------------------------------------------------------===//
    379 
    380 #if LLVM_HAS_VARIADIC_TEMPLATES
    381 
    382 // Implement make_unique according to N3656.
    383 
    384 /// \brief Constructs a `new T()` with the given args and returns a
    385 ///        `unique_ptr<T>` which owns the object.
    386 ///
    387 /// Example:
    388 ///
    389 ///     auto p = make_unique<int>();
    390 ///     auto p = make_unique<std::tuple<int, int>>(0, 1);
    391 template <class T, class... Args>
    392 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    393 make_unique(Args &&... args) {
    394   return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
    395 }
    396 
    397 /// \brief Constructs a `new T[n]` with the given args and returns a
    398 ///        `unique_ptr<T[]>` which owns the object.
    399 ///
    400 /// \param n size of the new array.
    401 ///
    402 /// Example:
    403 ///
    404 ///     auto p = make_unique<int[]>(2); // value-initializes the array with 0's.
    405 template <class T>
    406 typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
    407                         std::unique_ptr<T>>::type
    408 make_unique(size_t n) {
    409   return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
    410 }
    411 
    412 /// This function isn't used and is only here to provide better compile errors.
    413 template <class T, class... Args>
    414 typename std::enable_if<std::extent<T>::value != 0>::type
    415 make_unique(Args &&...) LLVM_DELETED_FUNCTION;
    416 
    417 #else
    418 
    419 template <class T>
    420 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    421 make_unique() {
    422   return std::unique_ptr<T>(new T());
    423 }
    424 
    425 template <class T, class Arg1>
    426 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    427 make_unique(Arg1 &&arg1) {
    428   return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1)));
    429 }
    430 
    431 template <class T, class Arg1, class Arg2>
    432 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    433 make_unique(Arg1 &&arg1, Arg2 &&arg2) {
    434   return std::unique_ptr<T>(
    435       new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2)));
    436 }
    437 
    438 template <class T, class Arg1, class Arg2, class Arg3>
    439 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    440 make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3) {
    441   return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1),
    442                                   std::forward<Arg2>(arg2),
    443                                   std::forward<Arg3>(arg3)));
    444 }
    445 
    446 template <class T, class Arg1, class Arg2, class Arg3, class Arg4>
    447 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    448 make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4) {
    449   return std::unique_ptr<T>(
    450       new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
    451             std::forward<Arg3>(arg3), std::forward<Arg4>(arg4)));
    452 }
    453 
    454 template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
    455 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    456 make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5) {
    457   return std::unique_ptr<T>(
    458       new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
    459             std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
    460             std::forward<Arg5>(arg5)));
    461 }
    462 
    463 template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
    464           class Arg6>
    465 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    466 make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
    467             Arg6 &&arg6) {
    468   return std::unique_ptr<T>(
    469       new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
    470             std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
    471             std::forward<Arg5>(arg5), std::forward<Arg6>(arg6)));
    472 }
    473 
    474 template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
    475           class Arg6, class Arg7>
    476 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    477 make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
    478             Arg6 &&arg6, Arg7 &&arg7) {
    479   return std::unique_ptr<T>(
    480       new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
    481             std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
    482             std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
    483             std::forward<Arg7>(arg7)));
    484 }
    485 
    486 template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
    487           class Arg6, class Arg7, class Arg8>
    488 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    489 make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
    490             Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8) {
    491   return std::unique_ptr<T>(
    492       new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
    493             std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
    494             std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
    495             std::forward<Arg7>(arg7), std::forward<Arg8>(arg8)));
    496 }
    497 
    498 template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
    499           class Arg6, class Arg7, class Arg8, class Arg9>
    500 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    501 make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
    502             Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8, Arg9 &&arg9) {
    503   return std::unique_ptr<T>(
    504       new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
    505             std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
    506             std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
    507             std::forward<Arg7>(arg7), std::forward<Arg8>(arg8),
    508             std::forward<Arg9>(arg9)));
    509 }
    510 
    511 template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
    512           class Arg6, class Arg7, class Arg8, class Arg9, class Arg10>
    513 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
    514 make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
    515             Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8, Arg9 &&arg9, Arg10 &&arg10) {
    516   return std::unique_ptr<T>(
    517       new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
    518             std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
    519             std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
    520             std::forward<Arg7>(arg7), std::forward<Arg8>(arg8),
    521             std::forward<Arg9>(arg9), std::forward<Arg10>(arg10)));
    522 }
    523 
    524 template <class T>
    525 typename std::enable_if<std::is_array<T>::value &&std::extent<T>::value == 0,
    526                         std::unique_ptr<T>>::type
    527 make_unique(size_t n) {
    528   return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
    529 }
    530 
    531 #endif
    532 
    533 template<typename First, typename Second>
    534 struct pair_hash {
    535   size_t operator()(const std::pair<First, Second> &P) const {
    536     return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
    537   }
    538 };
    539 
    540 } // End llvm namespace
    541 
    542 #endif
    543