17ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===// 27ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 37ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// The LLVM Compiler Infrastructure 47ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 57ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// This file is distributed under the University of Illinois Open Source 67ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// License. See LICENSE.TXT for details. 77ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 87ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----------------------------------------------------------------------===// 97ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#ifndef LLVM_ADT_ARRAYREF_H 117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#define LLVM_ADT_ARRAYREF_H 127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/ADT/Hashing.h" 147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/ADT/None.h" 152df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include "llvm/ADT/STLExtras.h" 167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/ADT/SmallVector.h" 177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include <array> 187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include <vector> 197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensnamespace llvm { 217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// ArrayRef - Represent a constant reference to an array (0 or more elements 227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// consecutively in memory), i.e. a start pointer and a length. It allows 237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// various APIs to take consecutive elements easily and conveniently. 247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// 257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// This class does not own the underlying data, it is expected to be used in 267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// situations where the data resides in some other buffer, whose lifetime 277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// extends past that of the ArrayRef. For this reason, it is not in general 287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// safe to store an ArrayRef. 297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// 307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// This is intended to be trivially copyable, so it should be passed by 317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// value. 327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename T> 332df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens class LLVM_NODISCARD ArrayRef { 347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens public: 357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef const T *iterator; 367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef const T *const_iterator; 377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef size_t size_type; 387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef std::reverse_iterator<iterator> reverse_iterator; 407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens private: 427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// The start of the array, in an external buffer. 437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const T *Data; 447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// The number of elements. 467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens size_type Length; 477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens public: 497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @name Constructors 507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @{ 517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an empty ArrayRef. 537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ ArrayRef() : Data(nullptr), Length(0) {} 547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an empty ArrayRef from None. 567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ ArrayRef(NoneType) : Data(nullptr), Length(0) {} 577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a single element. 597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ ArrayRef(const T &OneElt) 607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : Data(&OneElt), Length(1) {} 617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a pointer and length. 637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ ArrayRef(const T *data, size_t length) 647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : Data(data), Length(length) {} 657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a range. 677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef(const T *begin, const T *end) 687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : Data(begin), Length(end - begin) {} 697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a SmallVector. This is templated in order to 717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// avoid instantiating SmallVectorTemplateCommon<T> whenever we 727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// copy-construct an ArrayRef. 737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename U> 747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec) 757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : Data(Vec.data()), Length(Vec.size()) { 767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a std::vector. 797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename A> 807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ ArrayRef(const std::vector<T, A> &Vec) 817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : Data(Vec.data()), Length(Vec.size()) {} 827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a std::array 847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <size_t N> 852df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /*implicit*/ constexpr ArrayRef(const std::array<T, N> &Arr) 862df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens : Data(Arr.data()), Length(N) {} 877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a C array. 897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <size_t N> 902df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /*implicit*/ constexpr ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {} 917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a std::initializer_list. 937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec) 947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : Data(Vec.begin() == Vec.end() ? (T*)nullptr : Vec.begin()), 957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Length(Vec.size()) {} 967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef<const T*> from ArrayRef<T*>. This uses SFINAE to 987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// ensure that only ArrayRefs of pointers can be converted. 997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename U> 1007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef( 1017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const ArrayRef<U *> &A, 1027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename std::enable_if< 1037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::is_convertible<U *const *, T const *>::value>::type * = nullptr) 1047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : Data(A.data()), Length(A.size()) {} 1057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef<const T*> from a SmallVector<T*>. This is 1077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// templated in order to avoid instantiating SmallVectorTemplateCommon<T> 1087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// whenever we copy-construct an ArrayRef. 1097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename U, typename DummyT> 1107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ ArrayRef( 1117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const SmallVectorTemplateCommon<U *, DummyT> &Vec, 1127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename std::enable_if< 1137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::is_convertible<U *const *, T const *>::value>::type * = nullptr) 1147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : Data(Vec.data()), Length(Vec.size()) { 1157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef<const T*> from std::vector<T*>. This uses SFINAE 1187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// to ensure that only vectors of pointers can be converted. 1197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename U, typename A> 1207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef(const std::vector<U *, A> &Vec, 1217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename std::enable_if< 1227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::is_convertible<U *const *, T const *>::value>::type* = 0) 1237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : Data(Vec.data()), Length(Vec.size()) {} 1247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @} 1267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @name Simple Operations 1277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @{ 1287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens iterator begin() const { return Data; } 1307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens iterator end() const { return Data + Length; } 1317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens reverse_iterator rbegin() const { return reverse_iterator(end()); } 1337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens reverse_iterator rend() const { return reverse_iterator(begin()); } 1347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// empty - Check if the array is empty. 1367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool empty() const { return Length == 0; } 1377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const T *data() const { return Data; } 1397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// size - Get the array size. 1417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens size_t size() const { return Length; } 1427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// front - Get the first element. 1447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const T &front() const { 1457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(!empty()); 1467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Data[0]; 1477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// back - Get the last element. 1507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const T &back() const { 1517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(!empty()); 1527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Data[Length-1]; 1537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // copy - Allocate copy in Allocator and return ArrayRef<T> to it. 1567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename Allocator> ArrayRef<T> copy(Allocator &A) { 1577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens T *Buff = A.template Allocate<T>(Length); 1587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::uninitialized_copy(begin(), end(), Buff); 1597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return ArrayRef<T>(Buff, Length); 1607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// equals - Check for element-wise equality. 1637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool equals(ArrayRef RHS) const { 1647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (Length != RHS.Length) 1657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return false; 1667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return std::equal(begin(), end(), RHS.begin()); 1677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// slice(n, m) - Chop off the first N elements of the array, and keep M 1707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// elements in the array. 1717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> slice(size_t N, size_t M) const { 1727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(N+M <= size() && "Invalid specifier"); 1737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return ArrayRef<T>(data()+N, M); 1747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1762df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// slice(n) - Chop off the first N elements of the array. 1772df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens ArrayRef<T> slice(size_t N) const { return slice(N, size() - N); } 1782df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 1797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Drop the first \p N elements of the array. 1807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> drop_front(size_t N = 1) const { 1817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(size() >= N && "Dropping more elements than exist"); 1827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return slice(N, size() - N); 1837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Drop the last \p N elements of the array. 1867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> drop_back(size_t N = 1) const { 1877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(size() >= N && "Dropping more elements than exist"); 1887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return slice(0, size() - N); 1897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1912df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// \brief Return a copy of *this with the first N elements satisfying the 1922df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// given predicate removed. 1932df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <class PredicateT> ArrayRef<T> drop_while(PredicateT Pred) const { 1942df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return ArrayRef<T>(find_if_not(*this, Pred), end()); 1952df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens } 1962df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 1972df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// \brief Return a copy of *this with the first N elements not satisfying 1982df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// the given predicate removed. 1992df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <class PredicateT> ArrayRef<T> drop_until(PredicateT Pred) const { 2002df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return ArrayRef<T>(find_if(*this, Pred), end()); 2012df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens } 2022df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 2037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Return a copy of *this with only the first \p N elements. 2047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> take_front(size_t N = 1) const { 2057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (N >= size()) 2067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 2077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return drop_back(size() - N); 2087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Return a copy of *this with only the last \p N elements. 2117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> take_back(size_t N = 1) const { 2127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (N >= size()) 2137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 2147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return drop_front(size() - N); 2157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2172df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// \brief Return the first N elements of this Array that satisfy the given 2182df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// predicate. 2192df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <class PredicateT> ArrayRef<T> take_while(PredicateT Pred) const { 2202df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return ArrayRef<T>(begin(), find_if_not(*this, Pred)); 2212df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens } 2222df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 2232df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// \brief Return the first N elements of this Array that don't satisfy the 2242df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// given predicate. 2252df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <class PredicateT> ArrayRef<T> take_until(PredicateT Pred) const { 2262df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return ArrayRef<T>(begin(), find_if(*this, Pred)); 2272df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens } 2282df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 2297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @} 2307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @name Operator Overloads 2317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @{ 2327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const T &operator[](size_t Index) const { 2337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(Index < Length && "Invalid index!"); 2347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Data[Index]; 2357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2372df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// Disallow accidental assignment from a temporary. 2382df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// 2392df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// The declaration here is extra complicated so that "arrayRef = {}" 2402df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// continues to select the move assignment operator. 2412df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <typename U> 2422df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type & 2432df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens operator=(U &&Temporary) = delete; 2442df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 2452df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// Disallow accidental assignment from a temporary. 2462df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// 2472df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// The declaration here is extra complicated so that "arrayRef = {}" 2482df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// continues to select the move assignment operator. 2492df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <typename U> 2502df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type & 2512df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens operator=(std::initializer_list<U>) = delete; 2522df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 2537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @} 2547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @name Expensive Operations 2557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @{ 2567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::vector<T> vec() const { 2577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return std::vector<T>(Data, Data+Length); 2587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @} 2617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @name Conversion operators 2627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @{ 2637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens operator std::vector<T>() const { 2647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return std::vector<T>(Data, Data+Length); 2657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @} 2687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens }; 2697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// MutableArrayRef - Represent a mutable reference to an array (0 or more 2717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// elements consecutively in memory), i.e. a start pointer and a length. It 2727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// allows various APIs to take and modify consecutive elements easily and 2737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// conveniently. 2747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// 2757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// This class does not own the underlying data, it is expected to be used in 2767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// situations where the data resides in some other buffer, whose lifetime 2777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// extends past that of the MutableArrayRef. For this reason, it is not in 2787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// general safe to store a MutableArrayRef. 2797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// 2807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// This is intended to be trivially copyable, so it should be passed by 2817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// value. 2827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename T> 2832df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens class LLVM_NODISCARD MutableArrayRef : public ArrayRef<T> { 2847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens public: 2857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef T *iterator; 2867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef std::reverse_iterator<iterator> reverse_iterator; 2887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an empty MutableArrayRef. 2907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ MutableArrayRef() : ArrayRef<T>() {} 2917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an empty MutableArrayRef from None. 2937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {} 2947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an MutableArrayRef from a single element. 2967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {} 2977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an MutableArrayRef from a pointer and length. 2997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ MutableArrayRef(T *data, size_t length) 3007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : ArrayRef<T>(data, length) {} 3017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an MutableArrayRef from a range. 3037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {} 3047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an MutableArrayRef from a SmallVector. 3067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec) 3077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : ArrayRef<T>(Vec) {} 3087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct a MutableArrayRef from a std::vector. 3107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /*implicit*/ MutableArrayRef(std::vector<T> &Vec) 3117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : ArrayRef<T>(Vec) {} 3127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a std::array 3147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <size_t N> 3152df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /*implicit*/ constexpr MutableArrayRef(std::array<T, N> &Arr) 3162df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens : ArrayRef<T>(Arr) {} 3177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an MutableArrayRef from a C array. 3197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <size_t N> 3202df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /*implicit*/ constexpr MutableArrayRef(T (&Arr)[N]) : ArrayRef<T>(Arr) {} 3217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens T *data() const { return const_cast<T*>(ArrayRef<T>::data()); } 3237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens iterator begin() const { return data(); } 3257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens iterator end() const { return data() + this->size(); } 3267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens reverse_iterator rbegin() const { return reverse_iterator(end()); } 3287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens reverse_iterator rend() const { return reverse_iterator(begin()); } 3297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// front - Get the first element. 3317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens T &front() const { 3327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(!this->empty()); 3337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return data()[0]; 3347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// back - Get the last element. 3377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens T &back() const { 3387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(!this->empty()); 3397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return data()[this->size()-1]; 3407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// slice(n, m) - Chop off the first N elements of the array, and keep M 3437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// elements in the array. 3447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MutableArrayRef<T> slice(size_t N, size_t M) const { 3452df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens assert(N + M <= this->size() && "Invalid specifier"); 3462df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return MutableArrayRef<T>(this->data() + N, M); 3472df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens } 3482df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 3492df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// slice(n) - Chop off the first N elements of the array. 3502df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens MutableArrayRef<T> slice(size_t N) const { 3512df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return slice(N, this->size() - N); 3527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Drop the first \p N elements of the array. 3557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MutableArrayRef<T> drop_front(size_t N = 1) const { 3567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(this->size() >= N && "Dropping more elements than exist"); 3577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return slice(N, this->size() - N); 3587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MutableArrayRef<T> drop_back(size_t N = 1) const { 3617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(this->size() >= N && "Dropping more elements than exist"); 3627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return slice(0, this->size() - N); 3637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3652df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// \brief Return a copy of *this with the first N elements satisfying the 3662df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// given predicate removed. 3672df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <class PredicateT> 3682df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens MutableArrayRef<T> drop_while(PredicateT Pred) const { 3692df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return MutableArrayRef<T>(find_if_not(*this, Pred), end()); 3702df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens } 3712df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 3722df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// \brief Return a copy of *this with the first N elements not satisfying 3732df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// the given predicate removed. 3742df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <class PredicateT> 3752df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens MutableArrayRef<T> drop_until(PredicateT Pred) const { 3762df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return MutableArrayRef<T>(find_if(*this, Pred), end()); 3772df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens } 3782df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 3797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Return a copy of *this with only the first \p N elements. 3807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MutableArrayRef<T> take_front(size_t N = 1) const { 3817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (N >= this->size()) 3827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 3837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return drop_back(this->size() - N); 3847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Return a copy of *this with only the last \p N elements. 3877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MutableArrayRef<T> take_back(size_t N = 1) const { 3887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (N >= this->size()) 3897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 3907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return drop_front(this->size() - N); 3917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3932df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// \brief Return the first N elements of this Array that satisfy the given 3942df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// predicate. 3952df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <class PredicateT> 3962df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens MutableArrayRef<T> take_while(PredicateT Pred) const { 3972df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return MutableArrayRef<T>(begin(), find_if_not(*this, Pred)); 3982df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens } 3992df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 4002df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// \brief Return the first N elements of this Array that don't satisfy the 4012df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// given predicate. 4022df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <class PredicateT> 4032df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens MutableArrayRef<T> take_until(PredicateT Pred) const { 4042df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return MutableArrayRef<T>(begin(), find_if(*this, Pred)); 4052df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens } 4062df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 4077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @} 4087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @name Operator Overloads 4097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @{ 4107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens T &operator[](size_t Index) const { 4117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(Index < this->size() && "Invalid index!"); 4127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return data()[Index]; 4137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens }; 4157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4162df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// This is a MutableArrayRef that owns its array. 4172df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <typename T> class OwningArrayRef : public MutableArrayRef<T> { 4182df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens public: 4192df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens OwningArrayRef() {} 4202df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens OwningArrayRef(size_t Size) : MutableArrayRef<T>(new T[Size], Size) {} 4212df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens OwningArrayRef(ArrayRef<T> Data) 4222df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens : MutableArrayRef<T>(new T[Data.size()], Data.size()) { 4232df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens std::copy(Data.begin(), Data.end(), this->begin()); 4242df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens } 4252df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens OwningArrayRef(OwningArrayRef &&Other) { *this = Other; } 4262df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens OwningArrayRef &operator=(OwningArrayRef &&Other) { 4272df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens delete[] this->data(); 4282df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens this->MutableArrayRef<T>::operator=(Other); 4292df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens Other.MutableArrayRef<T>::operator=(MutableArrayRef<T>()); 4302df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return *this; 4312df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens } 4322df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens ~OwningArrayRef() { delete[] this->data(); } 4332df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens }; 4342df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 4357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @name ArrayRef Convenience constructors 4367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @{ 4377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a single element. 4397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename T> 4407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> makeArrayRef(const T &OneElt) { 4417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return OneElt; 4427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a pointer and length. 4457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename T> 4467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> makeArrayRef(const T *data, size_t length) { 4477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return ArrayRef<T>(data, length); 4487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a range. 4517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename T> 4527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> makeArrayRef(const T *begin, const T *end) { 4537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return ArrayRef<T>(begin, end); 4547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a SmallVector. 4577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename T> 4587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) { 4597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Vec; 4607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a SmallVector. 4637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename T, unsigned N> 4647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) { 4657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Vec; 4667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a std::vector. 4697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename T> 4707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) { 4717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Vec; 4727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from an ArrayRef (no-op) (const) 4757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename T> ArrayRef<T> makeArrayRef(const ArrayRef<T> &Vec) { 4767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Vec; 4777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from an ArrayRef (no-op) 4807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename T> ArrayRef<T> &makeArrayRef(ArrayRef<T> &Vec) { 4817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Vec; 4827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Construct an ArrayRef from a C array. 4857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename T, size_t N> 4867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ArrayRef<T> makeArrayRef(const T (&Arr)[N]) { 4877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return ArrayRef<T>(Arr); 4887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @} 4917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @name ArrayRef Comparison Operators 4927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @{ 4937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename T> 4957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) { 4967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return LHS.equals(RHS); 4977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template<typename T> 5007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) { 5017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return !(LHS == RHS); 5027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 5037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// @} 5057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // ArrayRefs can be treated like a POD type. 5077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename T> struct isPodLike; 5087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename T> struct isPodLike<ArrayRef<T> > { 5097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static const bool value = true; 5107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens }; 5117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename T> hash_code hash_value(ArrayRef<T> S) { 5137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return hash_combine_range(S.begin(), S.end()); 5147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 5157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} // end namespace llvm 5167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif // LLVM_ADT_ARRAYREF_H 518