1 | // The template and inlines for the -*- C++ -*- valarray class. |
2 | |
3 | // Copyright (C) 1997-2024 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
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 include/valarray |
26 | * This is a Standard C++ Library header. |
27 | */ |
28 | |
29 | // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> |
30 | |
31 | #ifndef _GLIBCXX_VALARRAY |
32 | #define _GLIBCXX_VALARRAY 1 |
33 | |
34 | #pragma GCC system_header |
35 | |
36 | #include <bits/requires_hosted.h> // <cmath> dependant |
37 | |
38 | #include <bits/c++config.h> |
39 | #include <cmath> |
40 | #include <algorithm> |
41 | #include <debug/debug.h> |
42 | #if __cplusplus >= 201103L |
43 | #include <initializer_list> |
44 | #endif |
45 | |
46 | namespace std _GLIBCXX_VISIBILITY(default) |
47 | { |
48 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
49 | |
50 | template<class _Clos, typename _Tp> |
51 | class _Expr; |
52 | |
53 | template<typename _Tp1, typename _Tp2> |
54 | class _ValArray; |
55 | |
56 | namespace __detail |
57 | { |
58 | template<class _Oper, template<class, class> class _Meta, class _Dom> |
59 | struct _UnClos; |
60 | |
61 | template<class _Oper, |
62 | template<class, class> class _Meta1, |
63 | template<class, class> class _Meta2, |
64 | class _Dom1, class _Dom2> |
65 | struct _BinClos; |
66 | |
67 | template<template<class, class> class _Meta, class _Dom> |
68 | struct _SClos; |
69 | |
70 | template<template<class, class> class _Meta, class _Dom> |
71 | struct _GClos; |
72 | |
73 | template<template<class, class> class _Meta, class _Dom> |
74 | struct _IClos; |
75 | |
76 | template<template<class, class> class _Meta, class _Dom> |
77 | struct _ValFunClos; |
78 | |
79 | template<template<class, class> class _Meta, class _Dom> |
80 | struct _RefFunClos; |
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; |
90 | |
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 |
98 | |
99 | _GLIBCXX_END_NAMESPACE_VERSION |
100 | } // namespace |
101 | |
102 | #include <bits/valarray_array.h> |
103 | #include <bits/valarray_before.h> |
104 | |
105 | namespace std _GLIBCXX_VISIBILITY(default) |
106 | { |
107 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
108 | |
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 | |
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. |
125 | * |
126 | * @tparam _Tp Type of object in the array. |
127 | */ |
128 | template<class _Tp> |
129 | class valarray |
130 | { |
131 | template<class _Op> |
132 | struct _UnaryOp |
133 | { |
134 | typedef typename __fun<_Op, _Tp>::result_type __rt; |
135 | typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt; |
136 | }; |
137 | public: |
138 | typedef _Tp value_type; |
139 | |
140 | // _lib.valarray.cons_ construct/destroy: |
141 | /// Construct an empty array. |
142 | valarray() _GLIBCXX_NOTHROW; |
143 | |
144 | /// Construct an array with @a n elements. |
145 | explicit valarray(size_t); |
146 | |
147 | /// Construct an array with @a n elements initialized to @a t. |
148 | valarray(const _Tp&, size_t); |
149 | |
150 | /// Construct an array initialized to the first @a n elements of @a t. |
151 | valarray(const _Tp* __restrict__, size_t); |
152 | |
153 | /// Copy constructor. |
154 | valarray(const valarray&); |
155 | |
156 | #if __cplusplus >= 201103L |
157 | /// Move constructor. |
158 | valarray(valarray&&) noexcept; |
159 | #endif |
160 | |
161 | /// Construct an array with the same size and values in @a sa. |
162 | valarray(const slice_array<_Tp>&); |
163 | |
164 | /// Construct an array with the same size and values in @a ga. |
165 | valarray(const gslice_array<_Tp>&); |
166 | |
167 | /// Construct an array with the same size and values in @a ma. |
168 | valarray(const mask_array<_Tp>&); |
169 | |
170 | /// Construct an array with the same size and values in @a ia. |
171 | valarray(const indirect_array<_Tp>&); |
172 | |
173 | #if __cplusplus >= 201103L |
174 | /// Construct an array with an initializer_list of values. |
175 | valarray(initializer_list<_Tp>); |
176 | #endif |
177 | |
178 | template<class _Dom> |
179 | valarray(const _Expr<_Dom, _Tp>& __e); |
180 | |
181 | ~valarray() _GLIBCXX_NOEXCEPT; |
182 | |
183 | // _lib.valarray.assign_ assignment: |
184 | /** |
185 | * @brief Assign elements to an array. |
186 | * |
187 | * Assign elements of array to values in @a v. |
188 | * |
189 | * @param __v Valarray to get values from. |
190 | */ |
191 | valarray<_Tp>& operator=(const valarray<_Tp>& __v); |
192 | |
193 | #if __cplusplus >= 201103L |
194 | /** |
195 | * @brief Move assign elements to an array. |
196 | * |
197 | * Move assign elements of array to values in @a v. |
198 | * |
199 | * @param __v Valarray to get values from. |
200 | */ |
201 | valarray<_Tp>& operator=(valarray<_Tp>&& __v) noexcept; |
202 | #endif |
203 | |
204 | /** |
205 | * @brief Assign elements to a value. |
206 | * |
207 | * Assign all elements of array to @a t. |
208 | * |
209 | * @param __t Value for elements. |
210 | */ |
211 | valarray<_Tp>& operator=(const _Tp& __t); |
212 | |
213 | /** |
214 | * @brief Assign elements to an array subset. |
215 | * |
216 | * Assign elements of array to values in @a sa. Results are undefined |
217 | * if @a sa does not have the same size as this array. |
218 | * |
219 | * @param __sa Array slice to get values from. |
220 | */ |
221 | valarray<_Tp>& operator=(const slice_array<_Tp>& __sa); |
222 | |
223 | /** |
224 | * @brief Assign elements to an array subset. |
225 | * |
226 | * Assign elements of array to values in @a ga. Results are undefined |
227 | * if @a ga does not have the same size as this array. |
228 | * |
229 | * @param __ga Array slice to get values from. |
230 | */ |
231 | valarray<_Tp>& operator=(const gslice_array<_Tp>& __ga); |
232 | |
233 | /** |
234 | * @brief Assign elements to an array subset. |
235 | * |
236 | * Assign elements of array to values in @a ma. Results are undefined |
237 | * if @a ma does not have the same size as this array. |
238 | * |
239 | * @param __ma Array slice to get values from. |
240 | */ |
241 | valarray<_Tp>& operator=(const mask_array<_Tp>& __ma); |
242 | |
243 | /** |
244 | * @brief Assign elements to an array subset. |
245 | * |
246 | * Assign elements of array to values in @a ia. Results are undefined |
247 | * if @a ia does not have the same size as this array. |
248 | * |
249 | * @param __ia Array slice to get values from. |
250 | */ |
251 | valarray<_Tp>& operator=(const indirect_array<_Tp>& __ia); |
252 | |
253 | #if __cplusplus >= 201103L |
254 | /** |
255 | * @brief Assign elements to an initializer_list. |
256 | * |
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. |
259 | * |
260 | * @param __l initializer_list to get values from. |
261 | */ |
262 | valarray& operator=(initializer_list<_Tp> __l); |
263 | #endif |
264 | |
265 | template<class _Dom> valarray<_Tp>& |
266 | operator= (const _Expr<_Dom, _Tp>&); |
267 | |
268 | // _lib.valarray.access_ element access: |
269 | /** |
270 | * Return a reference to the i'th array element. |
271 | * |
272 | * @param __i Index of element to return. |
273 | * @return Reference to the i'th element. |
274 | */ |
275 | _Tp& operator[](size_t __i) _GLIBCXX_NOTHROW; |
276 | |
277 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
278 | // 389. Const overload of valarray::operator[] returns by value. |
279 | const _Tp& operator[](size_t) const _GLIBCXX_NOTHROW; |
280 | |
281 | // _lib.valarray.sub_ subset operations: |
282 | /** |
283 | * @brief Return an array subset. |
284 | * |
285 | * Returns a new valarray containing the elements of the array |
286 | * indicated by the slice argument. The new valarray has the same size |
287 | * as the input slice. @see slice. |
288 | * |
289 | * @param __s The source slice. |
290 | * @return New valarray containing elements in @a __s. |
291 | */ |
292 | _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice __s) const; |
293 | |
294 | /** |
295 | * @brief Return a reference to an array subset. |
296 | * |
297 | * Returns a new valarray containing the elements of the array |
298 | * indicated by the slice argument. The new valarray has the same size |
299 | * as the input slice. @see slice. |
300 | * |
301 | * @param __s The source slice. |
302 | * @return New valarray containing elements in @a __s. |
303 | */ |
304 | slice_array<_Tp> operator[](slice __s); |
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 | * |
312 | * @param __s The source slice. |
313 | * @return Slice_array referencing elements indicated by @a __s. |
314 | */ |
315 | _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice& __s) const; |
316 | |
317 | /** |
318 | * @brief Return a reference to an array subset. |
319 | * |
320 | * Returns a new valarray containing the elements of the array |
321 | * indicated by the gslice argument. The new valarray has |
322 | * the same size as the input gslice. @see gslice. |
323 | * |
324 | * @param __s The source gslice. |
325 | * @return New valarray containing elements in @a __s. |
326 | */ |
327 | gslice_array<_Tp> operator[](const gslice& __s); |
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 | * |
338 | * @param __m The valarray bitmask. |
339 | * @return New valarray containing elements indicated by @a __m. |
340 | */ |
341 | valarray<_Tp> operator[](const valarray<bool>& __m) const; |
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 | * |
352 | * @param __m The valarray bitmask. |
353 | * @return New valarray containing elements indicated by @a __m. |
354 | */ |
355 | mask_array<_Tp> operator[](const valarray<bool>& __m); |
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 | * |
365 | * @param __i The valarray element index list. |
366 | * @return New valarray containing elements in @a __s. |
367 | */ |
368 | _Expr<_IClos<_ValArray, _Tp>, _Tp> |
369 | operator[](const valarray<size_t>& __i) const; |
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 | * |
380 | * @param __i The valarray element index list. |
381 | * @return Indirect_array referencing elements in @a __i. |
382 | */ |
383 | indirect_array<_Tp> operator[](const valarray<size_t>& __i); |
384 | |
385 | // _lib.valarray.unary_ unary operators: |
386 | /// Return a new valarray by applying unary + to each element. |
387 | typename _UnaryOp<__unary_plus>::_Rt operator+() const; |
388 | |
389 | /// Return a new valarray by applying unary - to each element. |
390 | typename _UnaryOp<__negate>::_Rt operator-() const; |
391 | |
392 | /// Return a new valarray by applying unary ~ to each element. |
393 | typename _UnaryOp<__bitwise_not>::_Rt operator~() const; |
394 | |
395 | /// Return a new valarray by applying unary ! to each element. |
396 | typename _UnaryOp<__logical_not>::_Rt operator!() const; |
397 | |
398 | // _lib.valarray.cassign_ computed assignment: |
399 | /// Multiply each element of array by @a t. |
400 | valarray<_Tp>& operator*=(const _Tp&); |
401 | |
402 | /// Divide each element of array by @a t. |
403 | valarray<_Tp>& operator/=(const _Tp&); |
404 | |
405 | /// Set each element e of array to e % @a t. |
406 | valarray<_Tp>& operator%=(const _Tp&); |
407 | |
408 | /// Add @a t to each element of array. |
409 | valarray<_Tp>& operator+=(const _Tp&); |
410 | |
411 | /// Subtract @a t to each element of array. |
412 | valarray<_Tp>& operator-=(const _Tp&); |
413 | |
414 | /// Set each element e of array to e ^ @a t. |
415 | valarray<_Tp>& operator^=(const _Tp&); |
416 | |
417 | /// Set each element e of array to e & @a t. |
418 | valarray<_Tp>& operator&=(const _Tp&); |
419 | |
420 | /// Set each element e of array to e | @a t. |
421 | valarray<_Tp>& operator|=(const _Tp&); |
422 | |
423 | /// Left shift each element e of array by @a t bits. |
424 | valarray<_Tp>& operator<<=(const _Tp&); |
425 | |
426 | /// Right shift each element e of array by @a t bits. |
427 | valarray<_Tp>& operator>>=(const _Tp&); |
428 | |
429 | /// Multiply elements of array by corresponding elements of @a v. |
430 | valarray<_Tp>& operator*=(const valarray<_Tp>&); |
431 | |
432 | /// Divide elements of array by corresponding elements of @a v. |
433 | valarray<_Tp>& operator/=(const valarray<_Tp>&); |
434 | |
435 | /// Modulo elements of array by corresponding elements of @a v. |
436 | valarray<_Tp>& operator%=(const valarray<_Tp>&); |
437 | |
438 | /// Add corresponding elements of @a v to elements of array. |
439 | valarray<_Tp>& operator+=(const valarray<_Tp>&); |
440 | |
441 | /// Subtract corresponding elements of @a v from elements of array. |
442 | valarray<_Tp>& operator-=(const valarray<_Tp>&); |
443 | |
444 | /// Logical xor corresponding elements of @a v with elements of array. |
445 | valarray<_Tp>& operator^=(const valarray<_Tp>&); |
446 | |
447 | /// Logical or corresponding elements of @a v with elements of array. |
448 | valarray<_Tp>& operator|=(const valarray<_Tp>&); |
449 | |
450 | /// Logical and corresponding elements of @a v with elements of array. |
451 | valarray<_Tp>& operator&=(const valarray<_Tp>&); |
452 | |
453 | /// Left shift elements of array by corresponding elements of @a v. |
454 | valarray<_Tp>& operator<<=(const valarray<_Tp>&); |
455 | |
456 | /// Right shift elements of array by corresponding elements of @a v. |
457 | valarray<_Tp>& operator>>=(const valarray<_Tp>&); |
458 | |
459 | template<class _Dom> |
460 | valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&); |
461 | template<class _Dom> |
462 | valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&); |
463 | template<class _Dom> |
464 | valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&); |
465 | template<class _Dom> |
466 | valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&); |
467 | template<class _Dom> |
468 | valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&); |
469 | template<class _Dom> |
470 | valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&); |
471 | template<class _Dom> |
472 | valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&); |
473 | template<class _Dom> |
474 | valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&); |
475 | template<class _Dom> |
476 | valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&); |
477 | template<class _Dom> |
478 | valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&); |
479 | |
480 | // _lib.valarray.members_ member functions: |
481 | #if __cplusplus >= 201103L |
482 | /// Swap. |
483 | void swap(valarray<_Tp>& __v) noexcept; |
484 | #endif |
485 | |
486 | /// Return the number of elements in array. |
487 | size_t size() const; |
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<(). |
498 | _Tp min() const; |
499 | |
500 | /// Return the maximum element using operator<(). |
501 | _Tp max() const; |
502 | |
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 |
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 |
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 | * |
515 | * @param __n Number of element positions to shift. |
516 | * @return New valarray with elements in shifted positions. |
517 | */ |
518 | valarray<_Tp> shift (int __n) const; |
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 |
525 | * is (i - n) % size(). The new valarray has the same size as the |
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 | * |
532 | * @param __n Number of element positions to rotate. |
533 | * @return New valarray with elements in shifted positions. |
534 | */ |
535 | valarray<_Tp> cshift(int __n) const; |
536 | |
537 | /** |
538 | * @brief Apply a function to the array. |
539 | * |
540 | * Returns a new valarray with elements assigned to the result of |
541 | * applying __func to the corresponding element of this array. The new |
542 | * array has the same size as this one. |
543 | * |
544 | * @param __func Function of Tp returning Tp to apply. |
545 | * @return New valarray with transformed elements. |
546 | */ |
547 | _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(_Tp)) const; |
548 | |
549 | /** |
550 | * @brief Apply a function to the array. |
551 | * |
552 | * Returns a new valarray with elements assigned to the result of |
553 | * applying __func to the corresponding element of this array. The new |
554 | * array has the same size as this one. |
555 | * |
556 | * @param __func Function of const Tp& returning Tp to apply. |
557 | * @return New valarray with transformed elements. |
558 | */ |
559 | _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(const _Tp&)) const; |
560 | |
561 | /** |
562 | * @brief Resize array. |
563 | * |
564 | * Resize this array to @a size and set all elements to @a c. All |
565 | * references and iterators are invalidated. |
566 | * |
567 | * @param __size New array size. |
568 | * @param __c New value for all elements. |
569 | */ |
570 | void resize(size_t __size, _Tp __c = _Tp()); |
571 | |
572 | private: |
573 | size_t _M_size; |
574 | _Tp* __restrict__ _M_data; |
575 | |
576 | friend struct _Array<_Tp>; |
577 | }; |
578 | |
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 | |
584 | template<typename _Tp> |
585 | inline const _Tp& |
586 | valarray<_Tp>::operator[](size_t __i) const _GLIBCXX_NOTHROW |
587 | { |
588 | __glibcxx_requires_subscript(__i); |
589 | return _M_data[__i]; |
590 | } |
591 | |
592 | template<typename _Tp> |
593 | inline _Tp& |
594 | valarray<_Tp>::operator[](size_t __i) _GLIBCXX_NOTHROW |
595 | { |
596 | __glibcxx_requires_subscript(__i); |
597 | return _M_data[__i]; |
598 | } |
599 | |
600 | /// @} group numeric_arrays |
601 | |
602 | _GLIBCXX_END_NAMESPACE_VERSION |
603 | } // namespace |
604 | |
605 | #include <bits/valarray_after.h> |
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 | |
612 | namespace std _GLIBCXX_VISIBILITY(default) |
613 | { |
614 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
615 | |
616 | /** |
617 | * @addtogroup numeric_arrays |
618 | * @{ |
619 | */ |
620 | |
621 | template<typename _Tp> |
622 | inline |
623 | valarray<_Tp>::valarray() _GLIBCXX_NOTHROW : _M_size(0), _M_data(0) {} |
624 | |
625 | template<typename _Tp> |
626 | inline |
627 | valarray<_Tp>::valarray(size_t __n) |
628 | : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) |
629 | { std::__valarray_default_construct(_M_data, _M_data + __n); } |
630 | |
631 | template<typename _Tp> |
632 | inline |
633 | valarray<_Tp>::valarray(const _Tp& __t, size_t __n) |
634 | : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) |
635 | { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); } |
636 | |
637 | template<typename _Tp> |
638 | inline |
639 | valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n) |
640 | : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) |
641 | { |
642 | __glibcxx_assert(__p != 0 || __n == 0); |
643 | std::__valarray_copy_construct(__p, __p + __n, _M_data); |
644 | } |
645 | |
646 | template<typename _Tp> |
647 | inline |
648 | valarray<_Tp>::valarray(const valarray<_Tp>& __v) |
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); } |
652 | |
653 | #if __cplusplus >= 201103L |
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 | |
664 | template<typename _Tp> |
665 | inline |
666 | valarray<_Tp>::valarray(const slice_array<_Tp>& __sa) |
667 | : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz)) |
668 | { |
669 | std::__valarray_copy_construct |
670 | (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); |
671 | } |
672 | |
673 | template<typename _Tp> |
674 | inline |
675 | valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga) |
676 | : _M_size(__ga._M_index.size()), |
677 | _M_data(__valarray_get_storage<_Tp>(_M_size)) |
678 | { |
679 | std::__valarray_copy_construct |
680 | (__ga._M_array, _Array<size_t>(__ga._M_index), |
681 | _Array<_Tp>(_M_data), _M_size); |
682 | } |
683 | |
684 | template<typename _Tp> |
685 | inline |
686 | valarray<_Tp>::valarray(const mask_array<_Tp>& __ma) |
687 | : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz)) |
688 | { |
689 | std::__valarray_copy_construct |
690 | (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); |
691 | } |
692 | |
693 | template<typename _Tp> |
694 | inline |
695 | valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia) |
696 | : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz)) |
697 | { |
698 | std::__valarray_copy_construct |
699 | (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); |
700 | } |
701 | |
702 | #if __cplusplus >= 201103L |
703 | template<typename _Tp> |
704 | inline |
705 | valarray<_Tp>::valarray(initializer_list<_Tp> __l) |
706 | : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size())) |
707 | { std::__valarray_copy_construct(__l.begin(), __l.end(), _M_data); } |
708 | #endif |
709 | |
710 | template<typename _Tp> template<class _Dom> |
711 | inline |
712 | valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e) |
713 | : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size)) |
714 | { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); } |
715 | |
716 | template<typename _Tp> |
717 | inline |
718 | valarray<_Tp>::~valarray() _GLIBCXX_NOEXCEPT |
719 | { |
720 | std::__valarray_destroy_elements(_M_data, _M_data + _M_size); |
721 | std::__valarray_release_memory(p: _M_data); |
722 | } |
723 | |
724 | template<typename _Tp> |
725 | inline valarray<_Tp>& |
726 | valarray<_Tp>::operator=(const valarray<_Tp>& __v) |
727 | { |
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(p: _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 | } |
744 | return *this; |
745 | } |
746 | |
747 | #if __cplusplus >= 201103L |
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(p: _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 | |
764 | template<typename _Tp> |
765 | inline valarray<_Tp>& |
766 | valarray<_Tp>::operator=(initializer_list<_Tp> __l) |
767 | { |
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(p: _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; |
785 | } |
786 | #endif |
787 | |
788 | template<typename _Tp> |
789 | inline valarray<_Tp>& |
790 | valarray<_Tp>::operator=(const _Tp& __t) |
791 | { |
792 | std::__valarray_fill(_M_data, _M_size, __t); |
793 | return *this; |
794 | } |
795 | |
796 | template<typename _Tp> |
797 | inline valarray<_Tp>& |
798 | valarray<_Tp>::operator=(const slice_array<_Tp>& __sa) |
799 | { |
800 | __glibcxx_assert(_M_size == __sa._M_sz); |
801 | std::__valarray_copy(__sa._M_array, __sa._M_sz, |
802 | __sa._M_stride, _Array<_Tp>(_M_data)); |
803 | return *this; |
804 | } |
805 | |
806 | template<typename _Tp> |
807 | inline valarray<_Tp>& |
808 | valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga) |
809 | { |
810 | __glibcxx_assert(_M_size == __ga._M_index.size()); |
811 | std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index), |
812 | _Array<_Tp>(_M_data), _M_size); |
813 | return *this; |
814 | } |
815 | |
816 | template<typename _Tp> |
817 | inline valarray<_Tp>& |
818 | valarray<_Tp>::operator=(const mask_array<_Tp>& __ma) |
819 | { |
820 | __glibcxx_assert(_M_size == __ma._M_sz); |
821 | std::__valarray_copy(__ma._M_array, __ma._M_mask, |
822 | _Array<_Tp>(_M_data), _M_size); |
823 | return *this; |
824 | } |
825 | |
826 | template<typename _Tp> |
827 | inline valarray<_Tp>& |
828 | valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia) |
829 | { |
830 | __glibcxx_assert(_M_size == __ia._M_sz); |
831 | std::__valarray_copy(__ia._M_array, __ia._M_index, |
832 | _Array<_Tp>(_M_data), _M_size); |
833 | return *this; |
834 | } |
835 | |
836 | template<typename _Tp> template<class _Dom> |
837 | inline valarray<_Tp>& |
838 | valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) |
839 | { |
840 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
841 | // 630. arrays of valarray. |
842 | if (_M_size == __e.size()) |
843 | { |
844 | // Copy manually instead of using __valarray_copy, because __e might |
845 | // alias _M_data and the _Array param type of __valarray_copy uses |
846 | // restrict which doesn't allow aliasing. |
847 | for (size_t __i = 0; __i < _M_size; ++__i) |
848 | _M_data[__i] = __e[__i]; |
849 | } |
850 | else |
851 | { |
852 | if (_M_data) |
853 | { |
854 | std::__valarray_destroy_elements(_M_data, _M_data + _M_size); |
855 | std::__valarray_release_memory(p: _M_data); |
856 | } |
857 | _M_size = __e.size(); |
858 | _M_data = __valarray_get_storage<_Tp>(_M_size); |
859 | std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); |
860 | } |
861 | return *this; |
862 | } |
863 | |
864 | template<typename _Tp> |
865 | inline _Expr<_SClos<_ValArray,_Tp>, _Tp> |
866 | valarray<_Tp>::operator[](slice __s) const |
867 | { |
868 | typedef _SClos<_ValArray,_Tp> _Closure; |
869 | return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s)); |
870 | } |
871 | |
872 | template<typename _Tp> |
873 | inline slice_array<_Tp> |
874 | valarray<_Tp>::operator[](slice __s) |
875 | { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); } |
876 | |
877 | template<typename _Tp> |
878 | inline _Expr<_GClos<_ValArray,_Tp>, _Tp> |
879 | valarray<_Tp>::operator[](const gslice& __gs) const |
880 | { |
881 | typedef _GClos<_ValArray,_Tp> _Closure; |
882 | return _Expr<_Closure, _Tp> |
883 | (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index)); |
884 | } |
885 | |
886 | template<typename _Tp> |
887 | inline gslice_array<_Tp> |
888 | valarray<_Tp>::operator[](const gslice& __gs) |
889 | { |
890 | return gslice_array<_Tp> |
891 | (_Array<_Tp>(_M_data), __gs._M_index->_M_index); |
892 | } |
893 | |
894 | template<typename _Tp> |
895 | inline valarray<_Tp> |
896 | valarray<_Tp>::operator[](const valarray<bool>& __m) const |
897 | { |
898 | size_t __s = 0; |
899 | size_t __e = __m.size(); |
900 | for (size_t __i=0; __i<__e; ++__i) |
901 | if (__m[__i]) ++__s; |
902 | __glibcxx_assert(__s <= _M_size); |
903 | return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s, |
904 | _Array<bool> (__m))); |
905 | } |
906 | |
907 | template<typename _Tp> |
908 | inline mask_array<_Tp> |
909 | valarray<_Tp>::operator[](const valarray<bool>& __m) |
910 | { |
911 | size_t __s = 0; |
912 | size_t __e = __m.size(); |
913 | for (size_t __i=0; __i<__e; ++__i) |
914 | if (__m[__i]) ++__s; |
915 | __glibcxx_assert(__s <= _M_size); |
916 | return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m)); |
917 | } |
918 | |
919 | template<typename _Tp> |
920 | inline _Expr<_IClos<_ValArray,_Tp>, _Tp> |
921 | valarray<_Tp>::operator[](const valarray<size_t>& __i) const |
922 | { |
923 | typedef _IClos<_ValArray,_Tp> _Closure; |
924 | return _Expr<_Closure, _Tp>(_Closure(*this, __i)); |
925 | } |
926 | |
927 | template<typename _Tp> |
928 | inline indirect_array<_Tp> |
929 | valarray<_Tp>::operator[](const valarray<size_t>& __i) |
930 | { |
931 | return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(), |
932 | _Array<size_t>(__i)); |
933 | } |
934 | |
935 | #if __cplusplus >= 201103L |
936 | template<class _Tp> |
937 | inline void |
938 | valarray<_Tp>::swap(valarray<_Tp>& __v) noexcept |
939 | { |
940 | std::swap(_M_size, __v._M_size); |
941 | std::swap(_M_data, __v._M_data); |
942 | } |
943 | #endif |
944 | |
945 | template<class _Tp> |
946 | inline size_t |
947 | valarray<_Tp>::size() const |
948 | { return _M_size; } |
949 | |
950 | template<class _Tp> |
951 | inline _Tp |
952 | valarray<_Tp>::sum() const |
953 | { |
954 | __glibcxx_assert(_M_size > 0); |
955 | return std::__valarray_sum(_M_data, _M_data + _M_size); |
956 | } |
957 | |
958 | template<class _Tp> |
959 | inline valarray<_Tp> |
960 | valarray<_Tp>::shift(int __n) const |
961 | { |
962 | valarray<_Tp> __ret; |
963 | |
964 | if (_M_size == 0) |
965 | return __ret; |
966 | |
967 | _Tp* __restrict__ __tmp_M_data = |
968 | std::__valarray_get_storage<_Tp>(_M_size); |
969 | |
970 | if (__n == 0) |
971 | std::__valarray_copy_construct(_M_data, |
972 | _M_data + _M_size, __tmp_M_data); |
973 | else if (__n > 0) // shift left |
974 | { |
975 | if (size_t(__n) > _M_size) |
976 | __n = int(_M_size); |
977 | |
978 | std::__valarray_copy_construct(_M_data + __n, |
979 | _M_data + _M_size, __tmp_M_data); |
980 | std::__valarray_default_construct(__tmp_M_data + _M_size - __n, |
981 | __tmp_M_data + _M_size); |
982 | } |
983 | else // shift right |
984 | { |
985 | if (-size_t(__n) > _M_size) |
986 | __n = -int(_M_size); |
987 | |
988 | std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, |
989 | __tmp_M_data - __n); |
990 | std::__valarray_default_construct(__tmp_M_data, |
991 | __tmp_M_data - __n); |
992 | } |
993 | |
994 | __ret._M_size = _M_size; |
995 | __ret._M_data = __tmp_M_data; |
996 | return __ret; |
997 | } |
998 | |
999 | template<class _Tp> |
1000 | inline valarray<_Tp> |
1001 | valarray<_Tp>::cshift(int __n) const |
1002 | { |
1003 | valarray<_Tp> __ret; |
1004 | |
1005 | if (_M_size == 0) |
1006 | return __ret; |
1007 | |
1008 | _Tp* __restrict__ __tmp_M_data = |
1009 | std::__valarray_get_storage<_Tp>(_M_size); |
1010 | |
1011 | if (__n == 0) |
1012 | std::__valarray_copy_construct(_M_data, |
1013 | _M_data + _M_size, __tmp_M_data); |
1014 | else if (__n > 0) // cshift left |
1015 | { |
1016 | if (size_t(__n) > _M_size) |
1017 | __n = int(__n % _M_size); |
1018 | |
1019 | std::__valarray_copy_construct(_M_data, _M_data + __n, |
1020 | __tmp_M_data + _M_size - __n); |
1021 | std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size, |
1022 | __tmp_M_data); |
1023 | } |
1024 | else // cshift right |
1025 | { |
1026 | if (-size_t(__n) > _M_size) |
1027 | __n = -int(-size_t(__n) % _M_size); |
1028 | |
1029 | std::__valarray_copy_construct(_M_data + _M_size + __n, |
1030 | _M_data + _M_size, __tmp_M_data); |
1031 | std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, |
1032 | __tmp_M_data - __n); |
1033 | } |
1034 | |
1035 | __ret._M_size = _M_size; |
1036 | __ret._M_data = __tmp_M_data; |
1037 | return __ret; |
1038 | } |
1039 | |
1040 | template<class _Tp> |
1041 | inline void |
1042 | valarray<_Tp>::resize(size_t __n, _Tp __c) |
1043 | { |
1044 | // This complication is so to make valarray<valarray<T> > work |
1045 | // even though it is not required by the standard. Nobody should |
1046 | // be saying valarray<valarray<T> > anyway. See the specs. |
1047 | std::__valarray_destroy_elements(_M_data, _M_data + _M_size); |
1048 | if (_M_size != __n) |
1049 | { |
1050 | std::__valarray_release_memory(p: _M_data); |
1051 | _M_size = __n; |
1052 | _M_data = __valarray_get_storage<_Tp>(__n); |
1053 | } |
1054 | std::__valarray_fill_construct(_M_data, _M_data + __n, __c); |
1055 | } |
1056 | |
1057 | template<typename _Tp> |
1058 | inline _Tp |
1059 | valarray<_Tp>::min() const |
1060 | { |
1061 | __glibcxx_assert(_M_size > 0); |
1062 | return *std::min_element(_M_data, _M_data + _M_size); |
1063 | } |
1064 | |
1065 | template<typename _Tp> |
1066 | inline _Tp |
1067 | valarray<_Tp>::max() const |
1068 | { |
1069 | __glibcxx_assert(_M_size > 0); |
1070 | return *std::max_element(_M_data, _M_data + _M_size); |
1071 | } |
1072 | |
1073 | template<class _Tp> |
1074 | inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> |
1075 | valarray<_Tp>::apply(_Tp __func(_Tp)) const |
1076 | { |
1077 | typedef _ValFunClos<_ValArray, _Tp> _Closure; |
1078 | return _Expr<_Closure, _Tp>(_Closure(*this, __func)); |
1079 | } |
1080 | |
1081 | template<class _Tp> |
1082 | inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> |
1083 | valarray<_Tp>::apply(_Tp __func(const _Tp &)) const |
1084 | { |
1085 | typedef _RefFunClos<_ValArray, _Tp> _Closure; |
1086 | return _Expr<_Closure, _Tp>(_Closure(*this, __func)); |
1087 | } |
1088 | |
1089 | /// @cond undocumented |
1090 | #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ |
1091 | template<typename _Tp> \ |
1092 | inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \ |
1093 | valarray<_Tp>::operator _Op() const \ |
1094 | { \ |
1095 | typedef _UnClos<_Name, _ValArray, _Tp> _Closure; \ |
1096 | typedef typename __fun<_Name, _Tp>::result_type _Rt; \ |
1097 | return _Expr<_Closure, _Rt>(_Closure(*this)); \ |
1098 | } |
1099 | |
1100 | _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus) |
1101 | _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate) |
1102 | _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not) |
1103 | _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not) |
1104 | |
1105 | #undef _DEFINE_VALARRAY_UNARY_OPERATOR |
1106 | |
1107 | #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \ |
1108 | template<class _Tp> \ |
1109 | inline valarray<_Tp>& \ |
1110 | valarray<_Tp>::operator _Op##=(const _Tp &__t) \ |
1111 | { \ |
1112 | _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \ |
1113 | return *this; \ |
1114 | } \ |
1115 | \ |
1116 | template<class _Tp> \ |
1117 | inline valarray<_Tp>& \ |
1118 | valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \ |
1119 | { \ |
1120 | __glibcxx_assert(_M_size == __v._M_size); \ |
1121 | _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \ |
1122 | _Array<_Tp>(__v._M_data)); \ |
1123 | return *this; \ |
1124 | } |
1125 | |
1126 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus) |
1127 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus) |
1128 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies) |
1129 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides) |
1130 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus) |
1131 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) |
1132 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and) |
1133 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or) |
1134 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left) |
1135 | _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right) |
1136 | |
1137 | #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT |
1138 | |
1139 | #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \ |
1140 | template<class _Tp> template<class _Dom> \ |
1141 | inline valarray<_Tp>& \ |
1142 | valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) \ |
1143 | { \ |
1144 | _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \ |
1145 | return *this; \ |
1146 | } |
1147 | |
1148 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus) |
1149 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus) |
1150 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies) |
1151 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides) |
1152 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus) |
1153 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) |
1154 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and) |
1155 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or) |
1156 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left) |
1157 | _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right) |
1158 | |
1159 | #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT |
1160 | |
1161 | |
1162 | #define _DEFINE_BINARY_OPERATOR(_Op, _Name) \ |
1163 | template<typename _Tp> \ |
1164 | inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>, \ |
1165 | typename __fun<_Name, _Tp>::result_type> \ |
1166 | operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ |
1167 | { \ |
1168 | __glibcxx_assert(__v.size() == __w.size()); \ |
1169 | typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \ |
1170 | typedef typename __fun<_Name, _Tp>::result_type _Rt; \ |
1171 | return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \ |
1172 | } \ |
1173 | \ |
1174 | template<typename _Tp> \ |
1175 | inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>, \ |
1176 | typename __fun<_Name, _Tp>::result_type> \ |
1177 | operator _Op(const valarray<_Tp>& __v, \ |
1178 | const typename valarray<_Tp>::value_type& __t) \ |
1179 | { \ |
1180 | typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \ |
1181 | typedef typename __fun<_Name, _Tp>::result_type _Rt; \ |
1182 | return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \ |
1183 | } \ |
1184 | \ |
1185 | template<typename _Tp> \ |
1186 | inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>, \ |
1187 | typename __fun<_Name, _Tp>::result_type> \ |
1188 | operator _Op(const typename valarray<_Tp>::value_type& __t, \ |
1189 | const valarray<_Tp>& __v) \ |
1190 | { \ |
1191 | typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \ |
1192 | typedef typename __fun<_Name, _Tp>::result_type _Rt; \ |
1193 | return _Expr<_Closure, _Rt>(_Closure(__t, __v)); \ |
1194 | } |
1195 | |
1196 | _DEFINE_BINARY_OPERATOR(+, __plus) |
1197 | _DEFINE_BINARY_OPERATOR(-, __minus) |
1198 | _DEFINE_BINARY_OPERATOR(*, __multiplies) |
1199 | _DEFINE_BINARY_OPERATOR(/, __divides) |
1200 | _DEFINE_BINARY_OPERATOR(%, __modulus) |
1201 | _DEFINE_BINARY_OPERATOR(^, __bitwise_xor) |
1202 | _DEFINE_BINARY_OPERATOR(&, __bitwise_and) |
1203 | _DEFINE_BINARY_OPERATOR(|, __bitwise_or) |
1204 | _DEFINE_BINARY_OPERATOR(<<, __shift_left) |
1205 | _DEFINE_BINARY_OPERATOR(>>, __shift_right) |
1206 | _DEFINE_BINARY_OPERATOR(&&, __logical_and) |
1207 | _DEFINE_BINARY_OPERATOR(||, __logical_or) |
1208 | _DEFINE_BINARY_OPERATOR(==, __equal_to) |
1209 | _DEFINE_BINARY_OPERATOR(!=, __not_equal_to) |
1210 | _DEFINE_BINARY_OPERATOR(<, __less) |
1211 | _DEFINE_BINARY_OPERATOR(>, __greater) |
1212 | _DEFINE_BINARY_OPERATOR(<=, __less_equal) |
1213 | _DEFINE_BINARY_OPERATOR(>=, __greater_equal) |
1214 | |
1215 | #undef _DEFINE_BINARY_OPERATOR |
1216 | /// @endcond |
1217 | |
1218 | #if __cplusplus >= 201103L |
1219 | /** |
1220 | * @brief Return an iterator pointing to the first element of |
1221 | * the valarray. |
1222 | * @param __va valarray. |
1223 | */ |
1224 | template<class _Tp> |
1225 | [[__nodiscard__]] |
1226 | inline _Tp* |
1227 | begin(valarray<_Tp>& __va) noexcept |
1228 | { return __va.size() ? std::__addressof(__va[0]) : nullptr; } |
1229 | |
1230 | /** |
1231 | * @brief Return an iterator pointing to the first element of |
1232 | * the const valarray. |
1233 | * @param __va valarray. |
1234 | */ |
1235 | template<class _Tp> |
1236 | [[__nodiscard__]] |
1237 | inline const _Tp* |
1238 | begin(const valarray<_Tp>& __va) noexcept |
1239 | { return __va.size() ? std::__addressof(__va[0]) : nullptr; } |
1240 | |
1241 | /** |
1242 | * @brief Return an iterator pointing to one past the last element of |
1243 | * the valarray. |
1244 | * @param __va valarray. |
1245 | */ |
1246 | template<class _Tp> |
1247 | [[__nodiscard__]] |
1248 | inline _Tp* |
1249 | end(valarray<_Tp>& __va) noexcept |
1250 | { |
1251 | if (auto __n = __va.size()) |
1252 | return std::__addressof(__va[0]) + __n; |
1253 | else |
1254 | return nullptr; |
1255 | } |
1256 | |
1257 | /** |
1258 | * @brief Return an iterator pointing to one past the last element of |
1259 | * the const valarray. |
1260 | * @param __va valarray. |
1261 | */ |
1262 | template<class _Tp> |
1263 | [[__nodiscard__]] |
1264 | inline const _Tp* |
1265 | end(const valarray<_Tp>& __va) noexcept |
1266 | { |
1267 | if (auto __n = __va.size()) |
1268 | return std::__addressof(__va[0]) + __n; |
1269 | else |
1270 | return nullptr; |
1271 | } |
1272 | #endif // C++11 |
1273 | |
1274 | /// @} group numeric_arrays |
1275 | |
1276 | _GLIBCXX_END_NAMESPACE_VERSION |
1277 | } // namespace |
1278 | |
1279 | #endif /* _GLIBCXX_VALARRAY */ |
1280 | |