dynarray revision 276792
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 107261272Sdim#if defined(_LIBCPP_NO_EXCEPTIONS) 108261272Sdim #include <cassert> 109261272Sdim#endif 110261272Sdim 111261272Sdim#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 112261272Sdim#pragma GCC system_header 113261272Sdim#endif 114261272Sdim 115261272Sdimnamespace std { namespace experimental { inline namespace __array_extensions_v1 { 116261272Sdim 117261272Sdimtemplate <class _Tp> 118261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY dynarray 119261272Sdim{ 120261272Sdimpublic: 121261272Sdim // types: 122261272Sdim typedef dynarray __self; 123261272Sdim typedef _Tp value_type; 124261272Sdim typedef value_type& reference; 125261272Sdim typedef const value_type& const_reference; 126261272Sdim typedef value_type* iterator; 127261272Sdim typedef const value_type* const_iterator; 128261272Sdim typedef value_type* pointer; 129261272Sdim typedef const value_type* const_pointer; 130261272Sdim typedef size_t size_type; 131261272Sdim typedef ptrdiff_t difference_type; 132261272Sdim typedef std::reverse_iterator<iterator> reverse_iterator; 133261272Sdim typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 134261272Sdim 135261272Sdimprivate: 136261272Sdim size_t __size_; 137261272Sdim value_type * __base_; 138261272Sdim _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __base_(nullptr), __size_(0) {} 139261272Sdim 140261272Sdim static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count ) 141261272Sdim { 142261272Sdim if ( numeric_limits<size_t>::max() / sizeof (value_type) <= count ) 143261272Sdim { 144261272Sdim#ifndef _LIBCPP_NO_EXCEPTIONS 145261272Sdim throw bad_array_length(); 146261272Sdim#else 147261272Sdim assert(!"dynarray::allocation"); 148261272Sdim#endif 149261272Sdim } 150276792Sdim return static_cast<value_type *> (_VSTD::__allocate (sizeof(value_type) * count)); 151261272Sdim } 152261272Sdim 153261272Sdim static inline _LIBCPP_INLINE_VISIBILITY void __deallocate ( value_type* __ptr ) noexcept 154261272Sdim { 155276792Sdim _VSTD::__deallocate (static_cast<void *> (__ptr)); 156261272Sdim } 157261272Sdim 158261272Sdimpublic: 159261272Sdim 160261272Sdim explicit dynarray(size_type __c); 161261272Sdim dynarray(size_type __c, const value_type& __v); 162261272Sdim dynarray(const dynarray& __d); 163261272Sdim dynarray(initializer_list<value_type>); 164261272Sdim 165261272Sdim// We're not implementing these right now. 166276792Sdim// Updated with the resolution of LWG issue #2255 167261272Sdim// template <typename _Alloc> 168276792Sdim// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c); 169261272Sdim// template <typename _Alloc> 170276792Sdim// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c, const value_type& __v); 171261272Sdim// template <typename _Alloc> 172276792Sdim// dynarray(allocator_arg_t, const _Alloc& __alloc, const dynarray& __d); 173261272Sdim// template <typename _Alloc> 174276792Sdim// dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list<value_type>); 175261272Sdim 176261272Sdim dynarray& operator=(const dynarray&) = delete; 177261272Sdim ~dynarray(); 178261272Sdim 179261272Sdim // iterators: 180261272Sdim inline _LIBCPP_INLINE_VISIBILITY iterator begin() noexcept { return iterator(data()); } 181261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_iterator begin() const noexcept { return const_iterator(data()); } 182261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); } 183261272Sdim inline _LIBCPP_INLINE_VISIBILITY iterator end() noexcept { return iterator(data() + __size_); } 184261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_iterator end() const noexcept { return const_iterator(data() + __size_); } 185261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_iterator cend() const noexcept { return const_iterator(data() + __size_); } 186261272Sdim 187261272Sdim inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } 188261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } 189261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } 190261272Sdim inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() noexcept { return reverse_iterator(begin()); } 191261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } 192261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } 193261272Sdim 194261272Sdim // capacity: 195261272Sdim inline _LIBCPP_INLINE_VISIBILITY size_type size() const noexcept { return __size_; } 196261272Sdim inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; } 197261272Sdim inline _LIBCPP_INLINE_VISIBILITY bool empty() const noexcept { return __size_ == 0; } 198261272Sdim 199261272Sdim // element access: 200261272Sdim inline _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) { return data()[__n]; } 201261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; } 202261272Sdim 203261272Sdim inline _LIBCPP_INLINE_VISIBILITY reference front() { return data()[0]; } 204261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; } 205261272Sdim inline _LIBCPP_INLINE_VISIBILITY reference back() { return data()[__size_-1]; } 206261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reference back() const { return data()[__size_-1]; } 207261272Sdim 208261272Sdim inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const; 209261272Sdim inline _LIBCPP_INLINE_VISIBILITY reference at(size_type __n); 210261272Sdim 211261272Sdim // data access: 212261272Sdim inline _LIBCPP_INLINE_VISIBILITY _Tp* data() noexcept { return __base_; } 213261272Sdim inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; } 214261272Sdim 215261272Sdim // mutating member functions: 216261272Sdim inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); } 217261272Sdim}; 218261272Sdim 219261272Sdimtemplate <class _Tp> 220261272Sdiminline _LIBCPP_INLINE_VISIBILITY 221261272Sdimdynarray<_Tp>::dynarray(size_type __c) : dynarray () 222261272Sdim{ 223261272Sdim __base_ = __allocate (__c); 224261272Sdim value_type *__data = data (); 225261272Sdim for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) 226261272Sdim ::new (__data) value_type; 227261272Sdim} 228261272Sdim 229261272Sdimtemplate <class _Tp> 230261272Sdiminline _LIBCPP_INLINE_VISIBILITY 231261272Sdimdynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray () 232261272Sdim{ 233261272Sdim __base_ = __allocate (__c); 234261272Sdim value_type *__data = data (); 235261272Sdim for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) 236261272Sdim ::new (__data) value_type (__v); 237261272Sdim} 238261272Sdim 239261272Sdimtemplate <class _Tp> 240261272Sdiminline _LIBCPP_INLINE_VISIBILITY 241261272Sdimdynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray () 242261272Sdim{ 243261272Sdim size_t sz = __il.size(); 244261272Sdim __base_ = __allocate (sz); 245261272Sdim value_type *__data = data (); 246261272Sdim auto src = __il.begin(); 247261272Sdim for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) 248261272Sdim ::new (__data) value_type (*src); 249261272Sdim} 250261272Sdim 251261272Sdimtemplate <class _Tp> 252261272Sdiminline _LIBCPP_INLINE_VISIBILITY 253261272Sdimdynarray<_Tp>::dynarray(const dynarray& __d) : dynarray () 254261272Sdim{ 255261272Sdim size_t sz = __d.size(); 256261272Sdim __base_ = __allocate (sz); 257261272Sdim value_type *__data = data (); 258261272Sdim auto src = __d.begin(); 259261272Sdim for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) 260261272Sdim ::new (__data) value_type (*src); 261261272Sdim} 262261272Sdim 263261272Sdimtemplate <class _Tp> 264261272Sdiminline _LIBCPP_INLINE_VISIBILITY 265261272Sdimdynarray<_Tp>::~dynarray() 266261272Sdim{ 267261272Sdim value_type *__data = data () + __size_; 268261272Sdim for ( size_t i = 0; i < __size_; ++i ) 269261272Sdim (--__data)->value_type::~value_type(); 270261272Sdim __deallocate ( __base_ ); 271261272Sdim} 272261272Sdim 273261272Sdimtemplate <class _Tp> 274261272Sdiminline _LIBCPP_INLINE_VISIBILITY 275261272Sdimtypename dynarray<_Tp>::reference 276261272Sdimdynarray<_Tp>::at(size_type __n) 277261272Sdim{ 278261272Sdim if (__n >= __size_) 279261272Sdim { 280261272Sdim#ifndef _LIBCPP_NO_EXCEPTIONS 281261272Sdim throw out_of_range("dynarray::at"); 282261272Sdim#else 283261272Sdim assert(!"dynarray::at out_of_range"); 284261272Sdim#endif 285261272Sdim } 286261272Sdim return data()[__n]; 287261272Sdim} 288261272Sdim 289261272Sdimtemplate <class _Tp> 290261272Sdiminline _LIBCPP_INLINE_VISIBILITY 291261272Sdimtypename dynarray<_Tp>::const_reference 292261272Sdimdynarray<_Tp>::at(size_type __n) const 293261272Sdim{ 294261272Sdim if (__n >= __size_) 295261272Sdim { 296261272Sdim#ifndef _LIBCPP_NO_EXCEPTIONS 297261272Sdim throw out_of_range("dynarray::at"); 298261272Sdim#else 299261272Sdim assert(!"dynarray::at out_of_range"); 300261272Sdim#endif 301261272Sdim } 302261272Sdim return data()[__n]; 303261272Sdim} 304261272Sdim 305261272Sdim}}} 306261272Sdim 307261272Sdim 308261272Sdim_LIBCPP_BEGIN_NAMESPACE_STD 309261272Sdimtemplate <class _Tp, class _Alloc> 310261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {}; 311261272Sdim_LIBCPP_END_NAMESPACE_STD 312261272Sdim 313261272Sdim#endif // if _LIBCPP_STD_VER > 11 314261272Sdim#endif // _LIBCPP_DYNARRAY 315