#ifndef LLVM_ADT_ARRAYREF_H
#define LLVM_ADT_ARRAYREF_H
#include "llvm/ADT/SmallVector.h"
#include <vector>
namespace llvm {
class APInt;
template<typename T>
class ArrayRef {
public:
typedef const T *iterator;
typedef const T *const_iterator;
typedef size_t size_type;
private:
const T *Data;
size_type Length;
public:
ArrayRef() : Data(0), Length(0) {}
ArrayRef(const T &OneElt)
: Data(&OneElt), Length(1) {}
ArrayRef(const T *data, size_t length)
: Data(data), Length(length) {}
ArrayRef(const T *begin, const T *end)
: Data(begin), Length(end - begin) {}
ArrayRef(const SmallVectorImpl<T> &Vec)
: Data(Vec.data()), Length(Vec.size()) {}
ArrayRef(const std::vector<T> &Vec)
: Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
template <size_t N>
ArrayRef(const T (&Arr)[N])
: Data(Arr), Length(N) {}
iterator begin() const { return Data; }
iterator end() const { return Data + Length; }
bool empty() const { return Length == 0; }
const T *data() const { return Data; }
size_t size() const { return Length; }
const T &front() const {
assert(!empty());
return Data[0];
}
const T &back() const {
assert(!empty());
return Data[Length-1];
}
bool equals(ArrayRef RHS) const {
if (Length != RHS.Length)
return false;
for (size_type i = 0; i != Length; i++)
if (Data[i] != RHS.Data[i])
return false;
return true;
}
ArrayRef<T> slice(unsigned N) {
assert(N <= size() && "Invalid specifier");
return ArrayRef<T>(data()+N, size()-N);
}
ArrayRef<T> slice(unsigned N, unsigned M) {
assert(N+M <= size() && "Invalid specifier");
return ArrayRef<T>(data()+N, M);
}
const T &operator[](size_t Index) const {
assert(Index < Length && "Invalid index!");
return Data[Index];
}
std::vector<T> vec() const {
return std::vector<T>(Data, Data+Length);
}
operator std::vector<T>() const {
return std::vector<T>(Data, Data+Length);
}
};
template<typename T>
ArrayRef<T> makeArrayRef(const T &OneElt) {
return OneElt;
}
template<typename T>
ArrayRef<T> makeArrayRef(const T *data, size_t length) {
return ArrayRef<T>(data, length);
}
template<typename T>
ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
return ArrayRef<T>(begin, end);
}
template <typename T>
ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
return Vec;
}
template <typename T, unsigned N>
ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
return Vec;
}
template<typename T>
ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
return Vec;
}
template<typename T, size_t N>
ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
return ArrayRef<T>(Arr);
}
template<typename T>
inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
return LHS.equals(RHS);
}
template<typename T>
inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
return !(LHS == RHS);
}
template <typename T> struct isPodLike;
template <typename T> struct isPodLike<ArrayRef<T> > {
static const bool value = true;
};
}
#endif