ArrayRef.h revision 04df049014396fe97a31bf3fa8951201b2ed8ffe
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef LLVM_ADT_ARRAYREF_H
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LLVM_ADT_ARRAYREF_H
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "llvm/ADT/SmallVector.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace llvm {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class APInt;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// ArrayRef - Represent a constant reference to an array (0 or more elements
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// consecutively in memory), i.e. a start pointer and a length.  It allows
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// various APIs to take consecutive elements easily and conveniently.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ///
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// This class does not own the underlying data, it is expected to be used in
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// situations where the data resides in some other buffer, whose lifetime
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// extends past that of the StringRef. For this reason, it is not in general
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// safe to store a ArrayRef.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ///
28b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  /// This is intended to be trivially copyable, so it should be passed by
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// value.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename T>
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class ArrayRef {
32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  public:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef const T *iterator;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef const T *const_iterator;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef size_t size_type;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  private:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// The start of the array, in an external buffer.
39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const T *Data;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// The number of elements.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t Length;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public:
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// @name Constructors
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// @{
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// Construct an empty ArrayRef.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*implicit*/ ArrayRef() : Data(0), Length(0) {}
50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// Construct an ArrayRef from a single element.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*implicit*/ ArrayRef(const T &OneElt)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : Data(&OneElt), Length(1) {}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /// Construct an ArrayRef from a pointer and length.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*implicit*/ ArrayRef(const T *data, size_t length)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : Data(data), Length(length) {}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// Construct an ArrayRef from a SmallVector.
60b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    /*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : Data(Vec.data()), Length(Vec.size()) {}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// Construct an ArrayRef from a std::vector.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*implicit*/ ArrayRef(const std::vector<T> &Vec)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO: C arrays.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// @}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// @name Simple Operations
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// @{
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    iterator begin() const { return Data; }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iterator end() const { return Data + Length; }
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// empty - Check if the string is empty.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool empty() const { return Length == 0; }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// size - Get the string size.
80b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    size_t size() const { return Length; }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// front - Get the first element.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const T &front() const {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(!empty());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return Data[0];
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    /// back - Get the last element.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const T &back() const {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(!empty());
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return Data[Length-1];
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /// @}
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /// @name Operator Overloads
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /// @{
97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const T &operator[](size_t Index) const {
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      assert(Index < Length && "Invalid index!");
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return Data[Index];
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /// @}
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /// @name Expensive Operations
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /// @{
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<T> vec() const {
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return std::vector<T>(Data, Data+Length);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /// @}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ArrayRefs can be treated like a POD type.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename T> struct isPodLike;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename T> struct isPodLike<ArrayRef<T> > {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const bool value = true;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)