| // -*- C++ -*- | |
| //===-------------------------- dynarray ----------------------------------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is dual licensed under the MIT and the University of Illinois Open | |
| // Source Licenses. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef _LIBCPP_DYNARRAY | |
| #define _LIBCPP_DYNARRAY | |
| /* | |
| dynarray synopsis | |
| namespace std { namespace experimental { | |
| template< typename T > | |
| class dynarray | |
| { | |
| // types: | |
| typedef T value_type; | |
| typedef T& reference; | |
| typedef const T& const_reference; | |
| typedef T* pointer; | |
| typedef const T* const_pointer; | |
| typedef implementation-defined iterator; | |
| typedef implementation-defined const_iterator; | |
| typedef reverse_iterator<iterator> reverse_iterator; | |
| typedef reverse_iterator<const_iterator> const_reverse_iterator; | |
| typedef size_t size_type; | |
| typedef ptrdiff_t difference_type; | |
| public: | |
| // construct/copy/destroy: | |
| explicit dynarray(size_type c); | |
| dynarray(size_type c, const T& v); | |
| dynarray(const dynarray& d); | |
| dynarray(initializer_list<T>); | |
| template <class Alloc> | |
| dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc); | |
| template <class Alloc> | |
| dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc); | |
| template <class Alloc> | |
| dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc); | |
| template <class Alloc> | |
| dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc); | |
| dynarray& operator=(const dynarray&) = delete; | |
| ~dynarray(); | |
| // iterators: | |
| iterator begin() noexcept; | |
| const_iterator begin() const noexcept; | |
| const_iterator cbegin() const noexcept; | |
| iterator end() noexcept; | |
| const_iterator end() const noexcept; | |
| const_iterator cend() const noexcept; | |
| reverse_iterator rbegin() noexcept; | |
| const_reverse_iterator rbegin() const noexcept; | |
| const_reverse_iterator crbegin() const noexcept; | |
| reverse_iterator rend() noexcept; | |
| const_reverse_iterator rend() const noexcept; | |
| const_reverse_iterator crend() const noexcept; | |
| // capacity: | |
| size_type size() const noexcept; | |
| size_type max_size() const noexcept; | |
| bool empty() const noexcept; | |
| // element access: | |
| reference operator[](size_type n); | |
| const_reference operator[](size_type n) const; | |
| reference front(); | |
| const_reference front() const; | |
| reference back(); | |
| const_reference back() const; | |
| const_reference at(size_type n) const; | |
| reference at(size_type n); | |
| // data access: | |
| T* data() noexcept; | |
| const T* data() const noexcept; | |
| // mutating member functions: | |
| void fill(const T& v); | |
| }; | |
| }} // std::experimental | |
| */ | |
| #include <__config> | |
| #if _LIBCPP_STD_VER > 11 | |
| #include <__functional_base> | |
| #include <iterator> | |
| #include <stdexcept> | |
| #include <initializer_list> | |
| #include <new> | |
| #include <algorithm> | |
| #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| #pragma GCC system_header | |
| #endif | |
| _LIBCPP_PUSH_MACROS | |
| #include <__undef_macros> | |
| namespace std { namespace experimental { inline namespace __array_extensions_v1 { | |
| template <class _Tp> | |
| struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_DYNARRAY dynarray | |
| { | |
| public: | |
| // types: | |
| typedef dynarray __self; | |
| typedef _Tp value_type; | |
| typedef value_type& reference; | |
| typedef const value_type& const_reference; | |
| typedef value_type* iterator; | |
| typedef const value_type* const_iterator; | |
| typedef value_type* pointer; | |
| typedef const value_type* const_pointer; | |
| typedef size_t size_type; | |
| typedef ptrdiff_t difference_type; | |
| typedef std::reverse_iterator<iterator> reverse_iterator; | |
| typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | |
| private: | |
| size_t __size_; | |
| value_type * __base_; | |
| _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __size_(0), __base_(nullptr) {} | |
| static inline _LIBCPP_INLINE_VISIBILITY | |
| value_type* __allocate(size_t __count) { | |
| if (numeric_limits<size_t>::max() / sizeof (value_type) <= __count) | |
| __throw_bad_array_length(); | |
| return static_cast<value_type *>( | |
| _VSTD::__libcpp_allocate(sizeof(value_type) * __count, __alignof(value_type))); | |
| } | |
| static inline _LIBCPP_INLINE_VISIBILITY | |
| void __deallocate_value(value_type* __ptr ) noexcept { | |
| _VSTD::__libcpp_deallocate(static_cast<void *>(__ptr), __alignof(value_type)); | |
| } | |
| public: | |
| _LIBCPP_INLINE_VISIBILITY | |
| explicit dynarray(size_type __c); | |
| _LIBCPP_INLINE_VISIBILITY | |
| dynarray(size_type __c, const value_type& __v); | |
| _LIBCPP_INLINE_VISIBILITY | |
| dynarray(const dynarray& __d); | |
| _LIBCPP_INLINE_VISIBILITY | |
| dynarray(initializer_list<value_type>); | |
| // We're not implementing these right now. | |
| // Updated with the resolution of LWG issue #2255 | |
| // template <typename _Alloc> | |
| // dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c); | |
| // template <typename _Alloc> | |
| // dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c, const value_type& __v); | |
| // template <typename _Alloc> | |
| // dynarray(allocator_arg_t, const _Alloc& __alloc, const dynarray& __d); | |
| // template <typename _Alloc> | |
| // dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list<value_type>); | |
| dynarray& operator=(const dynarray&) = delete; | |
| _LIBCPP_INLINE_VISIBILITY | |
| ~dynarray(); | |
| // iterators: | |
| inline _LIBCPP_INLINE_VISIBILITY iterator begin() noexcept { return iterator(data()); } | |
| inline _LIBCPP_INLINE_VISIBILITY const_iterator begin() const noexcept { return const_iterator(data()); } | |
| inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); } | |
| inline _LIBCPP_INLINE_VISIBILITY iterator end() noexcept { return iterator(data() + __size_); } | |
| inline _LIBCPP_INLINE_VISIBILITY const_iterator end() const noexcept { return const_iterator(data() + __size_); } | |
| inline _LIBCPP_INLINE_VISIBILITY const_iterator cend() const noexcept { return const_iterator(data() + __size_); } | |
| inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } | |
| inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } | |
| inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } | |
| inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() noexcept { return reverse_iterator(begin()); } | |
| inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } | |
| inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } | |
| // capacity: | |
| inline _LIBCPP_INLINE_VISIBILITY size_type size() const noexcept { return __size_; } | |
| inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; } | |
| inline _LIBCPP_INLINE_VISIBILITY bool empty() const noexcept { return __size_ == 0; } | |
| // element access: | |
| inline _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) { return data()[__n]; } | |
| inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; } | |
| inline _LIBCPP_INLINE_VISIBILITY reference front() { return data()[0]; } | |
| inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; } | |
| inline _LIBCPP_INLINE_VISIBILITY reference back() { return data()[__size_-1]; } | |
| inline _LIBCPP_INLINE_VISIBILITY const_reference back() const { return data()[__size_-1]; } | |
| inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const; | |
| inline _LIBCPP_INLINE_VISIBILITY reference at(size_type __n); | |
| // data access: | |
| inline _LIBCPP_INLINE_VISIBILITY _Tp* data() noexcept { return __base_; } | |
| inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; } | |
| // mutating member functions: | |
| inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); } | |
| }; | |
| template <class _Tp> | |
| inline | |
| dynarray<_Tp>::dynarray(size_type __c) : dynarray () | |
| { | |
| __base_ = __allocate (__c); | |
| value_type *__data = data (); | |
| for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) | |
| ::new (__data) value_type; | |
| } | |
| template <class _Tp> | |
| inline | |
| dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray () | |
| { | |
| __base_ = __allocate (__c); | |
| value_type *__data = data (); | |
| for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) | |
| ::new (__data) value_type (__v); | |
| } | |
| template <class _Tp> | |
| inline | |
| dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray () | |
| { | |
| size_t sz = __il.size(); | |
| __base_ = __allocate (sz); | |
| value_type *__data = data (); | |
| auto src = __il.begin(); | |
| for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) | |
| ::new (__data) value_type (*src); | |
| } | |
| template <class _Tp> | |
| inline | |
| dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray () | |
| { | |
| size_t sz = __d.size(); | |
| __base_ = __allocate (sz); | |
| value_type *__data = data (); | |
| auto src = __d.begin(); | |
| for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) | |
| ::new (__data) value_type (*src); | |
| } | |
| template <class _Tp> | |
| inline | |
| dynarray<_Tp>::~dynarray() | |
| { | |
| value_type *__data = data () + __size_; | |
| for ( size_t i = 0; i < __size_; ++i ) | |
| (--__data)->value_type::~value_type(); | |
| __deallocate_value( __base_ ); | |
| } | |
| template <class _Tp> | |
| inline _LIBCPP_INLINE_VISIBILITY | |
| typename dynarray<_Tp>::reference | |
| dynarray<_Tp>::at(size_type __n) | |
| { | |
| if (__n >= __size_) | |
| __throw_out_of_range("dynarray::at"); | |
| return data()[__n]; | |
| } | |
| template <class _Tp> | |
| inline _LIBCPP_INLINE_VISIBILITY | |
| typename dynarray<_Tp>::const_reference | |
| dynarray<_Tp>::at(size_type __n) const | |
| { | |
| if (__n >= __size_) | |
| __throw_out_of_range("dynarray::at"); | |
| return data()[__n]; | |
| } | |
| }}} | |
| _LIBCPP_BEGIN_NAMESPACE_STD | |
| template <class _Tp, class _Alloc> | |
| struct _LIBCPP_TEMPLATE_VIS uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {}; | |
| _LIBCPP_END_NAMESPACE_STD | |
| _LIBCPP_POP_MACROS | |
| #endif // if _LIBCPP_STD_VER > 11 | |
| #endif // _LIBCPP_DYNARRAY |