dynarray 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. // -*- C++ -*-
  2. //===-------------------------- dynarray ----------------------------------===//
  3. //
  4. // The LLVM Compiler Infrastructure
  5. //
  6. // This file is dual licensed under the MIT and the University of Illinois Open
  7. // Source Licenses. See LICENSE.TXT for details.
  8. //
  9. //===----------------------------------------------------------------------===//
  10. #ifndef _LIBCPP_DYNARRAY
  11. #define _LIBCPP_DYNARRAY
  12. #include <__config>
  13. #if _LIBCPP_STD_VER > 11
  14. /*
  15. dynarray synopsis
  16. namespace std { namespace experimental {
  17. template< typename T >
  18. class dynarray
  19. {
  20. // types:
  21. typedef T value_type;
  22. typedef T& reference;
  23. typedef const T& const_reference;
  24. typedef T* pointer;
  25. typedef const T* const_pointer;
  26. typedef implementation-defined iterator;
  27. typedef implementation-defined const_iterator;
  28. typedef reverse_iterator<iterator> reverse_iterator;
  29. typedef reverse_iterator<const_iterator> const_reverse_iterator;
  30. typedef size_t size_type;
  31. typedef ptrdiff_t difference_type;
  32. public:
  33. // construct/copy/destroy:
  34. explicit dynarray(size_type c);
  35. dynarray(size_type c, const T& v);
  36. dynarray(const dynarray& d);
  37. dynarray(initializer_list<T>);
  38. template <class Alloc>
  39. dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc);
  40. template <class Alloc>
  41. dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc);
  42. template <class Alloc>
  43. dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc);
  44. template <class Alloc>
  45. dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc);
  46. dynarray& operator=(const dynarray&) = delete;
  47. ~dynarray();
  48. // iterators:
  49. iterator begin() noexcept;
  50. const_iterator begin() const noexcept;
  51. const_iterator cbegin() const noexcept;
  52. iterator end() noexcept;
  53. const_iterator end() const noexcept;
  54. const_iterator cend() const noexcept;
  55. reverse_iterator rbegin() noexcept;
  56. const_reverse_iterator rbegin() const noexcept;
  57. const_reverse_iterator crbegin() const noexcept;
  58. reverse_iterator rend() noexcept;
  59. const_reverse_iterator rend() const noexcept;
  60. const_reverse_iterator crend() const noexcept;
  61. // capacity:
  62. size_type size() const noexcept;
  63. size_type max_size() const noexcept;
  64. bool empty() const noexcept;
  65. // element access:
  66. reference operator[](size_type n);
  67. const_reference operator[](size_type n) const;
  68. reference front();
  69. const_reference front() const;
  70. reference back();
  71. const_reference back() const;
  72. const_reference at(size_type n) const;
  73. reference at(size_type n);
  74. // data access:
  75. T* data() noexcept;
  76. const T* data() const noexcept;
  77. // mutating member functions:
  78. void fill(const T& v);
  79. };
  80. }} // std::experimental
  81. */
  82. #include <__functional_base>
  83. #include <iterator>
  84. #include <stdexcept>
  85. #include <initializer_list>
  86. #include <new>
  87. #include <algorithm>
  88. #include <__undef___deallocate>
  89. #if defined(_LIBCPP_NO_EXCEPTIONS)
  90. #include <cassert>
  91. #endif
  92. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  93. #pragma GCC system_header
  94. #endif
  95. namespace std { namespace experimental { inline namespace __array_extensions_v1 {
  96. template <class _Tp>
  97. struct _LIBCPP_TYPE_VIS_ONLY dynarray
  98. {
  99. public:
  100. // types:
  101. typedef dynarray __self;
  102. typedef _Tp value_type;
  103. typedef value_type& reference;
  104. typedef const value_type& const_reference;
  105. typedef value_type* iterator;
  106. typedef const value_type* const_iterator;
  107. typedef value_type* pointer;
  108. typedef const value_type* const_pointer;
  109. typedef size_t size_type;
  110. typedef ptrdiff_t difference_type;
  111. typedef std::reverse_iterator<iterator> reverse_iterator;
  112. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  113. private:
  114. size_t __size_;
  115. value_type * __base_;
  116. _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __size_(0), __base_(nullptr) {}
  117. static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count )
  118. {
  119. if ( numeric_limits<size_t>::max() / sizeof (value_type) <= count )
  120. {
  121. #ifndef _LIBCPP_NO_EXCEPTIONS
  122. throw bad_array_length();
  123. #else
  124. assert(!"dynarray::allocation");
  125. #endif
  126. }
  127. return static_cast<value_type *> (_VSTD::__allocate (sizeof(value_type) * count));
  128. }
  129. static inline _LIBCPP_INLINE_VISIBILITY void __deallocate ( value_type* __ptr ) noexcept
  130. {
  131. _VSTD::__deallocate (static_cast<void *> (__ptr));
  132. }
  133. public:
  134. _LIBCPP_INLINE_VISIBILITY
  135. explicit dynarray(size_type __c);
  136. _LIBCPP_INLINE_VISIBILITY
  137. dynarray(size_type __c, const value_type& __v);
  138. _LIBCPP_INLINE_VISIBILITY
  139. dynarray(const dynarray& __d);
  140. _LIBCPP_INLINE_VISIBILITY
  141. dynarray(initializer_list<value_type>);
  142. // We're not implementing these right now.
  143. // Updated with the resolution of LWG issue #2255
  144. // template <typename _Alloc>
  145. // dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c);
  146. // template <typename _Alloc>
  147. // dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c, const value_type& __v);
  148. // template <typename _Alloc>
  149. // dynarray(allocator_arg_t, const _Alloc& __alloc, const dynarray& __d);
  150. // template <typename _Alloc>
  151. // dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list<value_type>);
  152. dynarray& operator=(const dynarray&) = delete;
  153. _LIBCPP_INLINE_VISIBILITY
  154. ~dynarray();
  155. // iterators:
  156. inline _LIBCPP_INLINE_VISIBILITY iterator begin() noexcept { return iterator(data()); }
  157. inline _LIBCPP_INLINE_VISIBILITY const_iterator begin() const noexcept { return const_iterator(data()); }
  158. inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); }
  159. inline _LIBCPP_INLINE_VISIBILITY iterator end() noexcept { return iterator(data() + __size_); }
  160. inline _LIBCPP_INLINE_VISIBILITY const_iterator end() const noexcept { return const_iterator(data() + __size_); }
  161. inline _LIBCPP_INLINE_VISIBILITY const_iterator cend() const noexcept { return const_iterator(data() + __size_); }
  162. inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
  163. inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
  164. inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
  165. inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
  166. inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
  167. inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
  168. // capacity:
  169. inline _LIBCPP_INLINE_VISIBILITY size_type size() const noexcept { return __size_; }
  170. inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; }
  171. inline _LIBCPP_INLINE_VISIBILITY bool empty() const noexcept { return __size_ == 0; }
  172. // element access:
  173. inline _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) { return data()[__n]; }
  174. inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; }
  175. inline _LIBCPP_INLINE_VISIBILITY reference front() { return data()[0]; }
  176. inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; }
  177. inline _LIBCPP_INLINE_VISIBILITY reference back() { return data()[__size_-1]; }
  178. inline _LIBCPP_INLINE_VISIBILITY const_reference back() const { return data()[__size_-1]; }
  179. inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const;
  180. inline _LIBCPP_INLINE_VISIBILITY reference at(size_type __n);
  181. // data access:
  182. inline _LIBCPP_INLINE_VISIBILITY _Tp* data() noexcept { return __base_; }
  183. inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; }
  184. // mutating member functions:
  185. inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); }
  186. };
  187. template <class _Tp>
  188. inline
  189. dynarray<_Tp>::dynarray(size_type __c) : dynarray ()
  190. {
  191. __base_ = __allocate (__c);
  192. value_type *__data = data ();
  193. for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
  194. ::new (__data) value_type;
  195. }
  196. template <class _Tp>
  197. inline
  198. dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray ()
  199. {
  200. __base_ = __allocate (__c);
  201. value_type *__data = data ();
  202. for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
  203. ::new (__data) value_type (__v);
  204. }
  205. template <class _Tp>
  206. inline
  207. dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray ()
  208. {
  209. size_t sz = __il.size();
  210. __base_ = __allocate (sz);
  211. value_type *__data = data ();
  212. auto src = __il.begin();
  213. for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
  214. ::new (__data) value_type (*src);
  215. }
  216. template <class _Tp>
  217. inline
  218. dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray ()
  219. {
  220. size_t sz = __d.size();
  221. __base_ = __allocate (sz);
  222. value_type *__data = data ();
  223. auto src = __d.begin();
  224. for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
  225. ::new (__data) value_type (*src);
  226. }
  227. template <class _Tp>
  228. inline
  229. dynarray<_Tp>::~dynarray()
  230. {
  231. value_type *__data = data () + __size_;
  232. for ( size_t i = 0; i < __size_; ++i )
  233. (--__data)->value_type::~value_type();
  234. __deallocate ( __base_ );
  235. }
  236. template <class _Tp>
  237. inline _LIBCPP_INLINE_VISIBILITY
  238. typename dynarray<_Tp>::reference
  239. dynarray<_Tp>::at(size_type __n)
  240. {
  241. if (__n >= __size_)
  242. {
  243. #ifndef _LIBCPP_NO_EXCEPTIONS
  244. throw out_of_range("dynarray::at");
  245. #else
  246. assert(!"dynarray::at out_of_range");
  247. #endif
  248. }
  249. return data()[__n];
  250. }
  251. template <class _Tp>
  252. inline _LIBCPP_INLINE_VISIBILITY
  253. typename dynarray<_Tp>::const_reference
  254. dynarray<_Tp>::at(size_type __n) const
  255. {
  256. if (__n >= __size_)
  257. {
  258. #ifndef _LIBCPP_NO_EXCEPTIONS
  259. throw out_of_range("dynarray::at");
  260. #else
  261. assert(!"dynarray::at out_of_range");
  262. #endif
  263. }
  264. return data()[__n];
  265. }
  266. }}}
  267. _LIBCPP_BEGIN_NAMESPACE_STD
  268. template <class _Tp, class _Alloc>
  269. struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {};
  270. _LIBCPP_END_NAMESPACE_STD
  271. #endif // if _LIBCPP_STD_VER > 11
  272. #endif // _LIBCPP_DYNARRAY