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