ArrayRef.h revision f6275309994dea2ec852c1f539875ae643646ec5
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/SmallVector.h"
14#include <vector>
15
16namespace llvm {
17  class APInt;
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  private:
38    /// The start of the array, in an external buffer.
39    const T *Data;
40
41    /// The number of elements.
42    size_type Length;
43
44  public:
45    /// @name Constructors
46    /// @{
47
48    /// Construct an empty ArrayRef.
49    /*implicit*/ ArrayRef() : Data(0), Length(0) {}
50
51    /// Construct an ArrayRef from a single element.
52    /*implicit*/ ArrayRef(const T &OneElt)
53      : Data(&OneElt), Length(1) {}
54
55    /// Construct an ArrayRef from a pointer and length.
56    /*implicit*/ ArrayRef(const T *data, size_t length)
57      : Data(data), Length(length) {}
58
59    /// Construct an ArrayRef from a range.
60    ArrayRef(const T *begin, const T *end)
61      : Data(begin), Length(end - begin) {}
62
63    /// Construct an ArrayRef from a SmallVector.
64    /*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec)
65      : Data(Vec.data()), Length(Vec.size()) {}
66
67    /// Construct an ArrayRef from a std::vector.
68    /*implicit*/ ArrayRef(const std::vector<T> &Vec)
69      : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
70
71    /// Construct an ArrayRef from a C array.
72    template <size_t N>
73    /*implicit*/ ArrayRef(const T (&Arr)[N])
74      : Data(Arr), Length(N) {}
75
76    /// @}
77    /// @name Simple Operations
78    /// @{
79
80    iterator begin() const { return Data; }
81    iterator end() const { return Data + Length; }
82
83    /// empty - Check if the array is empty.
84    bool empty() const { return Length == 0; }
85
86    const T *data() const { return Data; }
87
88    /// size - Get the array size.
89    size_t size() const { return Length; }
90
91    /// front - Get the first element.
92    const T &front() const {
93      assert(!empty());
94      return Data[0];
95    }
96
97    /// back - Get the last element.
98    const T &back() const {
99      assert(!empty());
100      return Data[Length-1];
101    }
102
103    /// equals - Check for element-wise equality.
104    bool equals(ArrayRef RHS) const {
105      if (Length != RHS.Length)
106        return false;
107      for (size_type i = 0; i != Length; i++)
108        if (Data[i] != RHS.Data[i])
109          return false;
110      return true;
111    }
112
113    /// slice(n) - Chop off the first N elements of the array.
114    ArrayRef<T> slice(unsigned N) {
115      assert(N <= size() && "Invalid specifier");
116      return ArrayRef<T>(data()+N, size()-N);
117    }
118
119    /// slice(n, m) - Chop off the first N elements of the array, and keep M
120    /// elements in the array.
121    ArrayRef<T> slice(unsigned N, unsigned M) {
122      assert(N+M <= size() && "Invalid specifier");
123      return ArrayRef<T>(data()+N, M);
124    }
125
126    /// @}
127    /// @name Operator Overloads
128    /// @{
129    const T &operator[](size_t Index) const {
130      assert(Index < Length && "Invalid index!");
131      return Data[Index];
132    }
133
134    /// @}
135    /// @name Expensive Operations
136    /// @{
137    std::vector<T> vec() const {
138      return std::vector<T>(Data, Data+Length);
139    }
140
141    /// @}
142    /// @name Conversion operators
143    /// @{
144    operator std::vector<T>() const {
145      return std::vector<T>(Data, Data+Length);
146    }
147
148    /// @}
149  };
150
151  /// @name ArrayRef Convenience constructors
152  /// @{
153
154  /// Construct an ArrayRef from a single element.
155  template<typename T>
156  ArrayRef<T> makeArrayRef(const T &OneElt) {
157    return OneElt;
158  }
159
160  /// Construct an ArrayRef from a pointer and length.
161  template<typename T>
162  ArrayRef<T> makeArrayRef(const T *data, size_t length) {
163    return ArrayRef<T>(data, length);
164  }
165
166  /// Construct an ArrayRef from a range.
167  template<typename T>
168  ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
169    return ArrayRef<T>(begin, end);
170  }
171
172  /// Construct an ArrayRef from a SmallVector.
173  template <typename T>
174  ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
175    return Vec;
176  }
177
178  /// Construct an ArrayRef from a SmallVector.
179  template <typename T, unsigned N>
180  ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
181    return Vec;
182  }
183
184  /// Construct an ArrayRef from a std::vector.
185  template<typename T>
186  ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
187    return Vec;
188  }
189
190  /// Construct an ArrayRef from a C array.
191  template<typename T, size_t N>
192  ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
193    return ArrayRef<T>(Arr);
194  }
195
196  /// @}
197  /// @name ArrayRef Comparison Operators
198  /// @{
199
200  template<typename T>
201  inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
202    return LHS.equals(RHS);
203  }
204
205  template<typename T>
206  inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
207    return !(LHS == RHS);
208  }
209
210  /// @}
211
212  // ArrayRefs can be treated like a POD type.
213  template <typename T> struct isPodLike;
214  template <typename T> struct isPodLike<ArrayRef<T> > {
215    static const bool value = true;
216  };
217}
218
219#endif
220