LCOV - code coverage report
Current view: top level - llvm/ADT - ArrayRef.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 5 15 33.3 %
Date: 2016-01-31 12:01:00 Functions: 5 25 20.0 %

          Line data    Source code
       1             : //===--- ArrayRef.h - Array Reference Wrapper -------------------*- 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             : #ifndef LLVM_ADT_ARRAYREF_H
      11             : #define LLVM_ADT_ARRAYREF_H
      12             : 
      13             : #include "llvm/ADT/None.h"
      14             : #include "llvm/ADT/SmallVector.h"
      15             : #include <vector>
      16             : 
      17             : namespace llvm {
      18             : 
      19             :   /// ArrayRef - Represent a constant reference to an array (0 or more elements
      20             :   /// consecutively in memory), i.e. a start pointer and a length.  It allows
      21             :   /// various APIs to take consecutive elements easily and conveniently.
      22             :   ///
      23             :   /// This class does not own the underlying data, it is expected to be used in
      24             :   /// situations where the data resides in some other buffer, whose lifetime
      25             :   /// extends past that of the ArrayRef. For this reason, it is not in general
      26             :   /// safe to store an ArrayRef.
      27             :   ///
      28             :   /// This is intended to be trivially copyable, so it should be passed by
      29             :   /// value.
      30             :   template<typename T>
      31             :   class ArrayRef {
      32             :   public:
      33             :     typedef const T *iterator;
      34             :     typedef const T *const_iterator;
      35             :     typedef size_t size_type;
      36             : 
      37             :     typedef std::reverse_iterator<iterator> reverse_iterator;
      38             : 
      39             :   private:
      40             :     /// The start of the array, in an external buffer.
      41             :     const T *Data;
      42             : 
      43             :     /// The number of elements.
      44             :     size_type Length;
      45             : 
      46             :   public:
      47             :     /// @name Constructors
      48             :     /// @{
      49             : 
      50             :     /// Construct an empty ArrayRef.
      51             :     /*implicit*/ ArrayRef() : Data(nullptr), Length(0) {}
      52             : 
      53             :     /// Construct an empty ArrayRef from None.
      54             :     /*implicit*/ ArrayRef(NoneType) : Data(nullptr), Length(0) {}
      55             : 
      56             :     /// Construct an ArrayRef from a single element.
      57             :     /*implicit*/ ArrayRef(const T &OneElt)
      58             :       : Data(&OneElt), Length(1) {}
      59             : 
      60             :     /// Construct an ArrayRef from a pointer and length.
      61             :     /*implicit*/ ArrayRef(const T *data, size_t length)
      62           0 :       : Data(data), Length(length) {}
      63             : 
      64             :     /// Construct an ArrayRef from a range.
      65             :     ArrayRef(const T *begin, const T *end)
      66          16 :       : Data(begin), Length(end - begin) {}
      67             : 
      68             :     /// Construct an ArrayRef from a SmallVector. This is templated in order to
      69             :     /// avoid instantiating SmallVectorTemplateCommon<T> whenever we
      70             :     /// copy-construct an ArrayRef.
      71             :     template<typename U>
      72             :     /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec)
      73             :       : Data(Vec.data()), Length(Vec.size()) {
      74             :     }
      75             : 
      76             :     /// Construct an ArrayRef from a std::vector.
      77             :     template<typename A>
      78             :     /*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
      79          12 :       : Data(Vec.data()), Length(Vec.size()) {}
      80             : 
      81             :     /// Construct an ArrayRef from a C array.
      82             :     template <size_t N>
      83             :     /*implicit*/ LLVM_CONSTEXPR ArrayRef(const T (&Arr)[N])
      84             :       : Data(Arr), Length(N) {}
      85             : 
      86             :     /// Construct an ArrayRef from a std::initializer_list.
      87             :     /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec)
      88             :     : Data(Vec.begin() == Vec.end() ? (T*)0 : Vec.begin()),
      89             :       Length(Vec.size()) {}
      90             : 
      91             :     /// Construct an ArrayRef<const T*> from ArrayRef<T*>. This uses SFINAE to
      92             :     /// ensure that only ArrayRefs of pointers can be converted.
      93             :     template <typename U>
      94             :     ArrayRef(const ArrayRef<U *> &A,
      95             :              typename std::enable_if<
      96             :                  std::is_convertible<U *const *, T const *>::value>::type* = 0)
      97             :       : Data(A.data()), Length(A.size()) {}
      98             : 
      99             :     /// Construct an ArrayRef<const T*> from a SmallVector<T*>. This is
     100             :     /// templated in order to avoid instantiating SmallVectorTemplateCommon<T>
     101             :     /// whenever we copy-construct an ArrayRef.
     102             :     template<typename U, typename DummyT>
     103             :     /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<U*, DummyT> &Vec,
     104             :                           typename std::enable_if<
     105             :                               std::is_convertible<U *const *,
     106             :                                                   T const *>::value>::type* = 0)
     107             :       : Data(Vec.data()), Length(Vec.size()) {
     108             :     }
     109             : 
     110             :     /// Construct an ArrayRef<const T*> from std::vector<T*>. This uses SFINAE
     111             :     /// to ensure that only vectors of pointers can be converted.
     112             :     template<typename U, typename A>
     113             :     ArrayRef(const std::vector<U *, A> &Vec,
     114             :              typename std::enable_if<
     115             :                  std::is_convertible<U *const *, T const *>::value>::type* = 0)
     116             :       : Data(Vec.data()), Length(Vec.size()) {}
     117             : 
     118             :     /// @}
     119             :     /// @name Simple Operations
     120             :     /// @{
     121             : 
     122          16 :     iterator begin() const { return Data; }
     123          16 :     iterator end() const { return Data + Length; }
     124             : 
     125             :     reverse_iterator rbegin() const { return reverse_iterator(end()); }
     126             :     reverse_iterator rend() const { return reverse_iterator(begin()); }
     127             : 
     128             :     /// empty - Check if the array is empty.
     129             :     bool empty() const { return Length == 0; }
     130             : 
     131           0 :     const T *data() const { return Data; }
     132             : 
     133             :     /// size - Get the array size.
     134           0 :     size_t size() const { return Length; }
     135             : 
     136             :     /// front - Get the first element.
     137             :     const T &front() const {
     138             :       assert(!empty());
     139             :       return Data[0];
     140             :     }
     141             : 
     142             :     /// back - Get the last element.
     143             :     const T &back() const {
     144             :       assert(!empty());
     145             :       return Data[Length-1];
     146             :     }
     147             : 
     148             :     // copy - Allocate copy in Allocator and return ArrayRef<T> to it.
     149             :     template <typename Allocator> ArrayRef<T> copy(Allocator &A) {
     150             :       T *Buff = A.template Allocate<T>(Length);
     151             :       std::copy(begin(), end(), Buff);
     152             :       return ArrayRef<T>(Buff, Length);
     153             :     }
     154             : 
     155             :     /// equals - Check for element-wise equality.
     156             :     bool equals(ArrayRef RHS) const {
     157             :       if (Length != RHS.Length)
     158             :         return false;
     159             :       if (Length == 0)
     160             :         return true;
     161             :       return std::equal(begin(), end(), RHS.begin());
     162             :     }
     163             : 
     164             :     /// slice(n) - Chop off the first N elements of the array.
     165             :     ArrayRef<T> slice(unsigned N) const {
     166             :       assert(N <= size() && "Invalid specifier");
     167             :       return ArrayRef<T>(data()+N, size()-N);
     168             :     }
     169             : 
     170             :     /// slice(n, m) - Chop off the first N elements of the array, and keep M
     171             :     /// elements in the array.
     172             :     ArrayRef<T> slice(unsigned N, unsigned M) const {
     173             :       assert(N+M <= size() && "Invalid specifier");
     174             :       return ArrayRef<T>(data()+N, M);
     175             :     }
     176             : 
     177             :     // \brief Drop the last \p N elements of the array.
     178             :     ArrayRef<T> drop_back(unsigned N = 1) const {
     179             :       assert(size() >= N && "Dropping more elements than exist");
     180             :       return slice(0, size() - N);
     181             :     }
     182             : 
     183             :     /// @}
     184             :     /// @name Operator Overloads
     185             :     /// @{
     186             :     const T &operator[](size_t Index) const {
     187           0 :       assert(Index < Length && "Invalid index!");
     188           0 :       return Data[Index];
     189             :     }
     190             : 
     191             :     /// @}
     192             :     /// @name Expensive Operations
     193             :     /// @{
     194             :     std::vector<T> vec() const {
     195             :       return std::vector<T>(Data, Data+Length);
     196             :     }
     197             : 
     198             :     /// @}
     199             :     /// @name Conversion operators
     200             :     /// @{
     201             :     operator std::vector<T>() const {
     202             :       return std::vector<T>(Data, Data+Length);
     203             :     }
     204             : 
     205             :     /// @}
     206             :   };
     207             : 
     208             :   /// MutableArrayRef - Represent a mutable reference to an array (0 or more
     209             :   /// elements consecutively in memory), i.e. a start pointer and a length.  It
     210             :   /// allows various APIs to take and modify consecutive elements easily and
     211             :   /// conveniently.
     212             :   ///
     213             :   /// This class does not own the underlying data, it is expected to be used in
     214             :   /// situations where the data resides in some other buffer, whose lifetime
     215             :   /// extends past that of the MutableArrayRef. For this reason, it is not in
     216             :   /// general safe to store a MutableArrayRef.
     217             :   ///
     218             :   /// This is intended to be trivially copyable, so it should be passed by
     219             :   /// value.
     220             :   template<typename T>
     221             :   class MutableArrayRef : public ArrayRef<T> {
     222             :   public:
     223             :     typedef T *iterator;
     224             : 
     225             :     typedef std::reverse_iterator<iterator> reverse_iterator;
     226             : 
     227             :     /// Construct an empty MutableArrayRef.
     228             :     /*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
     229             : 
     230             :     /// Construct an empty MutableArrayRef from None.
     231             :     /*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {}
     232             : 
     233             :     /// Construct an MutableArrayRef from a single element.
     234             :     /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
     235             : 
     236             :     /// Construct an MutableArrayRef from a pointer and length.
     237             :     /*implicit*/ MutableArrayRef(T *data, size_t length)
     238           0 :       : ArrayRef<T>(data, length) {}
     239             : 
     240             :     /// Construct an MutableArrayRef from a range.
     241             :     MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
     242             : 
     243             :     /// Construct an MutableArrayRef from a SmallVector.
     244             :     /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
     245             :     : ArrayRef<T>(Vec) {}
     246             : 
     247             :     /// Construct a MutableArrayRef from a std::vector.
     248             :     /*implicit*/ MutableArrayRef(std::vector<T> &Vec)
     249             :     : ArrayRef<T>(Vec) {}
     250             : 
     251             :     /// Construct an MutableArrayRef from a C array.
     252             :     template <size_t N>
     253             :     /*implicit*/ LLVM_CONSTEXPR MutableArrayRef(T (&Arr)[N])
     254             :       : ArrayRef<T>(Arr) {}
     255             : 
     256           0 :     T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
     257             : 
     258           0 :     iterator begin() const { return data(); }
     259           0 :     iterator end() const { return data() + this->size(); }
     260             : 
     261             :     reverse_iterator rbegin() const { return reverse_iterator(end()); }
     262             :     reverse_iterator rend() const { return reverse_iterator(begin()); }
     263             : 
     264             :     /// front - Get the first element.
     265             :     T &front() const {
     266             :       assert(!this->empty());
     267             :       return data()[0];
     268             :     }
     269             : 
     270             :     /// back - Get the last element.
     271             :     T &back() const {
     272             :       assert(!this->empty());
     273             :       return data()[this->size()-1];
     274             :     }
     275             : 
     276             :     /// slice(n) - Chop off the first N elements of the array.
     277             :     MutableArrayRef<T> slice(unsigned N) const {
     278             :       assert(N <= this->size() && "Invalid specifier");
     279             :       return MutableArrayRef<T>(data()+N, this->size()-N);
     280             :     }
     281             : 
     282             :     /// slice(n, m) - Chop off the first N elements of the array, and keep M
     283             :     /// elements in the array.
     284             :     MutableArrayRef<T> slice(unsigned N, unsigned M) const {
     285             :       assert(N+M <= this->size() && "Invalid specifier");
     286             :       return MutableArrayRef<T>(data()+N, M);
     287             :     }
     288             : 
     289             :     MutableArrayRef<T> drop_back(unsigned N) const {
     290             :       assert(this->size() >= N && "Dropping more elements than exist");
     291             :       return slice(0, this->size() - N);
     292             :     }
     293             : 
     294             :     /// @}
     295             :     /// @name Operator Overloads
     296             :     /// @{
     297             :     T &operator[](size_t Index) const {
     298             :       assert(Index < this->size() && "Invalid index!");
     299             :       return data()[Index];
     300             :     }
     301             :   };
     302             : 
     303             :   /// @name ArrayRef Convenience constructors
     304             :   /// @{
     305             : 
     306             :   /// Construct an ArrayRef from a single element.
     307             :   template<typename T>
     308             :   ArrayRef<T> makeArrayRef(const T &OneElt) {
     309             :     return OneElt;
     310             :   }
     311             : 
     312             :   /// Construct an ArrayRef from a pointer and length.
     313             :   template<typename T>
     314             :   ArrayRef<T> makeArrayRef(const T *data, size_t length) {
     315           0 :     return ArrayRef<T>(data, length);
     316             :   }
     317             : 
     318             :   /// Construct an ArrayRef from a range.
     319             :   template<typename T>
     320             :   ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
     321          16 :     return ArrayRef<T>(begin, end);
     322             :   }
     323             : 
     324             :   /// Construct an ArrayRef from a SmallVector.
     325             :   template <typename T>
     326             :   ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
     327             :     return Vec;
     328             :   }
     329             : 
     330             :   /// Construct an ArrayRef from a SmallVector.
     331             :   template <typename T, unsigned N>
     332             :   ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
     333             :     return Vec;
     334             :   }
     335             : 
     336             :   /// Construct an ArrayRef from a std::vector.
     337             :   template<typename T>
     338             :   ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
     339             :     return Vec;
     340             :   }
     341             : 
     342             :   /// Construct an ArrayRef from a C array.
     343             :   template<typename T, size_t N>
     344             :   ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
     345             :     return ArrayRef<T>(Arr);
     346             :   }
     347             : 
     348             :   /// @}
     349             :   /// @name ArrayRef Comparison Operators
     350             :   /// @{
     351             : 
     352             :   template<typename T>
     353             :   inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
     354             :     return LHS.equals(RHS);
     355             :   }
     356             : 
     357             :   template<typename T>
     358             :   inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
     359             :     return !(LHS == RHS);
     360             :   }
     361             : 
     362             :   /// @}
     363             : 
     364             :   // ArrayRefs can be treated like a POD type.
     365             :   template <typename T> struct isPodLike;
     366             :   template <typename T> struct isPodLike<ArrayRef<T> > {
     367             :     static const bool value = true;
     368             :   };
     369             : }
     370             : 
     371             : #endif

Generated by: LCOV version 1.11