ArrayRef.h revision 715c80a00b965f19ca2c7dacbc2f809221cc2730
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_t 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 SmallVector.
60    /*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec)
61      : Data(Vec.data()), Length(Vec.size()) {}
62
63    /// Construct an ArrayRef from a std::vector.
64    /*implicit*/ ArrayRef(const std::vector<T> &Vec)
65      : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
66
67    /// Construct an ArrayRef from a C array.
68    template <size_t N>
69    /*implicit*/ ArrayRef(const T (&Arr)[N])
70      : Data(Arr), Length(N) {}
71
72    /// @}
73    /// @name Simple Operations
74    /// @{
75
76    iterator begin() const { return Data; }
77    iterator end() const { return Data + Length; }
78
79    /// empty - Check if the array is empty.
80    bool empty() const { return Length == 0; }
81
82    const T *data() const { return Data; }
83
84    /// size - Get the array size.
85    size_t size() const { return Length; }
86
87    /// front - Get the first element.
88    const T &front() const {
89      assert(!empty());
90      return Data[0];
91    }
92
93    /// back - Get the last element.
94    const T &back() const {
95      assert(!empty());
96      return Data[Length-1];
97    }
98
99    /// slice(n) - Chop off the first N elements of the array.
100    ArrayRef<T> slice(unsigned N) {
101      assert(N <= size() && "Invalid specifier");
102      return ArrayRef<T>(data()+N, size()-N);
103    }
104
105    /// slice(n, m) - Chop off the first N elements of the array, and keep M
106    /// elements in the array.
107    ArrayRef<T> slice(unsigned N, unsigned M) {
108      assert(N+M <= size() && "Invalid specifier");
109      return ArrayRef<T>(data()+N, M);
110    }
111
112    /// @}
113    /// @name Operator Overloads
114    /// @{
115    const T &operator[](size_t Index) const {
116      assert(Index < Length && "Invalid index!");
117      return Data[Index];
118    }
119
120    /// @}
121    /// @name Expensive Operations
122    /// @{
123    std::vector<T> vec() const {
124      return std::vector<T>(Data, Data+Length);
125    }
126
127    /// @}
128  };
129
130  // ArrayRefs can be treated like a POD type.
131  template <typename T> struct isPodLike;
132  template <typename T> struct isPodLike<ArrayRef<T> > {
133    static const bool value = true;
134  };
135}
136
137#endif
138