dynarray revision 288943
1261272Sdim// -*- C++ -*- 2261272Sdim//===-------------------------- dynarray ----------------------------------===// 3261272Sdim// 4261272Sdim// The LLVM Compiler Infrastructure 5261272Sdim// 6261272Sdim// This file is dual licensed under the MIT and the University of Illinois Open 7261272Sdim// Source Licenses. See LICENSE.TXT for details. 8261272Sdim// 9261272Sdim//===----------------------------------------------------------------------===// 10261272Sdim 11261272Sdim#ifndef _LIBCPP_DYNARRAY 12261272Sdim#define _LIBCPP_DYNARRAY 13261272Sdim 14261272Sdim#include <__config> 15261272Sdim#if _LIBCPP_STD_VER > 11 16261272Sdim 17261272Sdim/* 18261272Sdim dynarray synopsis 19261272Sdim 20261272Sdimnamespace std { namespace experimental { 21261272Sdim 22261272Sdimtemplate< typename T > 23261272Sdimclass dynarray 24261272Sdim{ 25261272Sdim // types: 26261272Sdim typedef T value_type; 27261272Sdim typedef T& reference; 28261272Sdim typedef const T& const_reference; 29261272Sdim typedef T* pointer; 30261272Sdim typedef const T* const_pointer; 31261272Sdim typedef implementation-defined iterator; 32261272Sdim typedef implementation-defined const_iterator; 33261272Sdim typedef reverse_iterator<iterator> reverse_iterator; 34261272Sdim typedef reverse_iterator<const_iterator> const_reverse_iterator; 35261272Sdim typedef size_t size_type; 36261272Sdim typedef ptrdiff_t difference_type; 37261272Sdim 38261272Sdimpublic: 39261272Sdim // construct/copy/destroy: 40261272Sdim explicit dynarray(size_type c); 41261272Sdim dynarray(size_type c, const T& v); 42261272Sdim dynarray(const dynarray& d); 43261272Sdim dynarray(initializer_list<T>); 44261272Sdim 45276792Sdim template <class Alloc> 46276792Sdim dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc); 47276792Sdim template <class Alloc> 48276792Sdim dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc); 49276792Sdim template <class Alloc> 50276792Sdim dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc); 51276792Sdim template <class Alloc> 52276792Sdim dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc); 53261272Sdim dynarray& operator=(const dynarray&) = delete; 54261272Sdim ~dynarray(); 55261272Sdim 56261272Sdim // iterators: 57261272Sdim iterator begin() noexcept; 58261272Sdim const_iterator begin() const noexcept; 59261272Sdim const_iterator cbegin() const noexcept; 60261272Sdim iterator end() noexcept; 61261272Sdim const_iterator end() const noexcept; 62261272Sdim const_iterator cend() const noexcept; 63261272Sdim 64261272Sdim reverse_iterator rbegin() noexcept; 65261272Sdim const_reverse_iterator rbegin() const noexcept; 66261272Sdim const_reverse_iterator crbegin() const noexcept; 67261272Sdim reverse_iterator rend() noexcept; 68261272Sdim const_reverse_iterator rend() const noexcept; 69261272Sdim const_reverse_iterator crend() const noexcept; 70261272Sdim 71261272Sdim // capacity: 72261272Sdim size_type size() const noexcept; 73261272Sdim size_type max_size() const noexcept; 74261272Sdim bool empty() const noexcept; 75261272Sdim 76261272Sdim // element access: 77261272Sdim reference operator[](size_type n); 78261272Sdim const_reference operator[](size_type n) const; 79261272Sdim 80261272Sdim reference front(); 81261272Sdim const_reference front() const; 82261272Sdim reference back(); 83261272Sdim const_reference back() const; 84261272Sdim 85261272Sdim const_reference at(size_type n) const; 86261272Sdim reference at(size_type n); 87261272Sdim 88261272Sdim // data access: 89261272Sdim T* data() noexcept; 90261272Sdim const T* data() const noexcept; 91261272Sdim 92261272Sdim // mutating member functions: 93261272Sdim void fill(const T& v); 94261272Sdim}; 95261272Sdim 96261272Sdim}} // std::experimental 97261272Sdim 98261272Sdim*/ 99261272Sdim 100261272Sdim#include <__functional_base> 101261272Sdim#include <iterator> 102261272Sdim#include <stdexcept> 103261272Sdim#include <initializer_list> 104261272Sdim#include <new> 105261272Sdim#include <algorithm> 106261272Sdim 107288943Sdim#include <__undef___deallocate> 108288943Sdim 109261272Sdim#if defined(_LIBCPP_NO_EXCEPTIONS) 110261272Sdim #include <cassert> 111261272Sdim#endif 112261272Sdim 113261272Sdim#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 114261272Sdim#pragma GCC system_header 115261272Sdim#endif 116261272Sdim 117261272Sdimnamespace std { namespace experimental { inline namespace __array_extensions_v1 { 118261272Sdim 119261272Sdimtemplate <class _Tp> 120261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY dynarray 121261272Sdim{ 122261272Sdimpublic: 123261272Sdim // types: 124261272Sdim typedef dynarray __self; 125261272Sdim typedef _Tp value_type; 126261272Sdim typedef value_type& reference; 127261272Sdim typedef const value_type& const_reference; 128261272Sdim typedef value_type* iterator; 129261272Sdim typedef const value_type* const_iterator; 130261272Sdim typedef value_type* pointer; 131261272Sdim typedef const value_type* const_pointer; 132261272Sdim typedef size_t size_type; 133261272Sdim typedef ptrdiff_t difference_type; 134261272Sdim typedef std::reverse_iterator<iterator> reverse_iterator; 135261272Sdim typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 136261272Sdim 137261272Sdimprivate: 138261272Sdim size_t __size_; 139261272Sdim value_type * __base_; 140261272Sdim _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __base_(nullptr), __size_(0) {} 141261272Sdim 142261272Sdim static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count ) 143261272Sdim { 144261272Sdim if ( numeric_limits<size_t>::max() / sizeof (value_type) <= count ) 145261272Sdim { 146261272Sdim#ifndef _LIBCPP_NO_EXCEPTIONS 147261272Sdim throw bad_array_length(); 148261272Sdim#else 149261272Sdim assert(!"dynarray::allocation"); 150261272Sdim#endif 151261272Sdim } 152276792Sdim return static_cast<value_type *> (_VSTD::__allocate (sizeof(value_type) * count)); 153261272Sdim } 154261272Sdim 155261272Sdim static inline _LIBCPP_INLINE_VISIBILITY void __deallocate ( value_type* __ptr ) noexcept 156261272Sdim { 157276792Sdim _VSTD::__deallocate (static_cast<void *> (__ptr)); 158261272Sdim } 159261272Sdim 160261272Sdimpublic: 161261272Sdim 162261272Sdim explicit dynarray(size_type __c); 163261272Sdim dynarray(size_type __c, const value_type& __v); 164261272Sdim dynarray(const dynarray& __d); 165261272Sdim dynarray(initializer_list<value_type>); 166261272Sdim 167261272Sdim// We're not implementing these right now. 168276792Sdim// Updated with the resolution of LWG issue #2255 169261272Sdim// template <typename _Alloc> 170276792Sdim// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c); 171261272Sdim// template <typename _Alloc> 172276792Sdim// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c, const value_type& __v); 173261272Sdim// template <typename _Alloc> 174276792Sdim// dynarray(allocator_arg_t, const _Alloc& __alloc, const dynarray& __d); 175261272Sdim// template <typename _Alloc> 176276792Sdim// dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list<value_type>); 177261272Sdim 178261272Sdim dynarray& operator=(const dynarray&) = delete; 179261272Sdim ~dynarray(); 180261272Sdim 181261272Sdim // iterators: 182261272Sdim inline _LIBCPP_INLINE_VISIBILITY iterator begin() noexcept { return iterator(data()); } 183261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_iterator begin() const noexcept { return const_iterator(data()); } 184261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); } 185261272Sdim inline _LIBCPP_INLINE_VISIBILITY iterator end() noexcept { return iterator(data() + __size_); } 186261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_iterator end() const noexcept { return const_iterator(data() + __size_); } 187261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_iterator cend() const noexcept { return const_iterator(data() + __size_); } 188261272Sdim 189261272Sdim inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } 190261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } 191261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } 192261272Sdim inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() noexcept { return reverse_iterator(begin()); } 193261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } 194261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } 195261272Sdim 196261272Sdim // capacity: 197261272Sdim inline _LIBCPP_INLINE_VISIBILITY size_type size() const noexcept { return __size_; } 198261272Sdim inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; } 199261272Sdim inline _LIBCPP_INLINE_VISIBILITY bool empty() const noexcept { return __size_ == 0; } 200261272Sdim 201261272Sdim // element access: 202261272Sdim inline _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) { return data()[__n]; } 203261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; } 204261272Sdim 205261272Sdim inline _LIBCPP_INLINE_VISIBILITY reference front() { return data()[0]; } 206261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; } 207261272Sdim inline _LIBCPP_INLINE_VISIBILITY reference back() { return data()[__size_-1]; } 208261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reference back() const { return data()[__size_-1]; } 209261272Sdim 210261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const; 211261272Sdim inline _LIBCPP_INLINE_VISIBILITY reference at(size_type __n); 212261272Sdim 213261272Sdim // data access: 214261272Sdim inline _LIBCPP_INLINE_VISIBILITY _Tp* data() noexcept { return __base_; } 215261272Sdim inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; } 216261272Sdim 217261272Sdim // mutating member functions: 218261272Sdim inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); } 219261272Sdim}; 220261272Sdim 221261272Sdimtemplate <class _Tp> 222261272Sdiminline _LIBCPP_INLINE_VISIBILITY 223261272Sdimdynarray<_Tp>::dynarray(size_type __c) : dynarray () 224261272Sdim{ 225261272Sdim __base_ = __allocate (__c); 226261272Sdim value_type *__data = data (); 227261272Sdim for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) 228261272Sdim ::new (__data) value_type; 229261272Sdim} 230261272Sdim 231261272Sdimtemplate <class _Tp> 232261272Sdiminline _LIBCPP_INLINE_VISIBILITY 233261272Sdimdynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray () 234261272Sdim{ 235261272Sdim __base_ = __allocate (__c); 236261272Sdim value_type *__data = data (); 237261272Sdim for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) 238261272Sdim ::new (__data) value_type (__v); 239261272Sdim} 240261272Sdim 241261272Sdimtemplate <class _Tp> 242261272Sdiminline _LIBCPP_INLINE_VISIBILITY 243261272Sdimdynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray () 244261272Sdim{ 245261272Sdim size_t sz = __il.size(); 246261272Sdim __base_ = __allocate (sz); 247261272Sdim value_type *__data = data (); 248261272Sdim auto src = __il.begin(); 249261272Sdim for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) 250261272Sdim ::new (__data) value_type (*src); 251261272Sdim} 252261272Sdim 253261272Sdimtemplate <class _Tp> 254261272Sdiminline _LIBCPP_INLINE_VISIBILITY 255261272Sdimdynarray<_Tp>::dynarray(const dynarray& __d) : dynarray () 256261272Sdim{ 257261272Sdim size_t sz = __d.size(); 258261272Sdim __base_ = __allocate (sz); 259261272Sdim value_type *__data = data (); 260261272Sdim auto src = __d.begin(); 261261272Sdim for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) 262261272Sdim ::new (__data) value_type (*src); 263261272Sdim} 264261272Sdim 265261272Sdimtemplate <class _Tp> 266261272Sdiminline _LIBCPP_INLINE_VISIBILITY 267261272Sdimdynarray<_Tp>::~dynarray() 268261272Sdim{ 269261272Sdim value_type *__data = data () + __size_; 270261272Sdim for ( size_t i = 0; i < __size_; ++i ) 271261272Sdim (--__data)->value_type::~value_type(); 272261272Sdim __deallocate ( __base_ ); 273261272Sdim} 274261272Sdim 275261272Sdimtemplate <class _Tp> 276261272Sdiminline _LIBCPP_INLINE_VISIBILITY 277261272Sdimtypename dynarray<_Tp>::reference 278261272Sdimdynarray<_Tp>::at(size_type __n) 279261272Sdim{ 280261272Sdim if (__n >= __size_) 281261272Sdim { 282261272Sdim#ifndef _LIBCPP_NO_EXCEPTIONS 283261272Sdim throw out_of_range("dynarray::at"); 284261272Sdim#else 285261272Sdim assert(!"dynarray::at out_of_range"); 286261272Sdim#endif 287261272Sdim } 288261272Sdim return data()[__n]; 289261272Sdim} 290261272Sdim 291261272Sdimtemplate <class _Tp> 292261272Sdiminline _LIBCPP_INLINE_VISIBILITY 293261272Sdimtypename dynarray<_Tp>::const_reference 294261272Sdimdynarray<_Tp>::at(size_type __n) const 295261272Sdim{ 296261272Sdim if (__n >= __size_) 297261272Sdim { 298261272Sdim#ifndef _LIBCPP_NO_EXCEPTIONS 299261272Sdim throw out_of_range("dynarray::at"); 300261272Sdim#else 301261272Sdim assert(!"dynarray::at out_of_range"); 302261272Sdim#endif 303261272Sdim } 304261272Sdim return data()[__n]; 305261272Sdim} 306261272Sdim 307261272Sdim}}} 308261272Sdim 309261272Sdim 310261272Sdim_LIBCPP_BEGIN_NAMESPACE_STD 311261272Sdimtemplate <class _Tp, class _Alloc> 312261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {}; 313261272Sdim_LIBCPP_END_NAMESPACE_STD 314261272Sdim 315261272Sdim#endif // if _LIBCPP_STD_VER > 11 316261272Sdim#endif // _LIBCPP_DYNARRAY 317