]>
Commit | Line | Data |
---|---|---|
2c09be36 | 1 | // Profile array implementation -*- C++ -*- |
2 | ||
f1717362 | 3 | // Copyright (C) 2012-2016 Free Software Foundation, Inc. |
2c09be36 | 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. | |
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 | ||
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. | |
19 | ||
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/>. | |
24 | ||
25 | /** @file profile/array | |
26 | * This is a Standard C++ Library header. | |
27 | */ | |
28 | ||
29 | #ifndef _GLIBCXX_PROFILE_ARRAY | |
30 | #define _GLIBCXX_PROFILE_ARRAY 1 | |
31 | ||
32 | #pragma GCC system_header | |
33 | ||
a1d0f6e1 | 34 | #include <array> |
35 | ||
2c09be36 | 36 | namespace std _GLIBCXX_VISIBILITY(default) |
37 | { | |
38 | namespace __profile | |
39 | { | |
40 | template<typename _Tp, std::size_t _Nm> | |
41 | struct array | |
42 | { | |
43 | typedef _Tp value_type; | |
44 | typedef value_type* pointer; | |
45 | typedef const value_type* const_pointer; | |
46 | typedef value_type& reference; | |
47 | typedef const value_type& const_reference; | |
48 | typedef value_type* iterator; | |
49 | typedef const value_type* const_iterator; | |
50 | typedef std::size_t size_type; | |
51 | typedef std::ptrdiff_t difference_type; | |
52 | typedef std::reverse_iterator<iterator> reverse_iterator; | |
53 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | |
54 | ||
55 | // Support for zero-sized arrays mandatory. | |
56 | typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type; | |
57 | typename _AT_Type::_Type _M_elems; | |
58 | ||
59 | // No explicit construct/copy/destroy for aggregate type. | |
60 | ||
61 | // DR 776. | |
62 | void | |
63 | fill(const value_type& __u) | |
64 | { std::fill_n(begin(), size(), __u); } | |
65 | ||
66 | void | |
67 | swap(array& __other) | |
b5773487 | 68 | noexcept(__is_nothrow_swappable<_Tp>::value) |
2c09be36 | 69 | { std::swap_ranges(begin(), end(), __other.begin()); } |
70 | ||
71 | // Iterators. | |
72 | iterator | |
73 | begin() noexcept | |
74 | { return iterator(data()); } | |
75 | ||
76 | const_iterator | |
77 | begin() const noexcept | |
78 | { return const_iterator(data()); } | |
79 | ||
80 | iterator | |
81 | end() noexcept | |
82 | { return iterator(data() + _Nm); } | |
83 | ||
84 | const_iterator | |
85 | end() const noexcept | |
86 | { return const_iterator(data() + _Nm); } | |
87 | ||
5f70fed5 | 88 | reverse_iterator |
2c09be36 | 89 | rbegin() noexcept |
90 | { return reverse_iterator(end()); } | |
91 | ||
5f70fed5 | 92 | const_reverse_iterator |
2c09be36 | 93 | rbegin() const noexcept |
94 | { return const_reverse_iterator(end()); } | |
95 | ||
5f70fed5 | 96 | reverse_iterator |
2c09be36 | 97 | rend() noexcept |
98 | { return reverse_iterator(begin()); } | |
99 | ||
5f70fed5 | 100 | const_reverse_iterator |
2c09be36 | 101 | rend() const noexcept |
102 | { return const_reverse_iterator(begin()); } | |
103 | ||
104 | const_iterator | |
105 | cbegin() const noexcept | |
106 | { return const_iterator(data()); } | |
107 | ||
108 | const_iterator | |
109 | cend() const noexcept | |
110 | { return const_iterator(data() + _Nm); } | |
111 | ||
5f70fed5 | 112 | const_reverse_iterator |
2c09be36 | 113 | crbegin() const noexcept |
114 | { return const_reverse_iterator(end()); } | |
115 | ||
5f70fed5 | 116 | const_reverse_iterator |
2c09be36 | 117 | crend() const noexcept |
118 | { return const_reverse_iterator(begin()); } | |
119 | ||
120 | // Capacity. | |
5f70fed5 | 121 | constexpr size_type |
2c09be36 | 122 | size() const noexcept { return _Nm; } |
123 | ||
5f70fed5 | 124 | constexpr size_type |
2c09be36 | 125 | max_size() const noexcept { return _Nm; } |
126 | ||
5f70fed5 | 127 | constexpr bool |
2c09be36 | 128 | empty() const noexcept { return size() == 0; } |
129 | ||
130 | // Element access. | |
131 | reference | |
c79d2ed3 | 132 | operator[](size_type __n) noexcept |
2c09be36 | 133 | { return _AT_Type::_S_ref(_M_elems, __n); } |
134 | ||
135 | constexpr const_reference | |
136 | operator[](size_type __n) const noexcept | |
137 | { return _AT_Type::_S_ref(_M_elems, __n); } | |
138 | ||
139 | reference | |
140 | at(size_type __n) | |
141 | { | |
142 | if (__n >= _Nm) | |
b473f47f | 143 | std::__throw_out_of_range_fmt(__N("array::at: __n " |
144 | "(which is %zu) >= _Nm " | |
145 | "(which is %zu)"), | |
146 | __n, _Nm); | |
2c09be36 | 147 | return _AT_Type::_S_ref(_M_elems, __n); |
148 | } | |
149 | ||
150 | constexpr const_reference | |
151 | at(size_type __n) const | |
152 | { | |
153 | // Result of conditional expression must be an lvalue so use | |
154 | // boolean ? lvalue : (throw-expr, lvalue) | |
155 | return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n) | |
b473f47f | 156 | : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " |
157 | ">= _Nm (which is %zu)"), | |
158 | __n, _Nm), | |
2c09be36 | 159 | _AT_Type::_S_ref(_M_elems, 0)); |
160 | } | |
161 | ||
5f70fed5 | 162 | reference |
c79d2ed3 | 163 | front() noexcept |
2c09be36 | 164 | { return *begin(); } |
165 | ||
5f70fed5 | 166 | constexpr const_reference |
c79d2ed3 | 167 | front() const noexcept |
2c09be36 | 168 | { return _AT_Type::_S_ref(_M_elems, 0); } |
169 | ||
5f70fed5 | 170 | reference |
c79d2ed3 | 171 | back() noexcept |
2c09be36 | 172 | { return _Nm ? *(end() - 1) : *end(); } |
173 | ||
5f70fed5 | 174 | constexpr const_reference |
c79d2ed3 | 175 | back() const noexcept |
2c09be36 | 176 | { |
177 | return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) | |
5f70fed5 | 178 | : _AT_Type::_S_ref(_M_elems, 0); |
2c09be36 | 179 | } |
180 | ||
181 | pointer | |
182 | data() noexcept | |
cbf558ec | 183 | { return _AT_Type::_S_ptr(_M_elems); } |
2c09be36 | 184 | |
185 | const_pointer | |
186 | data() const noexcept | |
cbf558ec | 187 | { return _AT_Type::_S_ptr(_M_elems); } |
2c09be36 | 188 | }; |
189 | ||
190 | // Array comparisons. | |
191 | template<typename _Tp, std::size_t _Nm> | |
5f70fed5 | 192 | inline bool |
2c09be36 | 193 | operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) |
194 | { return std::equal(__one.begin(), __one.end(), __two.begin()); } | |
195 | ||
196 | template<typename _Tp, std::size_t _Nm> | |
197 | inline bool | |
198 | operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) | |
199 | { return !(__one == __two); } | |
200 | ||
201 | template<typename _Tp, std::size_t _Nm> | |
202 | inline bool | |
203 | operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) | |
5f70fed5 | 204 | { |
2c09be36 | 205 | return std::lexicographical_compare(__a.begin(), __a.end(), |
5f70fed5 | 206 | __b.begin(), __b.end()); |
2c09be36 | 207 | } |
208 | ||
209 | template<typename _Tp, std::size_t _Nm> | |
210 | inline bool | |
211 | operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) | |
212 | { return __two < __one; } | |
213 | ||
214 | template<typename _Tp, std::size_t _Nm> | |
215 | inline bool | |
216 | operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) | |
217 | { return !(__one > __two); } | |
218 | ||
219 | template<typename _Tp, std::size_t _Nm> | |
220 | inline bool | |
221 | operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) | |
222 | { return !(__one < __two); } | |
223 | ||
224 | // Specialized algorithms. | |
225 | template<typename _Tp, std::size_t _Nm> | |
226 | inline void | |
227 | swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) | |
228 | noexcept(noexcept(__one.swap(__two))) | |
229 | { __one.swap(__two); } | |
230 | ||
231 | template<std::size_t _Int, typename _Tp, std::size_t _Nm> | |
232 | constexpr _Tp& | |
233 | get(array<_Tp, _Nm>& __arr) noexcept | |
234 | { | |
235 | static_assert(_Int < _Nm, "index is out of bounds"); | |
236 | return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: | |
237 | _S_ref(__arr._M_elems, _Int); | |
238 | } | |
239 | ||
240 | template<std::size_t _Int, typename _Tp, std::size_t _Nm> | |
241 | constexpr _Tp&& | |
242 | get(array<_Tp, _Nm>&& __arr) noexcept | |
243 | { | |
244 | static_assert(_Int < _Nm, "index is out of bounds"); | |
b49122a5 | 245 | return std::move(__profile::get<_Int>(__arr)); |
2c09be36 | 246 | } |
247 | ||
248 | template<std::size_t _Int, typename _Tp, std::size_t _Nm> | |
249 | constexpr const _Tp& | |
250 | get(const array<_Tp, _Nm>& __arr) noexcept | |
251 | { | |
252 | static_assert(_Int < _Nm, "index is out of bounds"); | |
253 | return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: | |
254 | _S_ref(__arr._M_elems, _Int); | |
255 | } | |
256 | } // namespace __profile | |
257 | ||
a1d0f6e1 | 258 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
2c09be36 | 259 | // Tuple interface to class template array. |
260 | ||
261 | /// tuple_size | |
2c09be36 | 262 | template<typename _Tp, std::size_t _Nm> |
a1d0f6e1 | 263 | struct tuple_size<std::__profile::array<_Tp, _Nm>> |
2c09be36 | 264 | : public integral_constant<std::size_t, _Nm> { }; |
265 | ||
266 | /// tuple_element | |
2c09be36 | 267 | template<std::size_t _Int, typename _Tp, std::size_t _Nm> |
a1d0f6e1 | 268 | struct tuple_element<_Int, std::__profile::array<_Tp, _Nm>> |
2c09be36 | 269 | { |
270 | static_assert(_Int < _Nm, "index is out of bounds"); | |
271 | typedef _Tp type; | |
272 | }; | |
a1d0f6e1 | 273 | |
274 | template<typename _Tp, std::size_t _Nm> | |
275 | struct __is_tuple_like_impl<std::__profile::array<_Tp, _Nm>> : true_type | |
276 | { }; | |
277 | ||
278 | _GLIBCXX_END_NAMESPACE_VERSION | |
2c09be36 | 279 | } // namespace std |
280 | ||
281 | #endif // _GLIBCXX_PROFILE_ARRAY |