ArrayRef.h revision 715c80a00b965f19ca2c7dacbc2f809221cc2730
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
132b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner#include "llvm/ADT/SmallVector.h"
142b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner#include <vector>
152b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
162b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattnernamespace llvm {
172b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  class APInt;
182b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
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;
362b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
372b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  private:
382b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// The start of the array, in an external buffer.
392b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    const T *Data;
402b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
412b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// The number of elements.
422b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    size_t Length;
432b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
442b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  public:
452b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @name Constructors
462b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @{
472b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
482b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// Construct an empty ArrayRef.
492b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /*implicit*/ ArrayRef() : Data(0), Length(0) {}
502b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
512b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// Construct an ArrayRef from a single element.
522b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /*implicit*/ ArrayRef(const T &OneElt)
532b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      : Data(&OneElt), Length(1) {}
542b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
552b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// Construct an ArrayRef from a pointer and length.
5604df049014396fe97a31bf3fa8951201b2ed8ffeChris Lattner    /*implicit*/ ArrayRef(const T *data, size_t length)
572b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      : Data(data), Length(length) {}
582b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
592b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// Construct an ArrayRef from a SmallVector.
602b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec)
612b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      : Data(Vec.data()), Length(Vec.size()) {}
622b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
632b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// Construct an ArrayRef from a std::vector.
642b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /*implicit*/ ArrayRef(const std::vector<T> &Vec)
652b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
662b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
67438208e8cb29c67b2177619a339b84291729b6b7Frits van Bommel    /// Construct an ArrayRef from a C array.
68438208e8cb29c67b2177619a339b84291729b6b7Frits van Bommel    template <size_t N>
69438208e8cb29c67b2177619a339b84291729b6b7Frits van Bommel    /*implicit*/ ArrayRef(const T (&Arr)[N])
70438208e8cb29c67b2177619a339b84291729b6b7Frits van Bommel      : Data(Arr), Length(N) {}
712b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
722b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @}
732b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @name Simple Operations
742b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @{
752b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
762b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    iterator begin() const { return Data; }
772b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    iterator end() const { return Data + Length; }
782b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
7904b2f0d99feb9cdf87eb8f35483816d757d170ddChris Lattner    /// empty - Check if the array is empty.
802b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    bool empty() const { return Length == 0; }
812b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
82878ad7afa512ef300d5df4e7ca0189775342dfc2Chris Lattner    const T *data() const { return Data; }
83878ad7afa512ef300d5df4e7ca0189775342dfc2Chris Lattner
8404b2f0d99feb9cdf87eb8f35483816d757d170ddChris Lattner    /// size - Get the array size.
852b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    size_t size() const { return Length; }
862b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
872b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// front - Get the first element.
882b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    const T &front() const {
892b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      assert(!empty());
902b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      return Data[0];
912b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    }
922b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
9304df049014396fe97a31bf3fa8951201b2ed8ffeChris Lattner    /// back - Get the last element.
942b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    const T &back() const {
952b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      assert(!empty());
962b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      return Data[Length-1];
972b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    }
982b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
99fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    /// slice(n) - Chop off the first N elements of the array.
100fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    ArrayRef<T> slice(unsigned N) {
101fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner      assert(N <= size() && "Invalid specifier");
102fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner      return ArrayRef<T>(data()+N, size()-N);
103fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    }
104fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner
105fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    /// slice(n, m) - Chop off the first N elements of the array, and keep M
106fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    /// elements in the array.
107fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    ArrayRef<T> slice(unsigned N, unsigned M) {
108fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner      assert(N+M <= size() && "Invalid specifier");
109fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner      return ArrayRef<T>(data()+N, M);
110fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner    }
111fa09685a9aa17dbdd4c72ad032684debb25feb0bChris Lattner
1122b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @}
1132b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @name Operator Overloads
1142b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @{
11504df049014396fe97a31bf3fa8951201b2ed8ffeChris Lattner    const T &operator[](size_t Index) const {
1162b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      assert(Index < Length && "Invalid index!");
1172b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      return Data[Index];
1182b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    }
1192b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
1202b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @}
1212b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @name Expensive Operations
1222b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @{
1232b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    std::vector<T> vec() const {
1242b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner      return std::vector<T>(Data, Data+Length);
1252b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    }
1262b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
1272b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    /// @}
1282b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  };
1292b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
1302b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  // ArrayRefs can be treated like a POD type.
1312b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  template <typename T> struct isPodLike;
1322b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  template <typename T> struct isPodLike<ArrayRef<T> > {
1332b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner    static const bool value = true;
1342b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner  };
1352b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner}
1362b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner
1372b9bc422a5e6840f5b925316bc06d5943deb610aChris Lattner#endif
138