LLVM API Documentation

ArrayRef.h
Go to the documentation of this file.
00001 //===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #ifndef LLVM_ADT_ARRAYREF_H
00011 #define LLVM_ADT_ARRAYREF_H
00012 
00013 #include "llvm/ADT/None.h"
00014 #include "llvm/ADT/STLExtras.h"
00015 #include "llvm/ADT/SmallVector.h"
00016 #include <vector>
00017 
00018 namespace llvm {
00019 
00020   /// ArrayRef - Represent a constant reference to an array (0 or more elements
00021   /// consecutively in memory), i.e. a start pointer and a length.  It allows
00022   /// various APIs to take consecutive elements easily and conveniently.
00023   ///
00024   /// This class does not own the underlying data, it is expected to be used in
00025   /// situations where the data resides in some other buffer, whose lifetime
00026   /// extends past that of the ArrayRef. For this reason, it is not in general
00027   /// safe to store an ArrayRef.
00028   ///
00029   /// This is intended to be trivially copyable, so it should be passed by
00030   /// value.
00031   template<typename T>
00032   class ArrayRef {
00033   public:
00034     typedef const T *iterator;
00035     typedef const T *const_iterator;
00036     typedef size_t size_type;
00037 
00038     typedef std::reverse_iterator<iterator> reverse_iterator;
00039 
00040   private:
00041     /// The start of the array, in an external buffer.
00042     const T *Data;
00043 
00044     /// The number of elements.
00045     size_type Length;
00046 
00047     /// \brief A dummy "optional" type that is only created by implicit
00048     /// conversion from a reference to T.
00049     ///
00050     /// This type must *only* be used in a function argument or as a copy of
00051     /// a function argument, as otherwise it will hold a pointer to a temporary
00052     /// past that temporaries' lifetime.
00053     struct TRefOrNothing {
00054       const T *TPtr;
00055 
00056       TRefOrNothing() : TPtr(nullptr) {}
00057       TRefOrNothing(const T &TRef) : TPtr(&TRef) {}
00058     };
00059 
00060   public:
00061     /// @name Constructors
00062     /// @{
00063 
00064     /// Construct an empty ArrayRef.
00065     /*implicit*/ ArrayRef() : Data(nullptr), Length(0) {}
00066 
00067     /// Construct an empty ArrayRef from None.
00068     /*implicit*/ ArrayRef(NoneType) : Data(nullptr), Length(0) {}
00069 
00070     /// Construct an ArrayRef from a single element.
00071     /*implicit*/ ArrayRef(const T &OneElt)
00072       : Data(&OneElt), Length(1) {}
00073 
00074     /// Construct an ArrayRef from a pointer and length.
00075     /*implicit*/ ArrayRef(const T *data, size_t length)
00076       : Data(data), Length(length) {}
00077 
00078     /// Construct an ArrayRef from a range.
00079     ArrayRef(const T *begin, const T *end)
00080       : Data(begin), Length(end - begin) {}
00081 
00082     /// Construct an ArrayRef from a SmallVector. This is templated in order to
00083     /// avoid instantiating SmallVectorTemplateCommon<T> whenever we
00084     /// copy-construct an ArrayRef.
00085     template<typename U>
00086     /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec)
00087       : Data(Vec.data()), Length(Vec.size()) {
00088     }
00089 
00090     /// Construct an ArrayRef from a std::vector.
00091     template<typename A>
00092     /*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
00093       : Data(Vec.data()), Length(Vec.size()) {}
00094 
00095     /// Construct an ArrayRef from a C array.
00096     template <size_t N>
00097     /*implicit*/ LLVM_CONSTEXPR ArrayRef(const T (&Arr)[N])
00098       : Data(Arr), Length(N) {}
00099 
00100 #if LLVM_HAS_INITIALIZER_LISTS
00101     /// Construct an ArrayRef from a std::initializer_list.
00102     /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec)
00103     : Data(Vec.begin() == Vec.end() ? (T*)0 : Vec.begin()),
00104       Length(Vec.size()) {}
00105 #endif
00106 
00107     /// Construct an ArrayRef<const T*> from ArrayRef<T*>. This uses SFINAE to
00108     /// ensure that only ArrayRefs of pointers can be converted.
00109     template <typename U>
00110     ArrayRef(const ArrayRef<U *> &A,
00111              typename std::enable_if<
00112                  std::is_convertible<U *const *, T const *>::value>::type* = 0)
00113       : Data(A.data()), Length(A.size()) {}
00114 
00115     /// @}
00116     /// @name Simple Operations
00117     /// @{
00118 
00119     iterator begin() const { return Data; }
00120     iterator end() const { return Data + Length; }
00121 
00122     reverse_iterator rbegin() const { return reverse_iterator(end()); }
00123     reverse_iterator rend() const { return reverse_iterator(begin()); }
00124 
00125     /// empty - Check if the array is empty.
00126     bool empty() const { return Length == 0; }
00127 
00128     const T *data() const { return Data; }
00129 
00130     /// size - Get the array size.
00131     size_t size() const { return Length; }
00132 
00133     /// front - Get the first element.
00134     const T &front() const {
00135       assert(!empty());
00136       return Data[0];
00137     }
00138 
00139     /// back - Get the last element.
00140     const T &back() const {
00141       assert(!empty());
00142       return Data[Length-1];
00143     }
00144 
00145     // copy - Allocate copy in Allocator and return ArrayRef<T> to it.
00146     template <typename Allocator> ArrayRef<T> copy(Allocator &A) {
00147       T *Buff = A.template Allocate<T>(Length);
00148       std::copy(begin(), end(), Buff);
00149       return ArrayRef<T>(Buff, Length);
00150     }
00151 
00152     /// equals - Check for element-wise equality.
00153     bool equals(ArrayRef RHS) const {
00154       if (Length != RHS.Length)
00155         return false;
00156       // Don't use std::equal(), since it asserts in MSVC on nullptr iterators.
00157       for (auto L = begin(), LE = end(), R = RHS.begin(); L != LE; ++L, ++R)
00158         // Match std::equal() in using == (instead of !=) to minimize API
00159         // requirements of ArrayRef'ed types.
00160         if (!(*L == *R))
00161           return false;
00162       return true;
00163     }
00164 
00165     /// slice(n) - Chop off the first N elements of the array.
00166     ArrayRef<T> slice(unsigned N) const {
00167       assert(N <= size() && "Invalid specifier");
00168       return ArrayRef<T>(data()+N, size()-N);
00169     }
00170 
00171     /// slice(n, m) - Chop off the first N elements of the array, and keep M
00172     /// elements in the array.
00173     ArrayRef<T> slice(unsigned N, unsigned M) const {
00174       assert(N+M <= size() && "Invalid specifier");
00175       return ArrayRef<T>(data()+N, M);
00176     }
00177 
00178     // \brief Drop the last \p N elements of the array.
00179     ArrayRef<T> drop_back(unsigned N = 1) const {
00180       assert(size() >= N && "Dropping more elements than exist");
00181       return slice(0, size() - N);
00182     }
00183 
00184     /// @}
00185     /// @name Operator Overloads
00186     /// @{
00187     const T &operator[](size_t Index) const {
00188       assert(Index < Length && "Invalid index!");
00189       return Data[Index];
00190     }
00191 
00192     /// @}
00193     /// @name Expensive Operations
00194     /// @{
00195     std::vector<T> vec() const {
00196       return std::vector<T>(Data, Data+Length);
00197     }
00198 
00199     /// @}
00200     /// @name Conversion operators
00201     /// @{
00202     operator std::vector<T>() const {
00203       return std::vector<T>(Data, Data+Length);
00204     }
00205 
00206     /// @}
00207     /// @{
00208     /// @name Convenience methods
00209 
00210     /// @brief Predicate for testing that the array equals the exact sequence of
00211     /// arguments.
00212     ///
00213     /// Will return false if the size is not equal to the exact number of
00214     /// arguments given or if the array elements don't equal the argument
00215     /// elements in order. Currently supports up to 16 arguments, but can
00216     /// easily be extended.
00217     bool equals(TRefOrNothing Arg0 = TRefOrNothing(),
00218                 TRefOrNothing Arg1 = TRefOrNothing(),
00219                 TRefOrNothing Arg2 = TRefOrNothing(),
00220                 TRefOrNothing Arg3 = TRefOrNothing(),
00221                 TRefOrNothing Arg4 = TRefOrNothing(),
00222                 TRefOrNothing Arg5 = TRefOrNothing(),
00223                 TRefOrNothing Arg6 = TRefOrNothing(),
00224                 TRefOrNothing Arg7 = TRefOrNothing(),
00225                 TRefOrNothing Arg8 = TRefOrNothing(),
00226                 TRefOrNothing Arg9 = TRefOrNothing(),
00227                 TRefOrNothing Arg10 = TRefOrNothing(),
00228                 TRefOrNothing Arg11 = TRefOrNothing(),
00229                 TRefOrNothing Arg12 = TRefOrNothing(),
00230                 TRefOrNothing Arg13 = TRefOrNothing(),
00231                 TRefOrNothing Arg14 = TRefOrNothing(),
00232                 TRefOrNothing Arg15 = TRefOrNothing()) {
00233       TRefOrNothing Args[] = {Arg0,  Arg1,  Arg2,  Arg3, Arg4,  Arg5,
00234                               Arg6,  Arg7,  Arg8,  Arg9, Arg10, Arg11,
00235                               Arg12, Arg13, Arg14, Arg15};
00236       if (size() > array_lengthof(Args))
00237         return false;
00238 
00239       for (unsigned i = 0, e = size(); i != e; ++i)
00240         if (Args[i].TPtr == nullptr || (*this)[i] != *Args[i].TPtr)
00241           return false;
00242 
00243       // Either the size is exactly as many args, or the next arg must be null.
00244       return size() == array_lengthof(Args) || Args[size()].TPtr == nullptr;
00245     }
00246 
00247     /// @}
00248   };
00249 
00250   /// MutableArrayRef - Represent a mutable reference to an array (0 or more
00251   /// elements consecutively in memory), i.e. a start pointer and a length.  It
00252   /// allows various APIs to take and modify consecutive elements easily and
00253   /// conveniently.
00254   ///
00255   /// This class does not own the underlying data, it is expected to be used in
00256   /// situations where the data resides in some other buffer, whose lifetime
00257   /// extends past that of the MutableArrayRef. For this reason, it is not in
00258   /// general safe to store a MutableArrayRef.
00259   ///
00260   /// This is intended to be trivially copyable, so it should be passed by
00261   /// value.
00262   template<typename T>
00263   class MutableArrayRef : public ArrayRef<T> {
00264   public:
00265     typedef T *iterator;
00266 
00267     typedef std::reverse_iterator<iterator> reverse_iterator;
00268 
00269     /// Construct an empty MutableArrayRef.
00270     /*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
00271 
00272     /// Construct an empty MutableArrayRef from None.
00273     /*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {}
00274 
00275     /// Construct an MutableArrayRef from a single element.
00276     /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
00277 
00278     /// Construct an MutableArrayRef from a pointer and length.
00279     /*implicit*/ MutableArrayRef(T *data, size_t length)
00280       : ArrayRef<T>(data, length) {}
00281 
00282     /// Construct an MutableArrayRef from a range.
00283     MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
00284 
00285     /// Construct an MutableArrayRef from a SmallVector.
00286     /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
00287     : ArrayRef<T>(Vec) {}
00288 
00289     /// Construct a MutableArrayRef from a std::vector.
00290     /*implicit*/ MutableArrayRef(std::vector<T> &Vec)
00291     : ArrayRef<T>(Vec) {}
00292 
00293     /// Construct an MutableArrayRef from a C array.
00294     template <size_t N>
00295     /*implicit*/ LLVM_CONSTEXPR MutableArrayRef(T (&Arr)[N])
00296       : ArrayRef<T>(Arr) {}
00297 
00298     T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
00299 
00300     iterator begin() const { return data(); }
00301     iterator end() const { return data() + this->size(); }
00302 
00303     reverse_iterator rbegin() const { return reverse_iterator(end()); }
00304     reverse_iterator rend() const { return reverse_iterator(begin()); }
00305 
00306     /// front - Get the first element.
00307     T &front() const {
00308       assert(!this->empty());
00309       return data()[0];
00310     }
00311 
00312     /// back - Get the last element.
00313     T &back() const {
00314       assert(!this->empty());
00315       return data()[this->size()-1];
00316     }
00317 
00318     /// slice(n) - Chop off the first N elements of the array.
00319     MutableArrayRef<T> slice(unsigned N) const {
00320       assert(N <= this->size() && "Invalid specifier");
00321       return MutableArrayRef<T>(data()+N, this->size()-N);
00322     }
00323 
00324     /// slice(n, m) - Chop off the first N elements of the array, and keep M
00325     /// elements in the array.
00326     MutableArrayRef<T> slice(unsigned N, unsigned M) const {
00327       assert(N+M <= this->size() && "Invalid specifier");
00328       return MutableArrayRef<T>(data()+N, M);
00329     }
00330 
00331     /// @}
00332     /// @name Operator Overloads
00333     /// @{
00334     T &operator[](size_t Index) const {
00335       assert(Index < this->size() && "Invalid index!");
00336       return data()[Index];
00337     }
00338   };
00339 
00340   /// @name ArrayRef Convenience constructors
00341   /// @{
00342 
00343   /// Construct an ArrayRef from a single element.
00344   template<typename T>
00345   ArrayRef<T> makeArrayRef(const T &OneElt) {
00346     return OneElt;
00347   }
00348 
00349   /// Construct an ArrayRef from a pointer and length.
00350   template<typename T>
00351   ArrayRef<T> makeArrayRef(const T *data, size_t length) {
00352     return ArrayRef<T>(data, length);
00353   }
00354 
00355   /// Construct an ArrayRef from a range.
00356   template<typename T>
00357   ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
00358     return ArrayRef<T>(begin, end);
00359   }
00360 
00361   /// Construct an ArrayRef from a SmallVector.
00362   template <typename T>
00363   ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
00364     return Vec;
00365   }
00366 
00367   /// Construct an ArrayRef from a SmallVector.
00368   template <typename T, unsigned N>
00369   ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
00370     return Vec;
00371   }
00372 
00373   /// Construct an ArrayRef from a std::vector.
00374   template<typename T>
00375   ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
00376     return Vec;
00377   }
00378 
00379   /// Construct an ArrayRef from a C array.
00380   template<typename T, size_t N>
00381   ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
00382     return ArrayRef<T>(Arr);
00383   }
00384 
00385   /// @}
00386   /// @name ArrayRef Comparison Operators
00387   /// @{
00388 
00389   template<typename T>
00390   inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
00391     return LHS.equals(RHS);
00392   }
00393 
00394   template<typename T>
00395   inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
00396     return !(LHS == RHS);
00397   }
00398 
00399   /// @}
00400 
00401   // ArrayRefs can be treated like a POD type.
00402   template <typename T> struct isPodLike;
00403   template <typename T> struct isPodLike<ArrayRef<T> > {
00404     static const bool value = true;
00405   };
00406 }
00407 
00408 #endif