Import GCC-8 to a new vendor branch
[dragonfly.git] / contrib / gcc-8.0 / libstdc++-v3 / include / std / array
blob632896250cf704d83b56304f28cf1565813c5584
1 // <array> -*- C++ -*-
3 // Copyright (C) 2007-2018 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file include/array
26  *  This is a Standard C++ Library header.
27  */
29 #ifndef _GLIBCXX_ARRAY
30 #define _GLIBCXX_ARRAY 1
32 #pragma GCC system_header
34 #if __cplusplus < 201103L
35 # include <bits/c++0x_warning.h>
36 #else
38 #include <utility>
39 #include <stdexcept>
40 #include <bits/stl_algobase.h>
41 #include <bits/range_access.h>
43 namespace std _GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
47   template<typename _Tp, std::size_t _Nm>
48     struct __array_traits
49     {
50       typedef _Tp _Type[_Nm];
51       typedef __is_swappable<_Tp> _Is_swappable;
52       typedef __is_nothrow_swappable<_Tp> _Is_nothrow_swappable;
54       static constexpr _Tp&
55       _S_ref(const _Type& __t, std::size_t __n) noexcept
56       { return const_cast<_Tp&>(__t[__n]); }
58       static constexpr _Tp*
59       _S_ptr(const _Type& __t) noexcept
60       { return const_cast<_Tp*>(__t); }
61     };
63  template<typename _Tp>
64    struct __array_traits<_Tp, 0>
65    {
66      struct _Type { };
67      typedef true_type _Is_swappable;
68      typedef true_type _Is_nothrow_swappable;
70      static constexpr _Tp&
71      _S_ref(const _Type&, std::size_t) noexcept
72      { return *static_cast<_Tp*>(nullptr); }
74      static constexpr _Tp*
75      _S_ptr(const _Type&) noexcept
76      { return nullptr; }
77    };
79   /**
80    *  @brief A standard container for storing a fixed size sequence of elements.
81    *
82    *  @ingroup sequences
83    *
84    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
85    *  <a href="tables.html#66">reversible container</a>, and a
86    *  <a href="tables.html#67">sequence</a>.
87    *
88    *  Sets support random access iterators.
89    *
90    *  @tparam  Tp  Type of element. Required to be a complete type.
91    *  @tparam  N  Number of elements.
92   */
93   template<typename _Tp, std::size_t _Nm>
94     struct array
95     {
96       typedef _Tp                                     value_type;
97       typedef value_type*                             pointer;
98       typedef const value_type*                       const_pointer;
99       typedef value_type&                             reference;
100       typedef const value_type&                       const_reference;
101       typedef value_type*                             iterator;
102       typedef const value_type*                       const_iterator;
103       typedef std::size_t                             size_type;
104       typedef std::ptrdiff_t                          difference_type;
105       typedef std::reverse_iterator<iterator>         reverse_iterator;
106       typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
108       // Support for zero-sized arrays mandatory.
109       typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type;
110       typename _AT_Type::_Type                         _M_elems;
112       // No explicit construct/copy/destroy for aggregate type.
114       // DR 776.
115       void
116       fill(const value_type& __u)
117       { std::fill_n(begin(), size(), __u); }
119       void
120       swap(array& __other)
121       noexcept(_AT_Type::_Is_nothrow_swappable::value)
122       { std::swap_ranges(begin(), end(), __other.begin()); }
124       // Iterators.
125       _GLIBCXX17_CONSTEXPR iterator
126       begin() noexcept
127       { return iterator(data()); }
129       _GLIBCXX17_CONSTEXPR const_iterator
130       begin() const noexcept
131       { return const_iterator(data()); }
133       _GLIBCXX17_CONSTEXPR iterator
134       end() noexcept
135       { return iterator(data() + _Nm); }
137       _GLIBCXX17_CONSTEXPR const_iterator
138       end() const noexcept
139       { return const_iterator(data() + _Nm); }
141       _GLIBCXX17_CONSTEXPR reverse_iterator
142       rbegin() noexcept
143       { return reverse_iterator(end()); }
145       _GLIBCXX17_CONSTEXPR const_reverse_iterator
146       rbegin() const noexcept
147       { return const_reverse_iterator(end()); }
149       _GLIBCXX17_CONSTEXPR reverse_iterator
150       rend() noexcept
151       { return reverse_iterator(begin()); }
153       _GLIBCXX17_CONSTEXPR const_reverse_iterator
154       rend() const noexcept
155       { return const_reverse_iterator(begin()); }
157       _GLIBCXX17_CONSTEXPR const_iterator
158       cbegin() const noexcept
159       { return const_iterator(data()); }
161       _GLIBCXX17_CONSTEXPR const_iterator
162       cend() const noexcept
163       { return const_iterator(data() + _Nm); }
165       _GLIBCXX17_CONSTEXPR const_reverse_iterator
166       crbegin() const noexcept
167       { return const_reverse_iterator(end()); }
169       _GLIBCXX17_CONSTEXPR const_reverse_iterator
170       crend() const noexcept
171       { return const_reverse_iterator(begin()); }
173       // Capacity.
174       constexpr size_type
175       size() const noexcept { return _Nm; }
177       constexpr size_type
178       max_size() const noexcept { return _Nm; }
180       constexpr bool
181       empty() const noexcept { return size() == 0; }
183       // Element access.
184       _GLIBCXX17_CONSTEXPR reference
185       operator[](size_type __n) noexcept
186       { return _AT_Type::_S_ref(_M_elems, __n); }
188       constexpr const_reference
189       operator[](size_type __n) const noexcept
190       { return _AT_Type::_S_ref(_M_elems, __n); }
192       _GLIBCXX17_CONSTEXPR reference
193       at(size_type __n)
194       {
195         if (__n >= _Nm)
196           std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
197                                             ">= _Nm (which is %zu)"),
198                                         __n, _Nm);
199         return _AT_Type::_S_ref(_M_elems, __n);
200       }
202       constexpr const_reference
203       at(size_type __n) const
204       {
205         // Result of conditional expression must be an lvalue so use
206         // boolean ? lvalue : (throw-expr, lvalue)
207         return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
208           : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
209                                                ">= _Nm (which is %zu)"),
210                                            __n, _Nm),
211              _AT_Type::_S_ref(_M_elems, 0));
212       }
214       _GLIBCXX17_CONSTEXPR reference
215       front() noexcept
216       { return *begin(); }
218       constexpr const_reference
219       front() const noexcept
220       { return _AT_Type::_S_ref(_M_elems, 0); }
222       _GLIBCXX17_CONSTEXPR reference
223       back() noexcept
224       { return _Nm ? *(end() - 1) : *end(); }
226       constexpr const_reference
227       back() const noexcept
228       {
229         return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
230                    : _AT_Type::_S_ref(_M_elems, 0);
231       }
233       _GLIBCXX17_CONSTEXPR pointer
234       data() noexcept
235       { return _AT_Type::_S_ptr(_M_elems); }
237       _GLIBCXX17_CONSTEXPR const_pointer
238       data() const noexcept
239       { return _AT_Type::_S_ptr(_M_elems); }
240     };
242 #if __cpp_deduction_guides >= 201606
243   template<typename _Tp, typename... _Up>
244     array(_Tp, _Up...)
245       -> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>,
246                1 + sizeof...(_Up)>;
247 #endif
249   // Array comparisons.
250   template<typename _Tp, std::size_t _Nm>
251     inline bool
252     operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
253     { return std::equal(__one.begin(), __one.end(), __two.begin()); }
255   template<typename _Tp, std::size_t _Nm>
256     inline bool
257     operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
258     { return !(__one == __two); }
260   template<typename _Tp, std::size_t _Nm>
261     inline bool
262     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
263     {
264       return std::lexicographical_compare(__a.begin(), __a.end(),
265                                           __b.begin(), __b.end());
266     }
268   template<typename _Tp, std::size_t _Nm>
269     inline bool
270     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
271     { return __two < __one; }
273   template<typename _Tp, std::size_t _Nm>
274     inline bool
275     operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
276     { return !(__one > __two); }
278   template<typename _Tp, std::size_t _Nm>
279     inline bool
280     operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
281     { return !(__one < __two); }
283   // Specialized algorithms.
284   template<typename _Tp, std::size_t _Nm>
285     inline
286 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
287     // Constrained free swap overload, see p0185r1
288     typename enable_if<
289       _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value
290     >::type
291 #else
292     void
293 #endif
294     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
295     noexcept(noexcept(__one.swap(__two)))
296     { __one.swap(__two); }
298 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
299   template<typename _Tp, std::size_t _Nm>
300     typename enable_if<
301       !_GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value>::type
302     swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
303 #endif
305   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
306     constexpr _Tp&
307     get(array<_Tp, _Nm>& __arr) noexcept
308     {
309       static_assert(_Int < _Nm, "array index is within bounds");
310       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
311         _S_ref(__arr._M_elems, _Int);
312     }
314   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
315     constexpr _Tp&&
316     get(array<_Tp, _Nm>&& __arr) noexcept
317     {
318       static_assert(_Int < _Nm, "array index is within bounds");
319       return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
320     }
322   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
323     constexpr const _Tp&
324     get(const array<_Tp, _Nm>& __arr) noexcept
325     {
326       static_assert(_Int < _Nm, "array index is within bounds");
327       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
328         _S_ref(__arr._M_elems, _Int);
329     }
331   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
332     constexpr const _Tp&&
333     get(const array<_Tp, _Nm>&& __arr) noexcept
334     {
335       static_assert(_Int < _Nm, "array index is within bounds");
336       return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
337     }
339 _GLIBCXX_END_NAMESPACE_CONTAINER
340 } // namespace std
342 namespace std _GLIBCXX_VISIBILITY(default)
344 _GLIBCXX_BEGIN_NAMESPACE_VERSION
346   // Tuple interface to class template array.
348   /// tuple_size
349   template<typename _Tp>
350     struct tuple_size;
352   /// Partial specialization for std::array
353   template<typename _Tp, std::size_t _Nm>
354     struct tuple_size<_GLIBCXX_STD_C::array<_Tp, _Nm>>
355     : public integral_constant<std::size_t, _Nm> { };
357   /// tuple_element
358   template<std::size_t _Int, typename _Tp>
359     struct tuple_element;
361   /// Partial specialization for std::array
362   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
363     struct tuple_element<_Int, _GLIBCXX_STD_C::array<_Tp, _Nm>>
364     {
365       static_assert(_Int < _Nm, "index is out of bounds");
366       typedef _Tp type;
367     };
369   template<typename _Tp, std::size_t _Nm>
370     struct __is_tuple_like_impl<_GLIBCXX_STD_C::array<_Tp, _Nm>> : true_type
371     { };
373 _GLIBCXX_END_NAMESPACE_VERSION
374 } // namespace std
376 #ifdef _GLIBCXX_DEBUG
377 # include <debug/array>
378 #endif
380 #ifdef _GLIBCXX_PROFILE
381 # include <profile/array>
382 #endif
384 #endif // C++11
386 #endif // _GLIBCXX_ARRAY