ArrayRef.h revision cd81d94322a39503e4a3e87b6ee03d4fcb3465fb
12b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner//===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===//
22b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner//
32b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner//                     The LLVM Compiler Infrastructure
42b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner//
52b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner// This file is distributed under the University of Illinois Open Source
62b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner// License. See LICENSE.TXT for details.
72b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner//
82b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner//===----------------------------------------------------------------------===//
92b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
102b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner#ifndef LLVM_ADT_ARRAYREF_H
112b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner#define LLVM_ADT_ARRAYREF_H
122b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
135c332dbd30d9398ed25b30c3080506f7b8e92290Dmitri Gribenko#include "llvm/ADT/None.h"
142b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner#include "llvm/ADT/SmallVector.h"
152b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner#include <vector>
162b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
172b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattnernamespace llvm {
18fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
192b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  /// ArrayRef - Represent a constant reference to an array (0 or more elements
2004df049014396fe97a31bf3fa8951201b2ed8ffeChris Lattner  /// consecutively in memory), i.e. a start pointer and a length.  It allows
2104df049014396fe97a31bf3fa8951201b2ed8ffeChris Lattner  /// various APIs to take consecutive elements easily and conveniently.
222b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  ///
232b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  /// This class does not own the underlying data, it is expected to be used in
242b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  /// situations where the data resides in some other buffer, whose lifetime
25715c80a00b965f19ca2c7dacbc2f809221cc2730Jay Foad  /// extends past that of the ArrayRef. For this reason, it is not in general
26715c80a00b965f19ca2c7dacbc2f809221cc2730Jay Foad  /// safe to store an ArrayRef.
272b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  ///
282b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  /// This is intended to be trivially copyable, so it should be passed by
292b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  /// value.
302b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  template<typename T>
312b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  class ArrayRef {
322b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  public:
332b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    typedef const T *iterator;
342b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    typedef const T *const_iterator;
352b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    typedef size_t size_type;
36fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
37827de0520ee986fcda5f0d3290a3746249fa5847Andrew Trick    typedef std::reverse_iterator<iterator> reverse_iterator;
38827de0520ee986fcda5f0d3290a3746249fa5847Andrew Trick
392b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  private:
402b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// The start of the array, in an external buffer.
412b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    const T *Data;
42fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
432b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// The number of elements.
445d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad    size_type Length;
45fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
462b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  public:
472b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @name Constructors
482b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @{
49fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
502b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// Construct an empty ArrayRef.
51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    /*implicit*/ ArrayRef() : Data(nullptr), Length(0) {}
52fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
535c332dbd30d9398ed25b30c3080506f7b8e92290Dmitri Gribenko    /// Construct an empty ArrayRef from None.
54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    /*implicit*/ ArrayRef(NoneType) : Data(nullptr), Length(0) {}
555c332dbd30d9398ed25b30c3080506f7b8e92290Dmitri Gribenko
562b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// Construct an ArrayRef from a single element.
572b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /*implicit*/ ArrayRef(const T &OneElt)
582b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      : Data(&OneElt), Length(1) {}
59fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
602b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// Construct an ArrayRef from a pointer and length.
6104df049014396fe97a31bf3fa8951201b2ed8ffeChris Lattner    /*implicit*/ ArrayRef(const T *data, size_t length)
622b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      : Data(data), Length(length) {}
63fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
645d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad    /// Construct an ArrayRef from a range.
655d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad    ArrayRef(const T *begin, const T *end)
665d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad      : Data(begin), Length(end - begin) {}
67fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
68bc363931085587bac42a40653962a3e5acd1ffceRichard Smith    /// Construct an ArrayRef from a SmallVector. This is templated in order to
69bc363931085587bac42a40653962a3e5acd1ffceRichard Smith    /// avoid instantiating SmallVectorTemplateCommon<T> whenever we
70bc363931085587bac42a40653962a3e5acd1ffceRichard Smith    /// copy-construct an ArrayRef.
71bc363931085587bac42a40653962a3e5acd1ffceRichard Smith    template<typename U>
72bc363931085587bac42a40653962a3e5acd1ffceRichard Smith    /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec)
73bc363931085587bac42a40653962a3e5acd1ffceRichard Smith      : Data(Vec.data()), Length(Vec.size()) {
74bc363931085587bac42a40653962a3e5acd1ffceRichard Smith    }
752b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
762b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// Construct an ArrayRef from a std::vector.
77bc363931085587bac42a40653962a3e5acd1ffceRichard Smith    template<typename A>
78bc363931085587bac42a40653962a3e5acd1ffceRichard Smith    /*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      : Data(Vec.data()), Length(Vec.size()) {}
80fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
81438208e8cb29c67b2177619a339b84291729b6b7Frits van Bommel    /// Construct an ArrayRef from a C array.
82438208e8cb29c67b2177619a339b84291729b6b7Frits van Bommel    template <size_t N>
832f02ded68a114410f11bc2f4e901d0d8e5850de1Alexander Kornienko    /*implicit*/ LLVM_CONSTEXPR ArrayRef(const T (&Arr)[N])
84438208e8cb29c67b2177619a339b84291729b6b7Frits van Bommel      : Data(Arr), Length(N) {}
85fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
8643ed63bc8310758d2a80deecb2e470f383ca5691Pete Cooper#if LLVM_HAS_INITIALIZER_LISTS
8743ed63bc8310758d2a80deecb2e470f383ca5691Pete Cooper    /// Construct an ArrayRef from a std::initializer_list.
8843ed63bc8310758d2a80deecb2e470f383ca5691Pete Cooper    /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec)
8943ed63bc8310758d2a80deecb2e470f383ca5691Pete Cooper    : Data(Vec.begin() == Vec.end() ? (T*)0 : Vec.begin()),
9043ed63bc8310758d2a80deecb2e470f383ca5691Pete Cooper      Length(Vec.size()) {}
9143ed63bc8310758d2a80deecb2e470f383ca5691Pete Cooper#endif
9243ed63bc8310758d2a80deecb2e470f383ca5691Pete Cooper
932b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @}
942b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @name Simple Operations
952b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @{
962b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
972b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    iterator begin() const { return Data; }
982b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    iterator end() const { return Data + Length; }
99fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
100827de0520ee986fcda5f0d3290a3746249fa5847Andrew Trick    reverse_iterator rbegin() const { return reverse_iterator(end()); }
101827de0520ee986fcda5f0d3290a3746249fa5847Andrew Trick    reverse_iterator rend() const { return reverse_iterator(begin()); }
102827de0520ee986fcda5f0d3290a3746249fa5847Andrew Trick
10304b2f0d99feb9cdf87eb8f35483816d757d170ddChris Lattner    /// empty - Check if the array is empty.
1042b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    bool empty() const { return Length == 0; }
105fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
106878ad7afa512ef300d5df4e7ca0189775342dfc2Chris Lattner    const T *data() const { return Data; }
107fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
10804b2f0d99feb9cdf87eb8f35483816d757d170ddChris Lattner    /// size - Get the array size.
1092b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    size_t size() const { return Length; }
110fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
1112b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// front - Get the first element.
1122b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    const T &front() const {
1132b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      assert(!empty());
1142b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      return Data[0];
1152b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    }
116fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
11704df049014396fe97a31bf3fa8951201b2ed8ffeChris Lattner    /// back - Get the last element.
1182b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    const T &back() const {
1192b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      assert(!empty());
1202b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      return Data[Length-1];
1212b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    }
122fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // copy - Allocate copy in Allocator and return ArrayRef<T> to it.
124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    template <typename Allocator> ArrayRef<T> copy(Allocator &A) {
125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      T *Buff = A.template Allocate<T>(Length);
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::copy(begin(), end(), Buff);
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return ArrayRef<T>(Buff, Length);
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1305d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad    /// equals - Check for element-wise equality.
1315d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad    bool equals(ArrayRef RHS) const {
1325d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad      if (Length != RHS.Length)
1335d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad        return false;
134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return std::equal(begin(), end(), RHS.begin());
1355d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad    }
1365d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad
137fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    /// slice(n) - Chop off the first N elements of the array.
1381752e45de9914cb52d748c1052ecd2f1414bced4Chris Lattner    ArrayRef<T> slice(unsigned N) const {
139fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner      assert(N <= size() && "Invalid specifier");
140fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner      return ArrayRef<T>(data()+N, size()-N);
141fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    }
142fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner
143fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    /// slice(n, m) - Chop off the first N elements of the array, and keep M
144fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    /// elements in the array.
1451752e45de9914cb52d748c1052ecd2f1414bced4Chris Lattner    ArrayRef<T> slice(unsigned N, unsigned M) const {
146fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner      assert(N+M <= size() && "Invalid specifier");
147fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner      return ArrayRef<T>(data()+N, M);
148fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    }
149fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
150cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // \brief Drop the last \p N elements of the array.
151cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    ArrayRef<T> drop_back(unsigned N = 1) const {
152cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(size() >= N && "Dropping more elements than exist");
153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return slice(0, size() - N);
154cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1562b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @}
1572b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @name Operator Overloads
1582b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @{
15904df049014396fe97a31bf3fa8951201b2ed8ffeChris Lattner    const T &operator[](size_t Index) const {
1602b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      assert(Index < Length && "Invalid index!");
1612b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      return Data[Index];
1622b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    }
163fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
1642b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @}
1652b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @name Expensive Operations
1662b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @{
1672b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    std::vector<T> vec() const {
1682b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      return std::vector<T>(Data, Data+Length);
1692b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    }
170fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
1712b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @}
1722a4a6fecf0b8c92223f8fdf19545b564b7d3fcdeJay Foad    /// @name Conversion operators
1732a4a6fecf0b8c92223f8fdf19545b564b7d3fcdeJay Foad    /// @{
1742a4a6fecf0b8c92223f8fdf19545b564b7d3fcdeJay Foad    operator std::vector<T>() const {
1752a4a6fecf0b8c92223f8fdf19545b564b7d3fcdeJay Foad      return std::vector<T>(Data, Data+Length);
1762a4a6fecf0b8c92223f8fdf19545b564b7d3fcdeJay Foad    }
177fced2945995b4fd8f28f7dec9fcb5a6ab2e2798dJakub Staszak
1782a4a6fecf0b8c92223f8fdf19545b564b7d3fcdeJay Foad    /// @}
1792b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  };
180c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel
18146ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  /// MutableArrayRef - Represent a mutable reference to an array (0 or more
18246ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  /// elements consecutively in memory), i.e. a start pointer and a length.  It
18346ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  /// allows various APIs to take and modify consecutive elements easily and
18446ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  /// conveniently.
18546ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  ///
18646ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  /// This class does not own the underlying data, it is expected to be used in
18746ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  /// situations where the data resides in some other buffer, whose lifetime
18846ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  /// extends past that of the MutableArrayRef. For this reason, it is not in
18946ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  /// general safe to store a MutableArrayRef.
19046ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  ///
19146ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  /// This is intended to be trivially copyable, so it should be passed by
19246ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  /// value.
19346ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  template<typename T>
19446ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  class MutableArrayRef : public ArrayRef<T> {
19546ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  public:
19646ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    typedef T *iterator;
19746ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner
19890b81731c1a9bc126d0b29321b3513c9b85f8414Bill Wendling    typedef std::reverse_iterator<iterator> reverse_iterator;
19990b81731c1a9bc126d0b29321b3513c9b85f8414Bill Wendling
2005c332dbd30d9398ed25b30c3080506f7b8e92290Dmitri Gribenko    /// Construct an empty MutableArrayRef.
20146ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
2022f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
2035c332dbd30d9398ed25b30c3080506f7b8e92290Dmitri Gribenko    /// Construct an empty MutableArrayRef from None.
2045c332dbd30d9398ed25b30c3080506f7b8e92290Dmitri Gribenko    /*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {}
2055c332dbd30d9398ed25b30c3080506f7b8e92290Dmitri Gribenko
20646ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// Construct an MutableArrayRef from a single element.
20746ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
2082f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
20946ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// Construct an MutableArrayRef from a pointer and length.
21046ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /*implicit*/ MutableArrayRef(T *data, size_t length)
21146ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      : ArrayRef<T>(data, length) {}
2122f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
21346ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// Construct an MutableArrayRef from a range.
21446ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
2152f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
21646ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// Construct an MutableArrayRef from a SmallVector.
21746ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
21846ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    : ArrayRef<T>(Vec) {}
2192f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
22046ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// Construct a MutableArrayRef from a std::vector.
22146ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /*implicit*/ MutableArrayRef(std::vector<T> &Vec)
22246ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    : ArrayRef<T>(Vec) {}
2232f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
22446ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// Construct an MutableArrayRef from a C array.
22546ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    template <size_t N>
226dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    /*implicit*/ LLVM_CONSTEXPR MutableArrayRef(T (&Arr)[N])
22746ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      : ArrayRef<T>(Arr) {}
2282f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
22946ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
23046ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner
23146ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    iterator begin() const { return data(); }
23246ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    iterator end() const { return data() + this->size(); }
2332f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
23490b81731c1a9bc126d0b29321b3513c9b85f8414Bill Wendling    reverse_iterator rbegin() const { return reverse_iterator(end()); }
23590b81731c1a9bc126d0b29321b3513c9b85f8414Bill Wendling    reverse_iterator rend() const { return reverse_iterator(begin()); }
23690b81731c1a9bc126d0b29321b3513c9b85f8414Bill Wendling
23746ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// front - Get the first element.
23846ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    T &front() const {
23946ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      assert(!this->empty());
24046ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      return data()[0];
24146ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    }
2422f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
24346ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// back - Get the last element.
24446ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    T &back() const {
24546ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      assert(!this->empty());
24646ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      return data()[this->size()-1];
24746ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    }
24846ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner
24946ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// slice(n) - Chop off the first N elements of the array.
25046ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    MutableArrayRef<T> slice(unsigned N) const {
25146ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      assert(N <= this->size() && "Invalid specifier");
25246ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      return MutableArrayRef<T>(data()+N, this->size()-N);
25346ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    }
2542f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
25546ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// slice(n, m) - Chop off the first N elements of the array, and keep M
25646ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// elements in the array.
25746ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    MutableArrayRef<T> slice(unsigned N, unsigned M) const {
25846ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      assert(N+M <= this->size() && "Invalid specifier");
25946ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      return MutableArrayRef<T>(data()+N, M);
26046ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    }
2612f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
26246ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// @}
26346ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// @name Operator Overloads
26446ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    /// @{
26546ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    T &operator[](size_t Index) const {
26646ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      assert(Index < this->size() && "Invalid index!");
26746ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner      return data()[Index];
26846ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner    }
26946ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner  };
27046ada15d425c0f075853adff14927bbfc7fc39dcChris Lattner
271c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  /// @name ArrayRef Convenience constructors
272c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  /// @{
273c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel
274c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  /// Construct an ArrayRef from a single element.
275c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  template<typename T>
276c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  ArrayRef<T> makeArrayRef(const T &OneElt) {
277c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel    return OneElt;
278c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  }
279c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel
280c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  /// Construct an ArrayRef from a pointer and length.
281c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  template<typename T>
282c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  ArrayRef<T> makeArrayRef(const T *data, size_t length) {
283c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel    return ArrayRef<T>(data, length);
284c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  }
285c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel
286c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  /// Construct an ArrayRef from a range.
287c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  template<typename T>
288c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
289c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel    return ArrayRef<T>(begin, end);
290c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  }
291c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel
292c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  /// Construct an ArrayRef from a SmallVector.
293c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  template <typename T>
294c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
295c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel    return Vec;
296c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  }
297c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel
298c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  /// Construct an ArrayRef from a SmallVector.
299c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  template <typename T, unsigned N>
300c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
301c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel    return Vec;
302c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  }
303c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel
304c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  /// Construct an ArrayRef from a std::vector.
305c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  template<typename T>
306c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
307c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel    return Vec;
308c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  }
309c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel
310c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  /// Construct an ArrayRef from a C array.
311c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  template<typename T, size_t N>
312c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
313f6275309994dea2ec852c1f539875ae643646ec5Frits van Bommel    return ArrayRef<T>(Arr);
314c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  }
315c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel
316c48e1ef0e22b4113dd4dd48c5b170a19fe4d0188Frits van Bommel  /// @}
3175d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad  /// @name ArrayRef Comparison Operators
3185d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad  /// @{
3195d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad
3205d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad  template<typename T>
3215d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad  inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
3225d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad    return LHS.equals(RHS);
3235d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad  }
3245d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad
3255d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad  template<typename T>
3265d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad  inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
3275d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad    return !(LHS == RHS);
3285d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad  }
3295d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad
3305d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad  /// @}
3315d4f9909c49d28db9572acc4513c1a695b0c53daJay Foad
3322b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  // ArrayRefs can be treated like a POD type.
3332b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  template <typename T> struct isPodLike;
3342b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  template <typename T> struct isPodLike<ArrayRef<T> > {
3352b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    static const bool value = true;
3362b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  };
3372b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner}
3382f0a4e1aadfa227ed2565e532f0d1a3cf8e8efa5Andrew Trick
3392b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner#endif
340