LCOV - code coverage report
Current view: top level - llvm/ADT - STLExtras.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 1 2 50.0 %
Date: 2016-01-31 12:01:00 Functions: 1 1 100.0 %

          Line data    Source code
       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             : //===----------------------------------------------------------------------===//
     200             : //     Extra additions to <utility>
     201             : //===----------------------------------------------------------------------===//
     202             : 
     203             : /// \brief Function object to check whether the first component of a std::pair
     204             : /// compares less than the first component of another std::pair.
     205             : struct less_first {
     206             :   template <typename T> bool operator()(const T &lhs, const T &rhs) const {
     207             :     return lhs.first < rhs.first;
     208             :   }
     209             : };
     210             : 
     211             : /// \brief Function object to check whether the second component of a std::pair
     212             : /// compares less than the second component of another std::pair.
     213             : struct less_second {
     214             :   template <typename T> bool operator()(const T &lhs, const T &rhs) const {
     215             :     return lhs.second < rhs.second;
     216             :   }
     217             : };
     218             : 
     219             : // A subset of N3658. More stuff can be added as-needed.
     220             : 
     221             : /// \brief Represents a compile-time sequence of integers.
     222             : template <class T, T... I> struct integer_sequence {
     223             :   typedef T value_type;
     224             : 
     225             :   static LLVM_CONSTEXPR size_t size() { return sizeof...(I); }
     226             : };
     227             : 
     228             : /// \brief Alias for the common case of a sequence of size_ts.
     229             : template <size_t... I>
     230             : struct index_sequence : integer_sequence<std::size_t, I...> {};
     231             : 
     232             : template <std::size_t N, std::size_t... I>
     233             : struct build_index_impl : build_index_impl<N - 1, N - 1, I...> {};
     234             : template <std::size_t... I>
     235             : struct build_index_impl<0, I...> : index_sequence<I...> {};
     236             : 
     237             : /// \brief Creates a compile-time integer sequence for a parameter pack.
     238             : template <class... Ts>
     239             : struct index_sequence_for : build_index_impl<sizeof...(Ts)> {};
     240             : 
     241             : //===----------------------------------------------------------------------===//
     242             : //     Extra additions for arrays
     243             : //===----------------------------------------------------------------------===//
     244             : 
     245             : /// Find the length of an array.
     246             : template <class T, std::size_t N>
     247             : LLVM_CONSTEXPR inline size_t array_lengthof(T (&)[N]) {
     248             :   return N;
     249             : }
     250             : 
     251             : /// Adapt std::less<T> for array_pod_sort.
     252             : template<typename T>
     253             : inline int array_pod_sort_comparator(const void *P1, const void *P2) {
     254             :   if (std::less<T>()(*reinterpret_cast<const T*>(P1),
     255             :                      *reinterpret_cast<const T*>(P2)))
     256             :     return -1;
     257             :   if (std::less<T>()(*reinterpret_cast<const T*>(P2),
     258             :                      *reinterpret_cast<const T*>(P1)))
     259             :     return 1;
     260             :   return 0;
     261             : }
     262             : 
     263             : /// get_array_pod_sort_comparator - This is an internal helper function used to
     264             : /// get type deduction of T right.
     265             : template<typename T>
     266             : inline int (*get_array_pod_sort_comparator(const T &))
     267             :              (const void*, const void*) {
     268             :   return array_pod_sort_comparator<T>;
     269             : }
     270             : 
     271             : 
     272             : /// array_pod_sort - This sorts an array with the specified start and end
     273             : /// extent.  This is just like std::sort, except that it calls qsort instead of
     274             : /// using an inlined template.  qsort is slightly slower than std::sort, but
     275             : /// most sorts are not performance critical in LLVM and std::sort has to be
     276             : /// template instantiated for each type, leading to significant measured code
     277             : /// bloat.  This function should generally be used instead of std::sort where
     278             : /// possible.
     279             : ///
     280             : /// This function assumes that you have simple POD-like types that can be
     281             : /// compared with std::less and can be moved with memcpy.  If this isn't true,
     282             : /// you should use std::sort.
     283             : ///
     284             : /// NOTE: If qsort_r were portable, we could allow a custom comparator and
     285             : /// default to std::less.
     286             : template<class IteratorTy>
     287             : inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
     288             :   // Don't inefficiently call qsort with one element or trigger undefined
     289             :   // behavior with an empty sequence.
     290             :   auto NElts = End - Start;
     291             :   if (NElts <= 1) return;
     292             :   qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start));
     293             : }
     294             : 
     295             : template <class IteratorTy>
     296             : inline void array_pod_sort(
     297             :     IteratorTy Start, IteratorTy End,
     298             :     int (*Compare)(
     299             :         const typename std::iterator_traits<IteratorTy>::value_type *,
     300             :         const typename std::iterator_traits<IteratorTy>::value_type *)) {
     301             :   // Don't inefficiently call qsort with one element or trigger undefined
     302             :   // behavior with an empty sequence.
     303             :   auto NElts = End - Start;
     304             :   if (NElts <= 1) return;
     305             :   qsort(&*Start, NElts, sizeof(*Start),
     306             :         reinterpret_cast<int (*)(const void *, const void *)>(Compare));
     307             : }
     308             : 
     309             : //===----------------------------------------------------------------------===//
     310             : //     Extra additions to <algorithm>
     311             : //===----------------------------------------------------------------------===//
     312             : 
     313             : /// For a container of pointers, deletes the pointers and then clears the
     314             : /// container.
     315             : template<typename Container>
     316             : void DeleteContainerPointers(Container &C) {
     317             :   for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
     318             :     delete *I;
     319             :   C.clear();
     320             : }
     321             : 
     322             : /// In a container of pairs (usually a map) whose second element is a pointer,
     323             : /// deletes the second elements and then clears the container.
     324             : template<typename Container>
     325             : void DeleteContainerSeconds(Container &C) {
     326             :   for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
     327             :     delete I->second;
     328             :   C.clear();
     329             : }
     330             : 
     331             : /// Provide wrappers to std::all_of which take ranges instead of having to pass
     332             : /// being/end explicitly.
     333             : template<typename R, class UnaryPredicate>
     334             : bool all_of(R &&Range, UnaryPredicate &&P) {
     335             :   return std::all_of(Range.begin(), Range.end(),
     336             :                      std::forward<UnaryPredicate>(P));
     337             : }
     338             : 
     339             : //===----------------------------------------------------------------------===//
     340             : //     Extra additions to <memory>
     341             : //===----------------------------------------------------------------------===//
     342             : 
     343             : // Implement make_unique according to N3656.
     344             : 
     345             : /// \brief Constructs a `new T()` with the given args and returns a
     346             : ///        `unique_ptr<T>` which owns the object.
     347             : ///
     348             : /// Example:
     349             : ///
     350             : ///     auto p = make_unique<int>();
     351             : ///     auto p = make_unique<std::tuple<int, int>>(0, 1);
     352             : template <class T, class... Args>
     353             : typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
     354             : make_unique(Args &&... args) {
     355          24 :   return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
     356           0 : }
     357             : 
     358             : /// \brief Constructs a `new T[n]` with the given args and returns a
     359             : ///        `unique_ptr<T[]>` which owns the object.
     360             : ///
     361             : /// \param n size of the new array.
     362             : ///
     363             : /// Example:
     364             : ///
     365             : ///     auto p = make_unique<int[]>(2); // value-initializes the array with 0's.
     366             : template <class T>
     367             : typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
     368             :                         std::unique_ptr<T>>::type
     369             : make_unique(size_t n) {
     370             :   return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
     371             : }
     372             : 
     373             : /// This function isn't used and is only here to provide better compile errors.
     374             : template <class T, class... Args>
     375             : typename std::enable_if<std::extent<T>::value != 0>::type
     376             : make_unique(Args &&...) = delete;
     377             : 
     378             : struct FreeDeleter {
     379             :   void operator()(void* v) {
     380             :     ::free(v);
     381             :   }
     382             : };
     383             : 
     384             : template<typename First, typename Second>
     385             : struct pair_hash {
     386             :   size_t operator()(const std::pair<First, Second> &P) const {
     387             :     return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
     388             :   }
     389             : };
     390             : 
     391             : /// A functor like C++14's std::less<void> in its absence.
     392             : struct less {
     393             :   template <typename A, typename B> bool operator()(A &&a, B &&b) const {
     394             :     return std::forward<A>(a) < std::forward<B>(b);
     395             :   }
     396             : };
     397             : 
     398             : /// A functor like C++14's std::equal<void> in its absence.
     399             : struct equal {
     400             :   template <typename A, typename B> bool operator()(A &&a, B &&b) const {
     401             :     return std::forward<A>(a) == std::forward<B>(b);
     402             :   }
     403             : };
     404             : 
     405             : /// Binary functor that adapts to any other binary functor after dereferencing
     406             : /// operands.
     407             : template <typename T> struct deref {
     408             :   T func;
     409             :   // Could be further improved to cope with non-derivable functors and
     410             :   // non-binary functors (should be a variadic template member function
     411             :   // operator()).
     412             :   template <typename A, typename B>
     413             :   auto operator()(A &lhs, B &rhs) const -> decltype(func(*lhs, *rhs)) {
     414             :     assert(lhs);
     415             :     assert(rhs);
     416             :     return func(*lhs, *rhs);
     417             :   }
     418             : };
     419             : 
     420             : } // End llvm namespace
     421             : 
     422             : #endif

Generated by: LCOV version 1.11