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