ArrayRef.h revision 5d4f9909c49d28db9572acc4513c1a695b0c53da
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 Comparison Operators
152  /// @{
153
154  template<typename T>
155  inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
156    return LHS.equals(RHS);
157  }
158
159  template<typename T>
160  inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
161    return !(LHS == RHS);
162  }
163
164  /// @}
165
166  // ArrayRefs can be treated like a POD type.
167  template <typename T> struct isPodLike;
168  template <typename T> struct isPodLike<ArrayRef<T> > {
169    static const bool value = true;
170  };
171}
172
173#endif
174