]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/array
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / std / array
CommitLineData
bec9a462 1// <array> -*- C++ -*-
2
fbd26352 3// Copyright (C) 2007-2019 Free Software Foundation, Inc.
bec9a462 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
6bc9506f 8// Free Software Foundation; either version 3, or (at your option)
bec9a462 9// any later version.
10
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.
15
6bc9506f 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.
bec9a462 19
6bc9506f 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/>.
bec9a462 24
25/** @file include/array
26 * This is a Standard C++ Library header.
27 */
28
8965c264 29#ifndef _GLIBCXX_ARRAY
30#define _GLIBCXX_ARRAY 1
bec9a462 31
32#pragma GCC system_header
33
0c8766b1 34#if __cplusplus < 201103L
d5ad42a1 35# include <bits/c++0x_warning.h>
34e94b7c 36#else
bec9a462 37
a1d0f6e1 38#include <utility>
928134ff 39#include <stdexcept>
c17b0a1c 40#include <bits/stl_algobase.h>
04707963 41#include <bits/range_access.h>
c17b0a1c 42
2948dd21 43namespace std _GLIBCXX_VISIBILITY(default)
44{
2c09be36 45_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
5022cf3f 46
33efe4a6 47 template<typename _Tp, std::size_t _Nm>
48 struct __array_traits
49 {
50 typedef _Tp _Type[_Nm];
ca9fde3d 51 typedef __is_swappable<_Tp> _Is_swappable;
52 typedef __is_nothrow_swappable<_Tp> _Is_nothrow_swappable;
33efe4a6 53
54 static constexpr _Tp&
55 _S_ref(const _Type& __t, std::size_t __n) noexcept
56 { return const_cast<_Tp&>(__t[__n]); }
fcf3dfea 57
58 static constexpr _Tp*
59 _S_ptr(const _Type& __t) noexcept
60 { return const_cast<_Tp*>(__t); }
33efe4a6 61 };
62
63 template<typename _Tp>
64 struct __array_traits<_Tp, 0>
65 {
66 struct _Type { };
ca9fde3d 67 typedef true_type _Is_swappable;
68 typedef true_type _Is_nothrow_swappable;
33efe4a6 69
70 static constexpr _Tp&
71 _S_ref(const _Type&, std::size_t) noexcept
72 { return *static_cast<_Tp*>(nullptr); }
fcf3dfea 73
74 static constexpr _Tp*
75 _S_ptr(const _Type&) noexcept
76 { return nullptr; }
33efe4a6 77 };
78
5022cf3f 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 *
7184845c 90 * @tparam Tp Type of element. Required to be a complete type.
91 * @tparam N Number of elements.
5022cf3f 92 */
93 template<typename _Tp, std::size_t _Nm>
94 struct array
95 {
96 typedef _Tp value_type;
241361d8 97 typedef value_type* pointer;
98 typedef const value_type* const_pointer;
5022cf3f 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;
107
108 // Support for zero-sized arrays mandatory.
2c09be36 109 typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type;
110 typename _AT_Type::_Type _M_elems;
5022cf3f 111
112 // No explicit construct/copy/destroy for aggregate type.
113
114 // DR 776.
115 void
116 fill(const value_type& __u)
117 { std::fill_n(begin(), size(), __u); }
118
119 void
120 swap(array& __other)
ca9fde3d 121 noexcept(_AT_Type::_Is_nothrow_swappable::value)
5022cf3f 122 { std::swap_ranges(begin(), end(), __other.begin()); }
123
124 // Iterators.
cbf64566 125 _GLIBCXX17_CONSTEXPR iterator
cb17d4f2 126 begin() noexcept
241361d8 127 { return iterator(data()); }
5022cf3f 128
cbf64566 129 _GLIBCXX17_CONSTEXPR const_iterator
cb17d4f2 130 begin() const noexcept
241361d8 131 { return const_iterator(data()); }
5022cf3f 132
cbf64566 133 _GLIBCXX17_CONSTEXPR iterator
cb17d4f2 134 end() noexcept
241361d8 135 { return iterator(data() + _Nm); }
5022cf3f 136
cbf64566 137 _GLIBCXX17_CONSTEXPR const_iterator
cb17d4f2 138 end() const noexcept
241361d8 139 { return const_iterator(data() + _Nm); }
5022cf3f 140
cbf64566 141 _GLIBCXX17_CONSTEXPR reverse_iterator
cb17d4f2 142 rbegin() noexcept
5022cf3f 143 { return reverse_iterator(end()); }
144
cbf64566 145 _GLIBCXX17_CONSTEXPR const_reverse_iterator
cb17d4f2 146 rbegin() const noexcept
5022cf3f 147 { return const_reverse_iterator(end()); }
148
cbf64566 149 _GLIBCXX17_CONSTEXPR reverse_iterator
cb17d4f2 150 rend() noexcept
5022cf3f 151 { return reverse_iterator(begin()); }
152
cbf64566 153 _GLIBCXX17_CONSTEXPR const_reverse_iterator
cb17d4f2 154 rend() const noexcept
5022cf3f 155 { return const_reverse_iterator(begin()); }
156
cbf64566 157 _GLIBCXX17_CONSTEXPR const_iterator
cb17d4f2 158 cbegin() const noexcept
33efe4a6 159 { return const_iterator(data()); }
5022cf3f 160
cbf64566 161 _GLIBCXX17_CONSTEXPR const_iterator
cb17d4f2 162 cend() const noexcept
33efe4a6 163 { return const_iterator(data() + _Nm); }
5022cf3f 164
cbf64566 165 _GLIBCXX17_CONSTEXPR const_reverse_iterator
cb17d4f2 166 crbegin() const noexcept
5022cf3f 167 { return const_reverse_iterator(end()); }
168
cbf64566 169 _GLIBCXX17_CONSTEXPR const_reverse_iterator
cb17d4f2 170 crend() const noexcept
5022cf3f 171 { return const_reverse_iterator(begin()); }
172
173 // Capacity.
fb809cfc 174 constexpr size_type
cb17d4f2 175 size() const noexcept { return _Nm; }
5022cf3f 176
fb809cfc 177 constexpr size_type
cb17d4f2 178 max_size() const noexcept { return _Nm; }
5022cf3f 179
fb809cfc 180 constexpr bool
cb17d4f2 181 empty() const noexcept { return size() == 0; }
5022cf3f 182
183 // Element access.
cbf64566 184 _GLIBCXX17_CONSTEXPR reference
c79d2ed3 185 operator[](size_type __n) noexcept
33efe4a6 186 { return _AT_Type::_S_ref(_M_elems, __n); }
5022cf3f 187
928134ff 188 constexpr const_reference
189 operator[](size_type __n) const noexcept
33efe4a6 190 { return _AT_Type::_S_ref(_M_elems, __n); }
5022cf3f 191
cbf64566 192 _GLIBCXX17_CONSTEXPR reference
5022cf3f 193 at(size_type __n)
194 {
195 if (__n >= _Nm)
b473f47f 196 std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
197 ">= _Nm (which is %zu)"),
198 __n, _Nm);
33efe4a6 199 return _AT_Type::_S_ref(_M_elems, __n);
5022cf3f 200 }
201
928134ff 202 constexpr const_reference
5022cf3f 203 at(size_type __n) const
204 {
88580495 205 // Result of conditional expression must be an lvalue so use
206 // boolean ? lvalue : (throw-expr, lvalue)
33efe4a6 207 return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
b473f47f 208 : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
209 ">= _Nm (which is %zu)"),
210 __n, _Nm),
33efe4a6 211 _AT_Type::_S_ref(_M_elems, 0));
5f431e00 212 }
5022cf3f 213
cbf64566 214 _GLIBCXX17_CONSTEXPR reference
c79d2ed3 215 front() noexcept
5022cf3f 216 { return *begin(); }
217
fb809cfc 218 constexpr const_reference
c79d2ed3 219 front() const noexcept
a558fd42 220 { return _AT_Type::_S_ref(_M_elems, 0); }
5022cf3f 221
cbf64566 222 _GLIBCXX17_CONSTEXPR reference
c79d2ed3 223 back() noexcept
5022cf3f 224 { return _Nm ? *(end() - 1) : *end(); }
225
fb809cfc 226 constexpr const_reference
c79d2ed3 227 back() const noexcept
fb809cfc 228 {
229 return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
2c09be36 230 : _AT_Type::_S_ref(_M_elems, 0);
a558fd42 231 }
5022cf3f 232
cbf64566 233 _GLIBCXX17_CONSTEXPR pointer
cb17d4f2 234 data() noexcept
fcf3dfea 235 { return _AT_Type::_S_ptr(_M_elems); }
5022cf3f 236
cbf64566 237 _GLIBCXX17_CONSTEXPR const_pointer
cb17d4f2 238 data() const noexcept
fcf3dfea 239 { return _AT_Type::_S_ptr(_M_elems); }
5022cf3f 240 };
241
43b0b3ac 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
248
5022cf3f 249 // Array comparisons.
250 template<typename _Tp, std::size_t _Nm>
fb809cfc 251 inline bool
5022cf3f 252 operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
253 { return std::equal(__one.begin(), __one.end(), __two.begin()); }
254
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); }
259
260 template<typename _Tp, std::size_t _Nm>
261 inline bool
262 operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
fb809cfc 263 {
5022cf3f 264 return std::lexicographical_compare(__a.begin(), __a.end(),
fb809cfc 265 __b.begin(), __b.end());
5022cf3f 266 }
267
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; }
272
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); }
277
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); }
282
cb17d4f2 283 // Specialized algorithms.
5022cf3f 284 template<typename _Tp, std::size_t _Nm>
ca9fde3d 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
5022cf3f 294 swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
cb17d4f2 295 noexcept(noexcept(__one.swap(__two)))
5022cf3f 296 { __one.swap(__two); }
297
f89b61dd 298#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
299 template<typename _Tp, std::size_t _Nm>
f89b61dd 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
304
5022cf3f 305 template<std::size_t _Int, typename _Tp, std::size_t _Nm>
f749333e 306 constexpr _Tp&
cb17d4f2 307 get(array<_Tp, _Nm>& __arr) noexcept
d2ec08dc 308 {
2fa24ef2 309 static_assert(_Int < _Nm, "array index is within bounds");
2c09be36 310 return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
311 _S_ref(__arr._M_elems, _Int);
d2ec08dc 312 }
5022cf3f 313
cb17d4f2 314 template<std::size_t _Int, typename _Tp, std::size_t _Nm>
f749333e 315 constexpr _Tp&&
cb17d4f2 316 get(array<_Tp, _Nm>&& __arr) noexcept
d2ec08dc 317 {
2fa24ef2 318 static_assert(_Int < _Nm, "array index is within bounds");
b49122a5 319 return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
d2ec08dc 320 }
cb17d4f2 321
5022cf3f 322 template<std::size_t _Int, typename _Tp, std::size_t _Nm>
f749333e 323 constexpr const _Tp&
cb17d4f2 324 get(const array<_Tp, _Nm>& __arr) noexcept
d2ec08dc 325 {
2fa24ef2 326 static_assert(_Int < _Nm, "array index is within bounds");
2c09be36 327 return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
328 _S_ref(__arr._M_elems, _Int);
d2ec08dc 329 }
5022cf3f 330
6d8efcd4 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 }
338
2c09be36 339_GLIBCXX_END_NAMESPACE_CONTAINER
340} // namespace std
341
68ccd75c 342namespace std _GLIBCXX_VISIBILITY(default)
343{
344_GLIBCXX_BEGIN_NAMESPACE_VERSION
345
346 // Tuple interface to class template array.
347
348 /// tuple_size
fb809cfc 349 template<typename _Tp>
995d3275 350 struct tuple_size;
68ccd75c 351
3825cab1 352 /// Partial specialization for std::array
68ccd75c 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> { };
356
357 /// tuple_element
358 template<std::size_t _Int, typename _Tp>
995d3275 359 struct tuple_element;
68ccd75c 360
3825cab1 361 /// Partial specialization for std::array
68ccd75c 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 };
368
a1d0f6e1 369 template<typename _Tp, std::size_t _Nm>
370 struct __is_tuple_like_impl<_GLIBCXX_STD_C::array<_Tp, _Nm>> : true_type
371 { };
372
68ccd75c 373_GLIBCXX_END_NAMESPACE_VERSION
374} // namespace std
375
2c09be36 376#ifdef _GLIBCXX_DEBUG
377# include <debug/array>
378#endif
379
380#ifdef _GLIBCXX_PROFILE
381# include <profile/array>
382#endif
bec9a462 383
0c8766b1 384#endif // C++11
34e94b7c 385
8965c264 386#endif // _GLIBCXX_ARRAY