Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
8.9 KiB

  1. //===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef LLVM_ADT_ARRAYREF_H
  10. #define LLVM_ADT_ARRAYREF_H
  11. #include "llvm/ADT/SmallVector.h"
  12. #include <vector>
  13. namespace llvm {
  14. /// ArrayRef - Represent a constant reference to an array (0 or more elements
  15. /// consecutively in memory), i.e. a start pointer and a length. It allows
  16. /// various APIs to take consecutive elements easily and conveniently.
  17. ///
  18. /// This class does not own the underlying data, it is expected to be used in
  19. /// situations where the data resides in some other buffer, whose lifetime
  20. /// extends past that of the ArrayRef. For this reason, it is not in general
  21. /// safe to store an ArrayRef.
  22. ///
  23. /// This is intended to be trivially copyable, so it should be passed by
  24. /// value.
  25. template<typename T>
  26. class ArrayRef {
  27. public:
  28. typedef const T *iterator;
  29. typedef const T *const_iterator;
  30. typedef size_t size_type;
  31. typedef std::reverse_iterator<iterator> reverse_iterator;
  32. private:
  33. /// The start of the array, in an external buffer.
  34. const T *Data;
  35. /// The number of elements.
  36. size_type Length;
  37. public:
  38. /// @name Constructors
  39. /// @{
  40. /// Construct an empty ArrayRef.
  41. /*implicit*/ ArrayRef() : Data(0), Length(0) {}
  42. /// Construct an ArrayRef from a single element.
  43. /*implicit*/ ArrayRef(const T &OneElt)
  44. : Data(&OneElt), Length(1) {}
  45. /// Construct an ArrayRef from a pointer and length.
  46. /*implicit*/ ArrayRef(const T *data, size_t length)
  47. : Data(data), Length(length) {}
  48. /// Construct an ArrayRef from a range.
  49. ArrayRef(const T *begin, const T *end)
  50. : Data(begin), Length(end - begin) {}
  51. /// Construct an ArrayRef from a SmallVector. This is templated in order to
  52. /// avoid instantiating SmallVectorTemplateCommon<T> whenever we
  53. /// copy-construct an ArrayRef.
  54. template<typename U>
  55. /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec)
  56. : Data(Vec.data()), Length(Vec.size()) {
  57. }
  58. /// Construct an ArrayRef from a std::vector.
  59. template<typename A>
  60. /*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
  61. : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
  62. /// Construct an ArrayRef from a C array.
  63. template <size_t N>
  64. /*implicit*/ ArrayRef(const T (&Arr)[N])
  65. : Data(Arr), Length(N) {}
  66. /// @}
  67. /// @name Simple Operations
  68. /// @{
  69. iterator begin() const { return Data; }
  70. iterator end() const { return Data + Length; }
  71. reverse_iterator rbegin() const { return reverse_iterator(end()); }
  72. reverse_iterator rend() const { return reverse_iterator(begin()); }
  73. /// empty - Check if the array is empty.
  74. bool empty() const { return Length == 0; }
  75. const T *data() const { return Data; }
  76. /// size - Get the array size.
  77. size_t size() const { return Length; }
  78. /// front - Get the first element.
  79. const T &front() const {
  80. assert(!empty());
  81. return Data[0];
  82. }
  83. /// back - Get the last element.
  84. const T &back() const {
  85. assert(!empty());
  86. return Data[Length-1];
  87. }
  88. /// equals - Check for element-wise equality.
  89. bool equals(ArrayRef RHS) const {
  90. if (Length != RHS.Length)
  91. return false;
  92. for (size_type i = 0; i != Length; i++)
  93. if (Data[i] != RHS.Data[i])
  94. return false;
  95. return true;
  96. }
  97. /// slice(n) - Chop off the first N elements of the array.
  98. ArrayRef<T> slice(unsigned N) const {
  99. assert(N <= size() && "Invalid specifier");
  100. return ArrayRef<T>(data()+N, size()-N);
  101. }
  102. /// slice(n, m) - Chop off the first N elements of the array, and keep M
  103. /// elements in the array.
  104. ArrayRef<T> slice(unsigned N, unsigned M) const {
  105. assert(N+M <= size() && "Invalid specifier");
  106. return ArrayRef<T>(data()+N, M);
  107. }
  108. /// @}
  109. /// @name Operator Overloads
  110. /// @{
  111. const T &operator[](size_t Index) const {
  112. assert(Index < Length && "Invalid index!");
  113. return Data[Index];
  114. }
  115. /// @}
  116. /// @name Expensive Operations
  117. /// @{
  118. std::vector<T> vec() const {
  119. return std::vector<T>(Data, Data+Length);
  120. }
  121. /// @}
  122. /// @name Conversion operators
  123. /// @{
  124. operator std::vector<T>() const {
  125. return std::vector<T>(Data, Data+Length);
  126. }
  127. /// @}
  128. };
  129. /// MutableArrayRef - Represent a mutable reference to an array (0 or more
  130. /// elements consecutively in memory), i.e. a start pointer and a length. It
  131. /// allows various APIs to take and modify consecutive elements easily and
  132. /// conveniently.
  133. ///
  134. /// This class does not own the underlying data, it is expected to be used in
  135. /// situations where the data resides in some other buffer, whose lifetime
  136. /// extends past that of the MutableArrayRef. For this reason, it is not in
  137. /// general safe to store a MutableArrayRef.
  138. ///
  139. /// This is intended to be trivially copyable, so it should be passed by
  140. /// value.
  141. template<typename T>
  142. class MutableArrayRef : public ArrayRef<T> {
  143. public:
  144. typedef T *iterator;
  145. /// Construct an empty ArrayRef.
  146. /*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
  147. /// Construct an MutableArrayRef from a single element.
  148. /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
  149. /// Construct an MutableArrayRef from a pointer and length.
  150. /*implicit*/ MutableArrayRef(T *data, size_t length)
  151. : ArrayRef<T>(data, length) {}
  152. /// Construct an MutableArrayRef from a range.
  153. MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
  154. /// Construct an MutableArrayRef from a SmallVector.
  155. /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
  156. : ArrayRef<T>(Vec) {}
  157. /// Construct a MutableArrayRef from a std::vector.
  158. /*implicit*/ MutableArrayRef(std::vector<T> &Vec)
  159. : ArrayRef<T>(Vec) {}
  160. /// Construct an MutableArrayRef from a C array.
  161. template <size_t N>
  162. /*implicit*/ MutableArrayRef(T (&Arr)[N])
  163. : ArrayRef<T>(Arr) {}
  164. T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
  165. iterator begin() const { return data(); }
  166. iterator end() const { return data() + this->size(); }
  167. /// front - Get the first element.
  168. T &front() const {
  169. assert(!this->empty());
  170. return data()[0];
  171. }
  172. /// back - Get the last element.
  173. T &back() const {
  174. assert(!this->empty());
  175. return data()[this->size()-1];
  176. }
  177. /// slice(n) - Chop off the first N elements of the array.
  178. MutableArrayRef<T> slice(unsigned N) const {
  179. assert(N <= this->size() && "Invalid specifier");
  180. return MutableArrayRef<T>(data()+N, this->size()-N);
  181. }
  182. /// slice(n, m) - Chop off the first N elements of the array, and keep M
  183. /// elements in the array.
  184. MutableArrayRef<T> slice(unsigned N, unsigned M) const {
  185. assert(N+M <= this->size() && "Invalid specifier");
  186. return MutableArrayRef<T>(data()+N, M);
  187. }
  188. /// @}
  189. /// @name Operator Overloads
  190. /// @{
  191. T &operator[](size_t Index) const {
  192. assert(Index < this->size() && "Invalid index!");
  193. return data()[Index];
  194. }
  195. };
  196. /// @name ArrayRef Convenience constructors
  197. /// @{
  198. /// Construct an ArrayRef from a single element.
  199. template<typename T>
  200. ArrayRef<T> makeArrayRef(const T &OneElt) {
  201. return OneElt;
  202. }
  203. /// Construct an ArrayRef from a pointer and length.
  204. template<typename T>
  205. ArrayRef<T> makeArrayRef(const T *data, size_t length) {
  206. return ArrayRef<T>(data, length);
  207. }
  208. /// Construct an ArrayRef from a range.
  209. template<typename T>
  210. ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
  211. return ArrayRef<T>(begin, end);
  212. }
  213. /// Construct an ArrayRef from a SmallVector.
  214. template <typename T>
  215. ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
  216. return Vec;
  217. }
  218. /// Construct an ArrayRef from a SmallVector.
  219. template <typename T, unsigned N>
  220. ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
  221. return Vec;
  222. }
  223. /// Construct an ArrayRef from a std::vector.
  224. template<typename T>
  225. ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
  226. return Vec;
  227. }
  228. /// Construct an ArrayRef from a C array.
  229. template<typename T, size_t N>
  230. ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
  231. return ArrayRef<T>(Arr);
  232. }
  233. /// @}
  234. /// @name ArrayRef Comparison Operators
  235. /// @{
  236. template<typename T>
  237. inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
  238. return LHS.equals(RHS);
  239. }
  240. template<typename T>
  241. inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
  242. return !(LHS == RHS);
  243. }
  244. /// @}
  245. // ArrayRefs can be treated like a POD type.
  246. template <typename T> struct isPodLike;
  247. template <typename T> struct isPodLike<ArrayRef<T> > {
  248. static const bool value = true;
  249. };
  250. }
  251. #endif