]>
Commit | Line | Data |
---|---|---|
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 | 43 | namespace 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 | 342 | namespace 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 |