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