]>
Commit | Line | Data |
---|---|---|
54c1bf78 | 1 | // The template and inlines for the -*- C++ -*- valarray class. |
de96ac46 | 2 | |
83ffe9cd | 3 | // Copyright (C) 1997-2023 Free Software Foundation, Inc. |
de96ac46 BK |
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 | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
de96ac46 BK |
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 | ||
748086b7 JJ |
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/>. | |
de96ac46 | 24 | |
f910786b | 25 | /** @file include/valarray |
33ac58d5 | 26 | * This is a Standard C++ Library header. |
2f9d51b8 PE |
27 | */ |
28 | ||
143c27b0 BK |
29 | // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> |
30 | ||
1143680e SE |
31 | #ifndef _GLIBCXX_VALARRAY |
32 | #define _GLIBCXX_VALARRAY 1 | |
54c1bf78 BK |
33 | |
34 | #pragma GCC system_header | |
35 | ||
18f176d0 AA |
36 | #include <bits/requires_hosted.h> // <cmath> dependant |
37 | ||
54c1bf78 | 38 | #include <bits/c++config.h> |
54c1bf78 | 39 | #include <cmath> |
54c1bf78 | 40 | #include <algorithm> |
285b36d6 | 41 | #include <debug/debug.h> |
734f5023 | 42 | #if __cplusplus >= 201103L |
988499f4 | 43 | #include <initializer_list> |
a7d5d7e2 | 44 | #endif |
54c1bf78 | 45 | |
12ffa228 BK |
46 | namespace std _GLIBCXX_VISIBILITY(default) |
47 | { | |
48 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
3cbc7af0 | 49 | |
33ac58d5 | 50 | template<class _Clos, typename _Tp> |
74d6b8ca | 51 | class _Expr; |
54c1bf78 | 52 | |
33ac58d5 JW |
53 | template<typename _Tp1, typename _Tp2> |
54 | class _ValArray; | |
54c1bf78 | 55 | |
1b749ae9 JW |
56 | namespace __detail |
57 | { | |
74d6b8ca GDR |
58 | template<class _Oper, template<class, class> class _Meta, class _Dom> |
59 | struct _UnClos; | |
54c1bf78 | 60 | |
971cfc6f | 61 | template<class _Oper, |
54c1bf78 BK |
62 | template<class, class> class _Meta1, |
63 | template<class, class> class _Meta2, | |
33ac58d5 | 64 | class _Dom1, class _Dom2> |
74d6b8ca | 65 | class _BinClos; |
54c1bf78 | 66 | |
33ac58d5 | 67 | template<template<class, class> class _Meta, class _Dom> |
74d6b8ca | 68 | class _SClos; |
54c1bf78 | 69 | |
33ac58d5 | 70 | template<template<class, class> class _Meta, class _Dom> |
74d6b8ca | 71 | class _GClos; |
33ac58d5 JW |
72 | |
73 | template<template<class, class> class _Meta, class _Dom> | |
74d6b8ca | 74 | class _IClos; |
33ac58d5 JW |
75 | |
76 | template<template<class, class> class _Meta, class _Dom> | |
74d6b8ca | 77 | class _ValFunClos; |
33ac58d5 JW |
78 | |
79 | template<template<class, class> class _Meta, class _Dom> | |
74d6b8ca | 80 | class _RefFunClos; |
1b749ae9 JW |
81 | } // namespace __detail |
82 | ||
83 | using __detail::_UnClos; | |
84 | using __detail::_BinClos; | |
85 | using __detail::_SClos; | |
86 | using __detail::_GClos; | |
87 | using __detail::_IClos; | |
88 | using __detail::_ValFunClos; | |
89 | using __detail::_RefFunClos; | |
74d6b8ca | 90 | |
74d6b8ca GDR |
91 | template<class _Tp> class valarray; // An array of type _Tp |
92 | class slice; // BLAS-like slice out of an array | |
93 | template<class _Tp> class slice_array; | |
94 | class gslice; // generalized slice out of an array | |
95 | template<class _Tp> class gslice_array; | |
96 | template<class _Tp> class mask_array; // masked array | |
97 | template<class _Tp> class indirect_array; // indirected array | |
54c1bf78 | 98 | |
12ffa228 BK |
99 | _GLIBCXX_END_NAMESPACE_VERSION |
100 | } // namespace | |
54c1bf78 BK |
101 | |
102 | #include <bits/valarray_array.h> | |
c13bea50 | 103 | #include <bits/valarray_before.h> |
33ac58d5 | 104 | |
12ffa228 BK |
105 | namespace std _GLIBCXX_VISIBILITY(default) |
106 | { | |
107 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
3cbc7af0 | 108 | |
5b9daa7e BK |
109 | /** |
110 | * @defgroup numeric_arrays Numeric Arrays | |
111 | * @ingroup numerics | |
112 | * | |
113 | * Classes and functions for representing and manipulating arrays of elements. | |
114 | * @{ | |
115 | */ | |
116 | ||
7fb397a4 JQ |
117 | /** |
118 | * @brief Smart array designed to support numeric processing. | |
119 | * | |
120 | * A valarray is an array that provides constraints intended to allow for | |
121 | * effective optimization of numeric array processing by reducing the | |
122 | * aliasing that can result from pointer representations. It represents a | |
123 | * one-dimensional array from which different multidimensional subsets can | |
124 | * be accessed and modified. | |
33ac58d5 | 125 | * |
93c66bc6 | 126 | * @tparam _Tp Type of object in the array. |
7fb397a4 | 127 | */ |
33ac58d5 | 128 | template<class _Tp> |
74d6b8ca GDR |
129 | class valarray |
130 | { | |
131 | template<class _Op> | |
33ac58d5 | 132 | struct _UnaryOp |
74d6b8ca GDR |
133 | { |
134 | typedef typename __fun<_Op, _Tp>::result_type __rt; | |
135 | typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt; | |
136 | }; | |
137 | public: | |
54c1bf78 | 138 | typedef _Tp value_type; |
33ac58d5 | 139 | |
74d6b8ca | 140 | // _lib.valarray.cons_ construct/destroy: |
7fb397a4 | 141 | /// Construct an empty array. |
4f032929 | 142 | valarray() _GLIBCXX_NOTHROW; |
7fb397a4 JQ |
143 | |
144 | /// Construct an array with @a n elements. | |
54c1bf78 | 145 | explicit valarray(size_t); |
7fb397a4 JQ |
146 | |
147 | /// Construct an array with @a n elements initialized to @a t. | |
54c1bf78 | 148 | valarray(const _Tp&, size_t); |
7fb397a4 JQ |
149 | |
150 | /// Construct an array initialized to the first @a n elements of @a t. | |
54c1bf78 | 151 | valarray(const _Tp* __restrict__, size_t); |
7fb397a4 JQ |
152 | |
153 | /// Copy constructor. | |
54c1bf78 | 154 | valarray(const valarray&); |
7fb397a4 | 155 | |
734f5023 | 156 | #if __cplusplus >= 201103L |
8a3cabe3 PC |
157 | /// Move constructor. |
158 | valarray(valarray&&) noexcept; | |
159 | #endif | |
160 | ||
7fb397a4 | 161 | /// Construct an array with the same size and values in @a sa. |
54c1bf78 | 162 | valarray(const slice_array<_Tp>&); |
7fb397a4 JQ |
163 | |
164 | /// Construct an array with the same size and values in @a ga. | |
54c1bf78 | 165 | valarray(const gslice_array<_Tp>&); |
7fb397a4 JQ |
166 | |
167 | /// Construct an array with the same size and values in @a ma. | |
54c1bf78 | 168 | valarray(const mask_array<_Tp>&); |
7fb397a4 JQ |
169 | |
170 | /// Construct an array with the same size and values in @a ia. | |
54c1bf78 | 171 | valarray(const indirect_array<_Tp>&); |
7fb397a4 | 172 | |
734f5023 | 173 | #if __cplusplus >= 201103L |
988499f4 JM |
174 | /// Construct an array with an initializer_list of values. |
175 | valarray(initializer_list<_Tp>); | |
176 | #endif | |
177 | ||
54c1bf78 | 178 | template<class _Dom> |
b714a419 PC |
179 | valarray(const _Expr<_Dom, _Tp>& __e); |
180 | ||
6a97dbf7 | 181 | ~valarray() _GLIBCXX_NOEXCEPT; |
54c1bf78 BK |
182 | |
183 | // _lib.valarray.assign_ assignment: | |
7fb397a4 JQ |
184 | /** |
185 | * @brief Assign elements to an array. | |
186 | * | |
8a3cabe3 | 187 | * Assign elements of array to values in @a v. |
7fb397a4 | 188 | * |
93c66bc6 | 189 | * @param __v Valarray to get values from. |
7fb397a4 | 190 | */ |
93c66bc6 | 191 | valarray<_Tp>& operator=(const valarray<_Tp>& __v); |
7fb397a4 | 192 | |
734f5023 | 193 | #if __cplusplus >= 201103L |
8a3cabe3 PC |
194 | /** |
195 | * @brief Move assign elements to an array. | |
196 | * | |
197 | * Move assign elements of array to values in @a v. | |
198 | * | |
93c66bc6 | 199 | * @param __v Valarray to get values from. |
8a3cabe3 | 200 | */ |
93c66bc6 | 201 | valarray<_Tp>& operator=(valarray<_Tp>&& __v) noexcept; |
8a3cabe3 PC |
202 | #endif |
203 | ||
7fb397a4 JQ |
204 | /** |
205 | * @brief Assign elements to a value. | |
206 | * | |
207 | * Assign all elements of array to @a t. | |
208 | * | |
93c66bc6 | 209 | * @param __t Value for elements. |
7fb397a4 | 210 | */ |
93c66bc6 | 211 | valarray<_Tp>& operator=(const _Tp& __t); |
7fb397a4 JQ |
212 | |
213 | /** | |
214 | * @brief Assign elements to an array subset. | |
215 | * | |
216 | * Assign elements of array to values in @a sa. Results are undefined | |
dc5fef6a | 217 | * if @a sa does not have the same size as this array. |
7fb397a4 | 218 | * |
93c66bc6 | 219 | * @param __sa Array slice to get values from. |
7fb397a4 | 220 | */ |
93c66bc6 | 221 | valarray<_Tp>& operator=(const slice_array<_Tp>& __sa); |
7fb397a4 JQ |
222 | |
223 | /** | |
224 | * @brief Assign elements to an array subset. | |
225 | * | |
226 | * Assign elements of array to values in @a ga. Results are undefined | |
dc5fef6a | 227 | * if @a ga does not have the same size as this array. |
7fb397a4 | 228 | * |
93c66bc6 | 229 | * @param __ga Array slice to get values from. |
7fb397a4 | 230 | */ |
93c66bc6 | 231 | valarray<_Tp>& operator=(const gslice_array<_Tp>& __ga); |
7fb397a4 JQ |
232 | |
233 | /** | |
234 | * @brief Assign elements to an array subset. | |
235 | * | |
236 | * Assign elements of array to values in @a ma. Results are undefined | |
dc5fef6a | 237 | * if @a ma does not have the same size as this array. |
7fb397a4 | 238 | * |
93c66bc6 | 239 | * @param __ma Array slice to get values from. |
7fb397a4 | 240 | */ |
93c66bc6 | 241 | valarray<_Tp>& operator=(const mask_array<_Tp>& __ma); |
7fb397a4 JQ |
242 | |
243 | /** | |
244 | * @brief Assign elements to an array subset. | |
245 | * | |
246 | * Assign elements of array to values in @a ia. Results are undefined | |
dc5fef6a | 247 | * if @a ia does not have the same size as this array. |
7fb397a4 | 248 | * |
93c66bc6 | 249 | * @param __ia Array slice to get values from. |
7fb397a4 | 250 | */ |
93c66bc6 | 251 | valarray<_Tp>& operator=(const indirect_array<_Tp>& __ia); |
54c1bf78 | 252 | |
734f5023 | 253 | #if __cplusplus >= 201103L |
988499f4 JM |
254 | /** |
255 | * @brief Assign elements to an initializer_list. | |
256 | * | |
93c66bc6 BK |
257 | * Assign elements of array to values in @a __l. Results are undefined |
258 | * if @a __l does not have the same size as this array. | |
988499f4 | 259 | * |
93c66bc6 | 260 | * @param __l initializer_list to get values from. |
988499f4 | 261 | */ |
93c66bc6 | 262 | valarray& operator=(initializer_list<_Tp> __l); |
988499f4 JM |
263 | #endif |
264 | ||
54c1bf78 | 265 | template<class _Dom> valarray<_Tp>& |
b714a419 | 266 | operator= (const _Expr<_Dom, _Tp>&); |
54c1bf78 BK |
267 | |
268 | // _lib.valarray.access_ element access: | |
7fb397a4 | 269 | /** |
33ac58d5 | 270 | * Return a reference to the i'th array element. |
7fb397a4 | 271 | * |
93c66bc6 | 272 | * @param __i Index of element to return. |
7fb397a4 JQ |
273 | * @return Reference to the i'th element. |
274 | */ | |
4f032929 | 275 | _Tp& operator[](size_t __i) _GLIBCXX_NOTHROW; |
7fb397a4 | 276 | |
2787b59a PC |
277 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
278 | // 389. Const overload of valarray::operator[] returns by value. | |
4f032929 | 279 | const _Tp& operator[](size_t) const _GLIBCXX_NOTHROW; |
7fb397a4 | 280 | |
54c1bf78 | 281 | // _lib.valarray.sub_ subset operations: |
7fb397a4 JQ |
282 | /** |
283 | * @brief Return an array subset. | |
284 | * | |
285 | * Returns a new valarray containing the elements of the array | |
dc5fef6a VR |
286 | * indicated by the slice argument. The new valarray has the same size |
287 | * as the input slice. @see slice. | |
7fb397a4 | 288 | * |
93c66bc6 BK |
289 | * @param __s The source slice. |
290 | * @return New valarray containing elements in @a __s. | |
7fb397a4 | 291 | */ |
93c66bc6 | 292 | _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice __s) const; |
7fb397a4 JQ |
293 | |
294 | /** | |
295 | * @brief Return a reference to an array subset. | |
296 | * | |
297 | * Returns a new valarray containing the elements of the array | |
dc5fef6a VR |
298 | * indicated by the slice argument. The new valarray has the same size |
299 | * as the input slice. @see slice. | |
7fb397a4 | 300 | * |
93c66bc6 BK |
301 | * @param __s The source slice. |
302 | * @return New valarray containing elements in @a __s. | |
7fb397a4 | 303 | */ |
93c66bc6 | 304 | slice_array<_Tp> operator[](slice __s); |
7fb397a4 JQ |
305 | |
306 | /** | |
307 | * @brief Return an array subset. | |
308 | * | |
309 | * Returns a slice_array referencing the elements of the array | |
310 | * indicated by the slice argument. @see gslice. | |
311 | * | |
93c66bc6 BK |
312 | * @param __s The source slice. |
313 | * @return Slice_array referencing elements indicated by @a __s. | |
7fb397a4 | 314 | */ |
93c66bc6 | 315 | _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice& __s) const; |
7fb397a4 JQ |
316 | |
317 | /** | |
318 | * @brief Return a reference to an array subset. | |
319 | * | |
320 | * Returns a new valarray containing the elements of the array | |
dc5fef6a VR |
321 | * indicated by the gslice argument. The new valarray has |
322 | * the same size as the input gslice. @see gslice. | |
7fb397a4 | 323 | * |
93c66bc6 BK |
324 | * @param __s The source gslice. |
325 | * @return New valarray containing elements in @a __s. | |
7fb397a4 | 326 | */ |
93c66bc6 | 327 | gslice_array<_Tp> operator[](const gslice& __s); |
7fb397a4 JQ |
328 | |
329 | /** | |
330 | * @brief Return an array subset. | |
331 | * | |
332 | * Returns a new valarray containing the elements of the array | |
333 | * indicated by the argument. The input is a valarray of bool which | |
334 | * represents a bitmask indicating which elements should be copied into | |
335 | * the new valarray. Each element of the array is added to the return | |
336 | * valarray if the corresponding element of the argument is true. | |
337 | * | |
93c66bc6 BK |
338 | * @param __m The valarray bitmask. |
339 | * @return New valarray containing elements indicated by @a __m. | |
7fb397a4 | 340 | */ |
93c66bc6 | 341 | valarray<_Tp> operator[](const valarray<bool>& __m) const; |
7fb397a4 JQ |
342 | |
343 | /** | |
344 | * @brief Return a reference to an array subset. | |
345 | * | |
346 | * Returns a new mask_array referencing the elements of the array | |
347 | * indicated by the argument. The input is a valarray of bool which | |
348 | * represents a bitmask indicating which elements are part of the | |
349 | * subset. Elements of the array are part of the subset if the | |
350 | * corresponding element of the argument is true. | |
351 | * | |
93c66bc6 BK |
352 | * @param __m The valarray bitmask. |
353 | * @return New valarray containing elements indicated by @a __m. | |
7fb397a4 | 354 | */ |
93c66bc6 | 355 | mask_array<_Tp> operator[](const valarray<bool>& __m); |
7fb397a4 JQ |
356 | |
357 | /** | |
358 | * @brief Return an array subset. | |
359 | * | |
360 | * Returns a new valarray containing the elements of the array | |
361 | * indicated by the argument. The elements in the argument are | |
362 | * interpreted as the indices of elements of this valarray to copy to | |
363 | * the return valarray. | |
364 | * | |
93c66bc6 BK |
365 | * @param __i The valarray element index list. |
366 | * @return New valarray containing elements in @a __s. | |
7fb397a4 | 367 | */ |
54c1bf78 | 368 | _Expr<_IClos<_ValArray, _Tp>, _Tp> |
93c66bc6 | 369 | operator[](const valarray<size_t>& __i) const; |
7fb397a4 JQ |
370 | |
371 | /** | |
372 | * @brief Return a reference to an array subset. | |
373 | * | |
374 | * Returns an indirect_array referencing the elements of the array | |
375 | * indicated by the argument. The elements in the argument are | |
376 | * interpreted as the indices of elements of this valarray to include | |
377 | * in the subset. The returned indirect_array refers to these | |
378 | * elements. | |
379 | * | |
93c66bc6 BK |
380 | * @param __i The valarray element index list. |
381 | * @return Indirect_array referencing elements in @a __i. | |
7fb397a4 | 382 | */ |
93c66bc6 | 383 | indirect_array<_Tp> operator[](const valarray<size_t>& __i); |
54c1bf78 BK |
384 | |
385 | // _lib.valarray.unary_ unary operators: | |
7fb397a4 | 386 | /// Return a new valarray by applying unary + to each element. |
74d6b8ca | 387 | typename _UnaryOp<__unary_plus>::_Rt operator+() const; |
7fb397a4 JQ |
388 | |
389 | /// Return a new valarray by applying unary - to each element. | |
74d6b8ca | 390 | typename _UnaryOp<__negate>::_Rt operator-() const; |
7fb397a4 JQ |
391 | |
392 | /// Return a new valarray by applying unary ~ to each element. | |
74d6b8ca | 393 | typename _UnaryOp<__bitwise_not>::_Rt operator~() const; |
7fb397a4 JQ |
394 | |
395 | /// Return a new valarray by applying unary ! to each element. | |
74d6b8ca GDR |
396 | typename _UnaryOp<__logical_not>::_Rt operator!() const; |
397 | ||
54c1bf78 | 398 | // _lib.valarray.cassign_ computed assignment: |
7fb397a4 | 399 | /// Multiply each element of array by @a t. |
74d6b8ca | 400 | valarray<_Tp>& operator*=(const _Tp&); |
7fb397a4 JQ |
401 | |
402 | /// Divide each element of array by @a t. | |
74d6b8ca | 403 | valarray<_Tp>& operator/=(const _Tp&); |
7fb397a4 JQ |
404 | |
405 | /// Set each element e of array to e % @a t. | |
74d6b8ca | 406 | valarray<_Tp>& operator%=(const _Tp&); |
7fb397a4 JQ |
407 | |
408 | /// Add @a t to each element of array. | |
74d6b8ca | 409 | valarray<_Tp>& operator+=(const _Tp&); |
7fb397a4 JQ |
410 | |
411 | /// Subtract @a t to each element of array. | |
74d6b8ca | 412 | valarray<_Tp>& operator-=(const _Tp&); |
7fb397a4 JQ |
413 | |
414 | /// Set each element e of array to e ^ @a t. | |
74d6b8ca | 415 | valarray<_Tp>& operator^=(const _Tp&); |
7fb397a4 JQ |
416 | |
417 | /// Set each element e of array to e & @a t. | |
74d6b8ca | 418 | valarray<_Tp>& operator&=(const _Tp&); |
7fb397a4 JQ |
419 | |
420 | /// Set each element e of array to e | @a t. | |
74d6b8ca | 421 | valarray<_Tp>& operator|=(const _Tp&); |
7fb397a4 JQ |
422 | |
423 | /// Left shift each element e of array by @a t bits. | |
54c1bf78 | 424 | valarray<_Tp>& operator<<=(const _Tp&); |
7fb397a4 JQ |
425 | |
426 | /// Right shift each element e of array by @a t bits. | |
54c1bf78 | 427 | valarray<_Tp>& operator>>=(const _Tp&); |
7fb397a4 JQ |
428 | |
429 | /// Multiply elements of array by corresponding elements of @a v. | |
74d6b8ca | 430 | valarray<_Tp>& operator*=(const valarray<_Tp>&); |
7fb397a4 JQ |
431 | |
432 | /// Divide elements of array by corresponding elements of @a v. | |
74d6b8ca | 433 | valarray<_Tp>& operator/=(const valarray<_Tp>&); |
7fb397a4 JQ |
434 | |
435 | /// Modulo elements of array by corresponding elements of @a v. | |
74d6b8ca | 436 | valarray<_Tp>& operator%=(const valarray<_Tp>&); |
7fb397a4 JQ |
437 | |
438 | /// Add corresponding elements of @a v to elements of array. | |
74d6b8ca | 439 | valarray<_Tp>& operator+=(const valarray<_Tp>&); |
7fb397a4 JQ |
440 | |
441 | /// Subtract corresponding elements of @a v from elements of array. | |
74d6b8ca | 442 | valarray<_Tp>& operator-=(const valarray<_Tp>&); |
7fb397a4 JQ |
443 | |
444 | /// Logical xor corresponding elements of @a v with elements of array. | |
74d6b8ca | 445 | valarray<_Tp>& operator^=(const valarray<_Tp>&); |
7fb397a4 JQ |
446 | |
447 | /// Logical or corresponding elements of @a v with elements of array. | |
74d6b8ca | 448 | valarray<_Tp>& operator|=(const valarray<_Tp>&); |
7fb397a4 JQ |
449 | |
450 | /// Logical and corresponding elements of @a v with elements of array. | |
74d6b8ca | 451 | valarray<_Tp>& operator&=(const valarray<_Tp>&); |
7fb397a4 JQ |
452 | |
453 | /// Left shift elements of array by corresponding elements of @a v. | |
54c1bf78 | 454 | valarray<_Tp>& operator<<=(const valarray<_Tp>&); |
7fb397a4 JQ |
455 | |
456 | /// Right shift elements of array by corresponding elements of @a v. | |
54c1bf78 BK |
457 | valarray<_Tp>& operator>>=(const valarray<_Tp>&); |
458 | ||
459 | template<class _Dom> | |
b714a419 | 460 | valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&); |
54c1bf78 | 461 | template<class _Dom> |
b714a419 | 462 | valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&); |
54c1bf78 | 463 | template<class _Dom> |
b714a419 | 464 | valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&); |
54c1bf78 | 465 | template<class _Dom> |
b714a419 | 466 | valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&); |
54c1bf78 | 467 | template<class _Dom> |
b714a419 | 468 | valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&); |
54c1bf78 | 469 | template<class _Dom> |
b714a419 | 470 | valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&); |
54c1bf78 | 471 | template<class _Dom> |
b714a419 | 472 | valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&); |
54c1bf78 | 473 | template<class _Dom> |
b714a419 | 474 | valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&); |
54c1bf78 | 475 | template<class _Dom> |
b714a419 | 476 | valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&); |
54c1bf78 | 477 | template<class _Dom> |
b714a419 | 478 | valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&); |
54c1bf78 | 479 | |
54c1bf78 | 480 | // _lib.valarray.members_ member functions: |
734f5023 | 481 | #if __cplusplus >= 201103L |
8a3cabe3 PC |
482 | /// Swap. |
483 | void swap(valarray<_Tp>& __v) noexcept; | |
484 | #endif | |
485 | ||
7fb397a4 | 486 | /// Return the number of elements in array. |
54c1bf78 | 487 | size_t size() const; |
7fb397a4 JQ |
488 | |
489 | /** | |
490 | * @brief Return the sum of all elements in the array. | |
491 | * | |
492 | * Accumulates the sum of all elements into a Tp using +=. The order | |
493 | * of adding the elements is unspecified. | |
494 | */ | |
495 | _Tp sum() const; | |
496 | ||
497 | /// Return the minimum element using operator<(). | |
33ac58d5 | 498 | _Tp min() const; |
7fb397a4 JQ |
499 | |
500 | /// Return the maximum element using operator<(). | |
33ac58d5 | 501 | _Tp max() const; |
54c1bf78 | 502 | |
7fb397a4 JQ |
503 | /** |
504 | * @brief Return a shifted array. | |
505 | * | |
506 | * A new valarray is constructed as a copy of this array with elements | |
507 | * in shifted positions. For an element with index i, the new position | |
dc5fef6a VR |
508 | * is i - n. The new valarray has the same size as the current one. |
509 | * New elements without a value are set to 0. Elements whose new | |
7fb397a4 JQ |
510 | * position is outside the bounds of the array are discarded. |
511 | * | |
512 | * Positive arguments shift toward index 0, discarding elements [0, n). | |
513 | * Negative arguments discard elements from the top of the array. | |
514 | * | |
93c66bc6 | 515 | * @param __n Number of element positions to shift. |
7fb397a4 JQ |
516 | * @return New valarray with elements in shifted positions. |
517 | */ | |
93c66bc6 | 518 | valarray<_Tp> shift (int __n) const; |
7fb397a4 JQ |
519 | |
520 | /** | |
521 | * @brief Return a rotated array. | |
522 | * | |
523 | * A new valarray is constructed as a copy of this array with elements | |
524 | * in shifted positions. For an element with index i, the new position | |
dc5fef6a | 525 | * is (i - n) % size(). The new valarray has the same size as the |
7fb397a4 JQ |
526 | * current one. Elements that are shifted beyond the array bounds are |
527 | * shifted into the other end of the array. No elements are lost. | |
528 | * | |
529 | * Positive arguments shift toward index 0, wrapping around the top. | |
530 | * Negative arguments shift towards the top, wrapping around to 0. | |
531 | * | |
93c66bc6 | 532 | * @param __n Number of element positions to rotate. |
7fb397a4 JQ |
533 | * @return New valarray with elements in shifted positions. |
534 | */ | |
93c66bc6 | 535 | valarray<_Tp> cshift(int __n) const; |
7fb397a4 JQ |
536 | |
537 | /** | |
538 | * @brief Apply a function to the array. | |
539 | * | |
540 | * Returns a new valarray with elements assigned to the result of | |
0163bbaa | 541 | * applying __func to the corresponding element of this array. The new |
dc5fef6a | 542 | * array has the same size as this one. |
7fb397a4 | 543 | * |
0163bbaa | 544 | * @param __func Function of Tp returning Tp to apply. |
7fb397a4 JQ |
545 | * @return New valarray with transformed elements. |
546 | */ | |
0163bbaa | 547 | _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(_Tp)) const; |
7fb397a4 JQ |
548 | |
549 | /** | |
550 | * @brief Apply a function to the array. | |
551 | * | |
552 | * Returns a new valarray with elements assigned to the result of | |
0163bbaa | 553 | * applying __func to the corresponding element of this array. The new |
dc5fef6a | 554 | * array has the same size as this one. |
7fb397a4 | 555 | * |
0163bbaa | 556 | * @param __func Function of const Tp& returning Tp to apply. |
7fb397a4 JQ |
557 | * @return New valarray with transformed elements. |
558 | */ | |
0163bbaa | 559 | _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(const _Tp&)) const; |
7fb397a4 JQ |
560 | |
561 | /** | |
562 | * @brief Resize array. | |
563 | * | |
dc5fef6a | 564 | * Resize this array to @a size and set all elements to @a c. All |
7fb397a4 JQ |
565 | * references and iterators are invalidated. |
566 | * | |
93c66bc6 BK |
567 | * @param __size New array size. |
568 | * @param __c New value for all elements. | |
7fb397a4 | 569 | */ |
54c1bf78 BK |
570 | void resize(size_t __size, _Tp __c = _Tp()); |
571 | ||
74d6b8ca | 572 | private: |
54c1bf78 BK |
573 | size_t _M_size; |
574 | _Tp* __restrict__ _M_data; | |
33ac58d5 | 575 | |
0e5abeb0 | 576 | friend struct _Array<_Tp>; |
74d6b8ca | 577 | }; |
33ac58d5 | 578 | |
af181c91 JW |
579 | #if __cpp_deduction_guides >= 201606 |
580 | template<typename _Tp, size_t _Nm> | |
581 | valarray(const _Tp(&)[_Nm], size_t) -> valarray<_Tp>; | |
582 | #endif | |
583 | ||
54c1bf78 | 584 | template<typename _Tp> |
74d6b8ca | 585 | inline const _Tp& |
4f032929 | 586 | valarray<_Tp>::operator[](size_t __i) const _GLIBCXX_NOTHROW |
33ac58d5 | 587 | { |
285b36d6 | 588 | __glibcxx_requires_subscript(__i); |
b714a419 | 589 | return _M_data[__i]; |
285b36d6 | 590 | } |
54c1bf78 BK |
591 | |
592 | template<typename _Tp> | |
74d6b8ca | 593 | inline _Tp& |
4f032929 | 594 | valarray<_Tp>::operator[](size_t __i) _GLIBCXX_NOTHROW |
33ac58d5 | 595 | { |
285b36d6 | 596 | __glibcxx_requires_subscript(__i); |
b714a419 | 597 | return _M_data[__i]; |
285b36d6 | 598 | } |
54c1bf78 | 599 | |
f0b88346 | 600 | /// @} group numeric_arrays |
5b9daa7e | 601 | |
12ffa228 BK |
602 | _GLIBCXX_END_NAMESPACE_VERSION |
603 | } // namespace | |
c13bea50 NS |
604 | |
605 | #include <bits/valarray_after.h> | |
54c1bf78 BK |
606 | #include <bits/slice_array.h> |
607 | #include <bits/gslice.h> | |
608 | #include <bits/gslice_array.h> | |
609 | #include <bits/mask_array.h> | |
610 | #include <bits/indirect_array.h> | |
611 | ||
12ffa228 BK |
612 | namespace std _GLIBCXX_VISIBILITY(default) |
613 | { | |
614 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
3cbc7af0 | 615 | |
5b9daa7e BK |
616 | /** |
617 | * @addtogroup numeric_arrays | |
618 | * @{ | |
619 | */ | |
620 | ||
54c1bf78 | 621 | template<typename _Tp> |
74d6b8ca | 622 | inline |
4f032929 | 623 | valarray<_Tp>::valarray() _GLIBCXX_NOTHROW : _M_size(0), _M_data(0) {} |
54c1bf78 BK |
624 | |
625 | template<typename _Tp> | |
33ac58d5 JW |
626 | inline |
627 | valarray<_Tp>::valarray(size_t __n) | |
b714a419 | 628 | : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) |
eb9a4231 | 629 | { std::__valarray_default_construct(_M_data, _M_data + __n); } |
54c1bf78 BK |
630 | |
631 | template<typename _Tp> | |
74d6b8ca GDR |
632 | inline |
633 | valarray<_Tp>::valarray(const _Tp& __t, size_t __n) | |
b714a419 | 634 | : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) |
eb9a4231 | 635 | { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); } |
54c1bf78 BK |
636 | |
637 | template<typename _Tp> | |
74d6b8ca GDR |
638 | inline |
639 | valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n) | |
b714a419 | 640 | : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) |
33ac58d5 | 641 | { |
2f1e8e7c | 642 | __glibcxx_assert(__p != 0 || __n == 0); |
33ac58d5 | 643 | std::__valarray_copy_construct(__p, __p + __n, _M_data); |
285b36d6 | 644 | } |
54c1bf78 BK |
645 | |
646 | template<typename _Tp> | |
74d6b8ca GDR |
647 | inline |
648 | valarray<_Tp>::valarray(const valarray<_Tp>& __v) | |
b714a419 PC |
649 | : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size)) |
650 | { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, | |
651 | _M_data); } | |
54c1bf78 | 652 | |
734f5023 | 653 | #if __cplusplus >= 201103L |
8a3cabe3 PC |
654 | template<typename _Tp> |
655 | inline | |
656 | valarray<_Tp>::valarray(valarray<_Tp>&& __v) noexcept | |
657 | : _M_size(__v._M_size), _M_data(__v._M_data) | |
658 | { | |
659 | __v._M_size = 0; | |
660 | __v._M_data = 0; | |
661 | } | |
662 | #endif | |
663 | ||
54c1bf78 | 664 | template<typename _Tp> |
74d6b8ca GDR |
665 | inline |
666 | valarray<_Tp>::valarray(const slice_array<_Tp>& __sa) | |
b714a419 | 667 | : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz)) |
74d6b8ca | 668 | { |
6085dc49 | 669 | std::__valarray_copy_construct |
74d6b8ca GDR |
670 | (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); |
671 | } | |
54c1bf78 BK |
672 | |
673 | template<typename _Tp> | |
74d6b8ca GDR |
674 | inline |
675 | valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga) | |
b714a419 PC |
676 | : _M_size(__ga._M_index.size()), |
677 | _M_data(__valarray_get_storage<_Tp>(_M_size)) | |
74d6b8ca | 678 | { |
6085dc49 | 679 | std::__valarray_copy_construct |
74d6b8ca GDR |
680 | (__ga._M_array, _Array<size_t>(__ga._M_index), |
681 | _Array<_Tp>(_M_data), _M_size); | |
682 | } | |
54c1bf78 BK |
683 | |
684 | template<typename _Tp> | |
74d6b8ca GDR |
685 | inline |
686 | valarray<_Tp>::valarray(const mask_array<_Tp>& __ma) | |
b714a419 | 687 | : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz)) |
74d6b8ca | 688 | { |
6085dc49 | 689 | std::__valarray_copy_construct |
74d6b8ca GDR |
690 | (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); |
691 | } | |
54c1bf78 BK |
692 | |
693 | template<typename _Tp> | |
74d6b8ca GDR |
694 | inline |
695 | valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia) | |
b714a419 | 696 | : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz)) |
74d6b8ca | 697 | { |
6085dc49 | 698 | std::__valarray_copy_construct |
74d6b8ca GDR |
699 | (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); |
700 | } | |
54c1bf78 | 701 | |
734f5023 | 702 | #if __cplusplus >= 201103L |
988499f4 JM |
703 | template<typename _Tp> |
704 | inline | |
705 | valarray<_Tp>::valarray(initializer_list<_Tp> __l) | |
af4beb4b | 706 | : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size())) |
8a3cabe3 | 707 | { std::__valarray_copy_construct(__l.begin(), __l.end(), _M_data); } |
988499f4 JM |
708 | #endif |
709 | ||
54c1bf78 | 710 | template<typename _Tp> template<class _Dom> |
74d6b8ca GDR |
711 | inline |
712 | valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e) | |
b714a419 | 713 | : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size)) |
6085dc49 | 714 | { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); } |
54c1bf78 BK |
715 | |
716 | template<typename _Tp> | |
74d6b8ca | 717 | inline |
6a97dbf7 | 718 | valarray<_Tp>::~valarray() _GLIBCXX_NOEXCEPT |
74d6b8ca | 719 | { |
eb9a4231 PC |
720 | std::__valarray_destroy_elements(_M_data, _M_data + _M_size); |
721 | std::__valarray_release_memory(_M_data); | |
74d6b8ca | 722 | } |
54c1bf78 BK |
723 | |
724 | template<typename _Tp> | |
74d6b8ca GDR |
725 | inline valarray<_Tp>& |
726 | valarray<_Tp>::operator=(const valarray<_Tp>& __v) | |
727 | { | |
af4beb4b PC |
728 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
729 | // 630. arrays of valarray. | |
730 | if (_M_size == __v._M_size) | |
731 | std::__valarray_copy(__v._M_data, _M_size, _M_data); | |
732 | else | |
733 | { | |
734 | if (_M_data) | |
735 | { | |
736 | std::__valarray_destroy_elements(_M_data, _M_data + _M_size); | |
737 | std::__valarray_release_memory(_M_data); | |
738 | } | |
739 | _M_size = __v._M_size; | |
740 | _M_data = __valarray_get_storage<_Tp>(_M_size); | |
741 | std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, | |
742 | _M_data); | |
743 | } | |
54c1bf78 | 744 | return *this; |
74d6b8ca | 745 | } |
54c1bf78 | 746 | |
734f5023 | 747 | #if __cplusplus >= 201103L |
8a3cabe3 PC |
748 | template<typename _Tp> |
749 | inline valarray<_Tp>& | |
750 | valarray<_Tp>::operator=(valarray<_Tp>&& __v) noexcept | |
751 | { | |
752 | if (_M_data) | |
753 | { | |
754 | std::__valarray_destroy_elements(_M_data, _M_data + _M_size); | |
755 | std::__valarray_release_memory(_M_data); | |
756 | } | |
757 | _M_size = __v._M_size; | |
758 | _M_data = __v._M_data; | |
759 | __v._M_size = 0; | |
760 | __v._M_data = 0; | |
761 | return *this; | |
762 | } | |
763 | ||
988499f4 JM |
764 | template<typename _Tp> |
765 | inline valarray<_Tp>& | |
766 | valarray<_Tp>::operator=(initializer_list<_Tp> __l) | |
767 | { | |
af4beb4b PC |
768 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
769 | // 630. arrays of valarray. | |
770 | if (_M_size == __l.size()) | |
771 | std::__valarray_copy(__l.begin(), __l.size(), _M_data); | |
772 | else | |
773 | { | |
774 | if (_M_data) | |
775 | { | |
776 | std::__valarray_destroy_elements(_M_data, _M_data + _M_size); | |
777 | std::__valarray_release_memory(_M_data); | |
778 | } | |
779 | _M_size = __l.size(); | |
780 | _M_data = __valarray_get_storage<_Tp>(_M_size); | |
781 | std::__valarray_copy_construct(__l.begin(), __l.begin() + _M_size, | |
782 | _M_data); | |
783 | } | |
784 | return *this; | |
988499f4 JM |
785 | } |
786 | #endif | |
787 | ||
54c1bf78 | 788 | template<typename _Tp> |
74d6b8ca GDR |
789 | inline valarray<_Tp>& |
790 | valarray<_Tp>::operator=(const _Tp& __t) | |
791 | { | |
eb9a4231 | 792 | std::__valarray_fill(_M_data, _M_size, __t); |
54c1bf78 | 793 | return *this; |
74d6b8ca | 794 | } |
54c1bf78 BK |
795 | |
796 | template<typename _Tp> | |
74d6b8ca GDR |
797 | inline valarray<_Tp>& |
798 | valarray<_Tp>::operator=(const slice_array<_Tp>& __sa) | |
799 | { | |
2f1e8e7c | 800 | __glibcxx_assert(_M_size == __sa._M_sz); |
eb9a4231 PC |
801 | std::__valarray_copy(__sa._M_array, __sa._M_sz, |
802 | __sa._M_stride, _Array<_Tp>(_M_data)); | |
54c1bf78 | 803 | return *this; |
74d6b8ca | 804 | } |
54c1bf78 BK |
805 | |
806 | template<typename _Tp> | |
74d6b8ca GDR |
807 | inline valarray<_Tp>& |
808 | valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga) | |
809 | { | |
2f1e8e7c | 810 | __glibcxx_assert(_M_size == __ga._M_index.size()); |
eb9a4231 PC |
811 | std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index), |
812 | _Array<_Tp>(_M_data), _M_size); | |
54c1bf78 | 813 | return *this; |
74d6b8ca | 814 | } |
54c1bf78 BK |
815 | |
816 | template<typename _Tp> | |
74d6b8ca GDR |
817 | inline valarray<_Tp>& |
818 | valarray<_Tp>::operator=(const mask_array<_Tp>& __ma) | |
819 | { | |
2f1e8e7c | 820 | __glibcxx_assert(_M_size == __ma._M_sz); |
eb9a4231 PC |
821 | std::__valarray_copy(__ma._M_array, __ma._M_mask, |
822 | _Array<_Tp>(_M_data), _M_size); | |
54c1bf78 | 823 | return *this; |
74d6b8ca | 824 | } |
54c1bf78 BK |
825 | |
826 | template<typename _Tp> | |
74d6b8ca GDR |
827 | inline valarray<_Tp>& |
828 | valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia) | |
829 | { | |
2f1e8e7c | 830 | __glibcxx_assert(_M_size == __ia._M_sz); |
eb9a4231 PC |
831 | std::__valarray_copy(__ia._M_array, __ia._M_index, |
832 | _Array<_Tp>(_M_data), _M_size); | |
54c1bf78 | 833 | return *this; |
74d6b8ca | 834 | } |
54c1bf78 BK |
835 | |
836 | template<typename _Tp> template<class _Dom> | |
74d6b8ca GDR |
837 | inline valarray<_Tp>& |
838 | valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) | |
839 | { | |
b0ad3635 PC |
840 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
841 | // 630. arrays of valarray. | |
842 | if (_M_size == __e.size()) | |
843 | std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); | |
844 | else | |
845 | { | |
846 | if (_M_data) | |
847 | { | |
848 | std::__valarray_destroy_elements(_M_data, _M_data + _M_size); | |
849 | std::__valarray_release_memory(_M_data); | |
850 | } | |
851 | _M_size = __e.size(); | |
852 | _M_data = __valarray_get_storage<_Tp>(_M_size); | |
853 | std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); | |
854 | } | |
eb9a4231 | 855 | return *this; |
74d6b8ca | 856 | } |
54c1bf78 BK |
857 | |
858 | template<typename _Tp> | |
74d6b8ca GDR |
859 | inline _Expr<_SClos<_ValArray,_Tp>, _Tp> |
860 | valarray<_Tp>::operator[](slice __s) const | |
861 | { | |
54c1bf78 | 862 | typedef _SClos<_ValArray,_Tp> _Closure; |
74d6b8ca GDR |
863 | return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s)); |
864 | } | |
54c1bf78 BK |
865 | |
866 | template<typename _Tp> | |
74d6b8ca GDR |
867 | inline slice_array<_Tp> |
868 | valarray<_Tp>::operator[](slice __s) | |
b714a419 | 869 | { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); } |
54c1bf78 BK |
870 | |
871 | template<typename _Tp> | |
74d6b8ca GDR |
872 | inline _Expr<_GClos<_ValArray,_Tp>, _Tp> |
873 | valarray<_Tp>::operator[](const gslice& __gs) const | |
874 | { | |
54c1bf78 BK |
875 | typedef _GClos<_ValArray,_Tp> _Closure; |
876 | return _Expr<_Closure, _Tp> | |
74d6b8ca GDR |
877 | (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index)); |
878 | } | |
54c1bf78 BK |
879 | |
880 | template<typename _Tp> | |
74d6b8ca GDR |
881 | inline gslice_array<_Tp> |
882 | valarray<_Tp>::operator[](const gslice& __gs) | |
883 | { | |
54c1bf78 | 884 | return gslice_array<_Tp> |
74d6b8ca GDR |
885 | (_Array<_Tp>(_M_data), __gs._M_index->_M_index); |
886 | } | |
54c1bf78 BK |
887 | |
888 | template<typename _Tp> | |
74d6b8ca GDR |
889 | inline valarray<_Tp> |
890 | valarray<_Tp>::operator[](const valarray<bool>& __m) const | |
891 | { | |
892 | size_t __s = 0; | |
893 | size_t __e = __m.size(); | |
54c1bf78 | 894 | for (size_t __i=0; __i<__e; ++__i) |
74d6b8ca GDR |
895 | if (__m[__i]) ++__s; |
896 | return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s, | |
897 | _Array<bool> (__m))); | |
898 | } | |
54c1bf78 BK |
899 | |
900 | template<typename _Tp> | |
74d6b8ca GDR |
901 | inline mask_array<_Tp> |
902 | valarray<_Tp>::operator[](const valarray<bool>& __m) | |
903 | { | |
904 | size_t __s = 0; | |
905 | size_t __e = __m.size(); | |
54c1bf78 | 906 | for (size_t __i=0; __i<__e; ++__i) |
74d6b8ca GDR |
907 | if (__m[__i]) ++__s; |
908 | return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m)); | |
909 | } | |
54c1bf78 BK |
910 | |
911 | template<typename _Tp> | |
74d6b8ca GDR |
912 | inline _Expr<_IClos<_ValArray,_Tp>, _Tp> |
913 | valarray<_Tp>::operator[](const valarray<size_t>& __i) const | |
914 | { | |
54c1bf78 | 915 | typedef _IClos<_ValArray,_Tp> _Closure; |
74d6b8ca GDR |
916 | return _Expr<_Closure, _Tp>(_Closure(*this, __i)); |
917 | } | |
54c1bf78 BK |
918 | |
919 | template<typename _Tp> | |
74d6b8ca GDR |
920 | inline indirect_array<_Tp> |
921 | valarray<_Tp>::operator[](const valarray<size_t>& __i) | |
922 | { | |
923 | return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(), | |
924 | _Array<size_t>(__i)); | |
925 | } | |
54c1bf78 | 926 | |
734f5023 | 927 | #if __cplusplus >= 201103L |
8a3cabe3 PC |
928 | template<class _Tp> |
929 | inline void | |
930 | valarray<_Tp>::swap(valarray<_Tp>& __v) noexcept | |
931 | { | |
932 | std::swap(_M_size, __v._M_size); | |
933 | std::swap(_M_data, __v._M_data); | |
934 | } | |
935 | #endif | |
936 | ||
54c1bf78 | 937 | template<class _Tp> |
33ac58d5 | 938 | inline size_t |
74d6b8ca GDR |
939 | valarray<_Tp>::size() const |
940 | { return _M_size; } | |
54c1bf78 BK |
941 | |
942 | template<class _Tp> | |
74d6b8ca GDR |
943 | inline _Tp |
944 | valarray<_Tp>::sum() const | |
945 | { | |
2f1e8e7c | 946 | __glibcxx_assert(_M_size > 0); |
eb9a4231 | 947 | return std::__valarray_sum(_M_data, _M_data + _M_size); |
74d6b8ca | 948 | } |
54c1bf78 | 949 | |
22d67c60 | 950 | template<class _Tp> |
54c1bf78 BK |
951 | inline valarray<_Tp> |
952 | valarray<_Tp>::shift(int __n) const | |
953 | { | |
22d67c60 | 954 | valarray<_Tp> __ret; |
102693c7 PC |
955 | |
956 | if (_M_size == 0) | |
957 | return __ret; | |
958 | ||
22d67c60 PC |
959 | _Tp* __restrict__ __tmp_M_data = |
960 | std::__valarray_get_storage<_Tp>(_M_size); | |
961 | ||
102693c7 PC |
962 | if (__n == 0) |
963 | std::__valarray_copy_construct(_M_data, | |
964 | _M_data + _M_size, __tmp_M_data); | |
965 | else if (__n > 0) // shift left | |
8e768214 PC |
966 | { |
967 | if (size_t(__n) > _M_size) | |
226a2e08 | 968 | __n = int(_M_size); |
8e768214 PC |
969 | |
970 | std::__valarray_copy_construct(_M_data + __n, | |
971 | _M_data + _M_size, __tmp_M_data); | |
972 | std::__valarray_default_construct(__tmp_M_data + _M_size - __n, | |
973 | __tmp_M_data + _M_size); | |
974 | } | |
102693c7 | 975 | else // shift right |
8e768214 | 976 | { |
226a2e08 PC |
977 | if (-size_t(__n) > _M_size) |
978 | __n = -int(_M_size); | |
8e768214 PC |
979 | |
980 | std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, | |
22d67c60 | 981 | __tmp_M_data - __n); |
8e768214 | 982 | std::__valarray_default_construct(__tmp_M_data, |
22d67c60 | 983 | __tmp_M_data - __n); |
8e768214 | 984 | } |
22d67c60 PC |
985 | |
986 | __ret._M_size = _M_size; | |
987 | __ret._M_data = __tmp_M_data; | |
988 | return __ret; | |
54c1bf78 BK |
989 | } |
990 | ||
22d67c60 | 991 | template<class _Tp> |
54c1bf78 | 992 | inline valarray<_Tp> |
22d67c60 | 993 | valarray<_Tp>::cshift(int __n) const |
54c1bf78 | 994 | { |
22d67c60 | 995 | valarray<_Tp> __ret; |
102693c7 PC |
996 | |
997 | if (_M_size == 0) | |
998 | return __ret; | |
999 | ||
22d67c60 PC |
1000 | _Tp* __restrict__ __tmp_M_data = |
1001 | std::__valarray_get_storage<_Tp>(_M_size); | |
102693c7 PC |
1002 | |
1003 | if (__n == 0) | |
1004 | std::__valarray_copy_construct(_M_data, | |
1005 | _M_data + _M_size, __tmp_M_data); | |
1006 | else if (__n > 0) // cshift left | |
8e768214 PC |
1007 | { |
1008 | if (size_t(__n) > _M_size) | |
226a2e08 | 1009 | __n = int(__n % _M_size); |
22d67c60 | 1010 | |
8e768214 | 1011 | std::__valarray_copy_construct(_M_data, _M_data + __n, |
22d67c60 | 1012 | __tmp_M_data + _M_size - __n); |
8e768214 | 1013 | std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size, |
22d67c60 | 1014 | __tmp_M_data); |
8e768214 | 1015 | } |
102693c7 | 1016 | else // cshift right |
8e768214 | 1017 | { |
226a2e08 PC |
1018 | if (-size_t(__n) > _M_size) |
1019 | __n = -int(-size_t(__n) % _M_size); | |
8e768214 PC |
1020 | |
1021 | std::__valarray_copy_construct(_M_data + _M_size + __n, | |
1022 | _M_data + _M_size, __tmp_M_data); | |
1023 | std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, | |
1024 | __tmp_M_data - __n); | |
1025 | } | |
22d67c60 PC |
1026 | |
1027 | __ret._M_size = _M_size; | |
1028 | __ret._M_data = __tmp_M_data; | |
1029 | return __ret; | |
54c1bf78 BK |
1030 | } |
1031 | ||
22d67c60 | 1032 | template<class _Tp> |
74d6b8ca | 1033 | inline void |
22d67c60 | 1034 | valarray<_Tp>::resize(size_t __n, _Tp __c) |
74d6b8ca GDR |
1035 | { |
1036 | // This complication is so to make valarray<valarray<T> > work | |
1037 | // even though it is not required by the standard. Nobody should | |
1038 | // be saying valarray<valarray<T> > anyway. See the specs. | |
eb9a4231 | 1039 | std::__valarray_destroy_elements(_M_data, _M_data + _M_size); |
74d6b8ca GDR |
1040 | if (_M_size != __n) |
1041 | { | |
eb9a4231 | 1042 | std::__valarray_release_memory(_M_data); |
74d6b8ca GDR |
1043 | _M_size = __n; |
1044 | _M_data = __valarray_get_storage<_Tp>(__n); | |
1045 | } | |
eb9a4231 | 1046 | std::__valarray_fill_construct(_M_data, _M_data + __n, __c); |
74d6b8ca | 1047 | } |
33ac58d5 | 1048 | |
54c1bf78 | 1049 | template<typename _Tp> |
74d6b8ca GDR |
1050 | inline _Tp |
1051 | valarray<_Tp>::min() const | |
1052 | { | |
2f1e8e7c | 1053 | __glibcxx_assert(_M_size > 0); |
65be6ddd | 1054 | return *std::min_element(_M_data, _M_data + _M_size); |
74d6b8ca | 1055 | } |
54c1bf78 BK |
1056 | |
1057 | template<typename _Tp> | |
74d6b8ca GDR |
1058 | inline _Tp |
1059 | valarray<_Tp>::max() const | |
1060 | { | |
2f1e8e7c | 1061 | __glibcxx_assert(_M_size > 0); |
65be6ddd | 1062 | return *std::max_element(_M_data, _M_data + _M_size); |
74d6b8ca | 1063 | } |
33ac58d5 | 1064 | |
54c1bf78 | 1065 | template<class _Tp> |
b714a419 | 1066 | inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> |
0163bbaa | 1067 | valarray<_Tp>::apply(_Tp __func(_Tp)) const |
74d6b8ca | 1068 | { |
b714a419 | 1069 | typedef _ValFunClos<_ValArray, _Tp> _Closure; |
0163bbaa | 1070 | return _Expr<_Closure, _Tp>(_Closure(*this, __func)); |
74d6b8ca | 1071 | } |
54c1bf78 BK |
1072 | |
1073 | template<class _Tp> | |
b714a419 | 1074 | inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> |
0163bbaa | 1075 | valarray<_Tp>::apply(_Tp __func(const _Tp &)) const |
74d6b8ca | 1076 | { |
b714a419 | 1077 | typedef _RefFunClos<_ValArray, _Tp> _Closure; |
0163bbaa | 1078 | return _Expr<_Closure, _Tp>(_Closure(*this, __func)); |
74d6b8ca | 1079 | } |
54c1bf78 BK |
1080 | |
1081 | #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ | |
1082 | template<typename _Tp> \ | |
db5ab3aa | 1083 | inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \ |
b714a419 PC |
1084 | valarray<_Tp>::operator _Op() const \ |
1085 | { \ | |
db5ab3aa JW |
1086 | typedef _UnClos<_Name, _ValArray, _Tp> _Closure; \ |
1087 | typedef typename __fun<_Name, _Tp>::result_type _Rt; \ | |
b714a419 PC |
1088 | return _Expr<_Closure, _Rt>(_Closure(*this)); \ |
1089 | } | |
54c1bf78 | 1090 | |
74d6b8ca GDR |
1091 | _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus) |
1092 | _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate) | |
1093 | _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not) | |
1094 | _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not) | |
54c1bf78 BK |
1095 | |
1096 | #undef _DEFINE_VALARRAY_UNARY_OPERATOR | |
54c1bf78 BK |
1097 | |
1098 | #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \ | |
1099 | template<class _Tp> \ | |
971cfc6f GDR |
1100 | inline valarray<_Tp>& \ |
1101 | valarray<_Tp>::operator _Op##=(const _Tp &__t) \ | |
1102 | { \ | |
1103 | _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \ | |
54c1bf78 | 1104 | return *this; \ |
971cfc6f | 1105 | } \ |
54c1bf78 BK |
1106 | \ |
1107 | template<class _Tp> \ | |
971cfc6f GDR |
1108 | inline valarray<_Tp>& \ |
1109 | valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \ | |
1110 | { \ | |
2f1e8e7c | 1111 | __glibcxx_assert(_M_size == __v._M_size); \ |
971cfc6f GDR |
1112 | _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \ |
1113 | _Array<_Tp>(__v._M_data)); \ | |
54c1bf78 | 1114 | return *this; \ |
971cfc6f | 1115 | } |
54c1bf78 | 1116 | |
971cfc6f GDR |
1117 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus) |
1118 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus) | |
1119 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies) | |
1120 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides) | |
1121 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus) | |
1122 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) | |
1123 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and) | |
1124 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or) | |
1125 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left) | |
1126 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right) | |
54c1bf78 BK |
1127 | |
1128 | #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT | |
1129 | ||
54c1bf78 BK |
1130 | #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \ |
1131 | template<class _Tp> template<class _Dom> \ | |
971cfc6f | 1132 | inline valarray<_Tp>& \ |
b714a419 | 1133 | valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) \ |
971cfc6f GDR |
1134 | { \ |
1135 | _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \ | |
54c1bf78 | 1136 | return *this; \ |
971cfc6f | 1137 | } |
54c1bf78 | 1138 | |
971cfc6f GDR |
1139 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus) |
1140 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus) | |
1141 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies) | |
1142 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides) | |
1143 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus) | |
1144 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) | |
1145 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and) | |
1146 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or) | |
1147 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left) | |
1148 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right) | |
54c1bf78 BK |
1149 | |
1150 | #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT | |
33ac58d5 | 1151 | |
54c1bf78 BK |
1152 | |
1153 | #define _DEFINE_BINARY_OPERATOR(_Op, _Name) \ | |
1154 | template<typename _Tp> \ | |
db5ab3aa JW |
1155 | inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>, \ |
1156 | typename __fun<_Name, _Tp>::result_type> \ | |
971cfc6f GDR |
1157 | operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ |
1158 | { \ | |
db5ab3aa JW |
1159 | __glibcxx_assert(__v.size() == __w.size()); \ |
1160 | typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \ | |
1161 | typedef typename __fun<_Name, _Tp>::result_type _Rt; \ | |
1162 | return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \ | |
971cfc6f | 1163 | } \ |
54c1bf78 BK |
1164 | \ |
1165 | template<typename _Tp> \ | |
db5ab3aa JW |
1166 | inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>, \ |
1167 | typename __fun<_Name, _Tp>::result_type> \ | |
1168 | operator _Op(const valarray<_Tp>& __v, \ | |
1169 | const typename valarray<_Tp>::value_type& __t) \ | |
b714a419 PC |
1170 | { \ |
1171 | typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \ | |
db5ab3aa JW |
1172 | typedef typename __fun<_Name, _Tp>::result_type _Rt; \ |
1173 | return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \ | |
b714a419 | 1174 | } \ |
54c1bf78 BK |
1175 | \ |
1176 | template<typename _Tp> \ | |
db5ab3aa JW |
1177 | inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>, \ |
1178 | typename __fun<_Name, _Tp>::result_type> \ | |
1179 | operator _Op(const typename valarray<_Tp>::value_type& __t, \ | |
1180 | const valarray<_Tp>& __v) \ | |
b714a419 | 1181 | { \ |
db5ab3aa JW |
1182 | typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \ |
1183 | typedef typename __fun<_Name, _Tp>::result_type _Rt; \ | |
1184 | return _Expr<_Closure, _Rt>(_Closure(__t, __v)); \ | |
b714a419 | 1185 | } |
54c1bf78 | 1186 | |
971cfc6f GDR |
1187 | _DEFINE_BINARY_OPERATOR(+, __plus) |
1188 | _DEFINE_BINARY_OPERATOR(-, __minus) | |
1189 | _DEFINE_BINARY_OPERATOR(*, __multiplies) | |
1190 | _DEFINE_BINARY_OPERATOR(/, __divides) | |
1191 | _DEFINE_BINARY_OPERATOR(%, __modulus) | |
1192 | _DEFINE_BINARY_OPERATOR(^, __bitwise_xor) | |
1193 | _DEFINE_BINARY_OPERATOR(&, __bitwise_and) | |
1194 | _DEFINE_BINARY_OPERATOR(|, __bitwise_or) | |
1195 | _DEFINE_BINARY_OPERATOR(<<, __shift_left) | |
1196 | _DEFINE_BINARY_OPERATOR(>>, __shift_right) | |
1197 | _DEFINE_BINARY_OPERATOR(&&, __logical_and) | |
1198 | _DEFINE_BINARY_OPERATOR(||, __logical_or) | |
1199 | _DEFINE_BINARY_OPERATOR(==, __equal_to) | |
1200 | _DEFINE_BINARY_OPERATOR(!=, __not_equal_to) | |
1201 | _DEFINE_BINARY_OPERATOR(<, __less) | |
1202 | _DEFINE_BINARY_OPERATOR(>, __greater) | |
1203 | _DEFINE_BINARY_OPERATOR(<=, __less_equal) | |
1204 | _DEFINE_BINARY_OPERATOR(>=, __greater_equal) | |
54c1bf78 | 1205 | |
bcc4a44f PC |
1206 | #undef _DEFINE_BINARY_OPERATOR |
1207 | ||
734f5023 | 1208 | #if __cplusplus >= 201103L |
f67a9881 PC |
1209 | /** |
1210 | * @brief Return an iterator pointing to the first element of | |
1211 | * the valarray. | |
93c66bc6 | 1212 | * @param __va valarray. |
f67a9881 PC |
1213 | */ |
1214 | template<class _Tp> | |
91bac9fe | 1215 | [[__nodiscard__]] |
f67a9881 | 1216 | inline _Tp* |
91bac9fe JW |
1217 | begin(valarray<_Tp>& __va) noexcept |
1218 | { return __va.size() ? std::__addressof(__va[0]) : nullptr; } | |
f67a9881 PC |
1219 | |
1220 | /** | |
1221 | * @brief Return an iterator pointing to the first element of | |
1222 | * the const valarray. | |
93c66bc6 | 1223 | * @param __va valarray. |
f67a9881 PC |
1224 | */ |
1225 | template<class _Tp> | |
91bac9fe | 1226 | [[__nodiscard__]] |
f67a9881 | 1227 | inline const _Tp* |
91bac9fe JW |
1228 | begin(const valarray<_Tp>& __va) noexcept |
1229 | { return __va.size() ? std::__addressof(__va[0]) : nullptr; } | |
f67a9881 PC |
1230 | |
1231 | /** | |
1232 | * @brief Return an iterator pointing to one past the last element of | |
1233 | * the valarray. | |
93c66bc6 | 1234 | * @param __va valarray. |
f67a9881 PC |
1235 | */ |
1236 | template<class _Tp> | |
91bac9fe | 1237 | [[__nodiscard__]] |
f67a9881 | 1238 | inline _Tp* |
91bac9fe JW |
1239 | end(valarray<_Tp>& __va) noexcept |
1240 | { | |
1241 | if (auto __n = __va.size()) | |
1242 | return std::__addressof(__va[0]) + __n; | |
1243 | else | |
1244 | return nullptr; | |
1245 | } | |
f67a9881 PC |
1246 | |
1247 | /** | |
1248 | * @brief Return an iterator pointing to one past the last element of | |
1249 | * the const valarray. | |
93c66bc6 | 1250 | * @param __va valarray. |
f67a9881 PC |
1251 | */ |
1252 | template<class _Tp> | |
91bac9fe | 1253 | [[__nodiscard__]] |
f67a9881 | 1254 | inline const _Tp* |
91bac9fe JW |
1255 | end(const valarray<_Tp>& __va) noexcept |
1256 | { | |
1257 | if (auto __n = __va.size()) | |
1258 | return std::__addressof(__va[0]) + __n; | |
1259 | else | |
1260 | return nullptr; | |
1261 | } | |
734f5023 | 1262 | #endif // C++11 |
f67a9881 | 1263 | |
f0b88346 | 1264 | /// @} group numeric_arrays |
5b9daa7e | 1265 | |
12ffa228 BK |
1266 | _GLIBCXX_END_NAMESPACE_VERSION |
1267 | } // namespace | |
54c1bf78 | 1268 | |
1143680e | 1269 | #endif /* _GLIBCXX_VALARRAY */ |