1 // The template and inlines for the -*- C++ -*- valarray class.
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 // 2006, 2007, 2008, 2009, 2010, 2011
5 // Free Software Foundation, Inc.
7 // This file is part of the GNU ISO C++ Library. This library is free
8 // software; you can redistribute it and/or modify it under the
9 // terms of the GNU General Public License as published by the
10 // Free Software Foundation; either version 3, or (at your option)
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // Under Section 7 of GPL version 3, you are granted additional
19 // permissions described in the GCC Runtime Library Exception, version
20 // 3.1, as published by the Free Software Foundation.
22 // You should have received a copy of the GNU General Public License and
23 // a copy of the GCC Runtime Library Exception along with this program;
24 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 // <http://www.gnu.org/licenses/>.
27 /** @file include/valarray
28 * This is a Standard C++ Library header.
31 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
33 #ifndef _GLIBCXX_VALARRAY
34 #define _GLIBCXX_VALARRAY 1
36 #pragma GCC system_header
38 #include <bits/c++config.h>
41 #include <debug/debug.h>
42 #ifdef __GXX_EXPERIMENTAL_CXX0X__
43 #include <initializer_list>
46 namespace std _GLIBCXX_VISIBILITY(default)
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
50 template<class _Clos, typename _Tp>
53 template<typename _Tp1, typename _Tp2>
56 template<class _Oper, template<class, class> class _Meta, class _Dom>
60 template<class, class> class _Meta1,
61 template<class, class> class _Meta2,
62 class _Dom1, class _Dom2>
65 template<template<class, class> class _Meta, class _Dom>
68 template<template<class, class> class _Meta, class _Dom>
71 template<template<class, class> class _Meta, class _Dom>
74 template<template<class, class> class _Meta, class _Dom>
77 template<template<class, class> class _Meta, class _Dom>
80 template<class _Tp> class valarray; // An array of type _Tp
81 class slice; // BLAS-like slice out of an array
82 template<class _Tp> class slice_array;
83 class gslice; // generalized slice out of an array
84 template<class _Tp> class gslice_array;
85 template<class _Tp> class mask_array; // masked array
86 template<class _Tp> class indirect_array; // indirected array
88 _GLIBCXX_END_NAMESPACE_VERSION
91 #include <bits/valarray_array.h>
92 #include <bits/valarray_before.h>
94 namespace std _GLIBCXX_VISIBILITY(default)
96 _GLIBCXX_BEGIN_NAMESPACE_VERSION
99 * @defgroup numeric_arrays Numeric Arrays
102 * Classes and functions for representing and manipulating arrays of elements.
107 * @brief Smart array designed to support numeric processing.
109 * A valarray is an array that provides constraints intended to allow for
110 * effective optimization of numeric array processing by reducing the
111 * aliasing that can result from pointer representations. It represents a
112 * one-dimensional array from which different multidimensional subsets can
113 * be accessed and modified.
115 * @tparam _Tp Type of object in the array.
123 typedef typename __fun<_Op, _Tp>::result_type __rt;
124 typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt;
127 typedef _Tp value_type;
129 // _lib.valarray.cons_ construct/destroy:
130 /// Construct an empty array.
133 /// Construct an array with @a n elements.
134 explicit valarray(size_t);
136 /// Construct an array with @a n elements initialized to @a t.
137 valarray(const _Tp&, size_t);
139 /// Construct an array initialized to the first @a n elements of @a t.
140 valarray(const _Tp* __restrict__, size_t);
142 /// Copy constructor.
143 valarray(const valarray&);
145 #ifdef __GXX_EXPERIMENTAL_CXX0X__
146 /// Move constructor.
147 valarray(valarray&&) noexcept;
150 /// Construct an array with the same size and values in @a sa.
151 valarray(const slice_array<_Tp>&);
153 /// Construct an array with the same size and values in @a ga.
154 valarray(const gslice_array<_Tp>&);
156 /// Construct an array with the same size and values in @a ma.
157 valarray(const mask_array<_Tp>&);
159 /// Construct an array with the same size and values in @a ia.
160 valarray(const indirect_array<_Tp>&);
162 #ifdef __GXX_EXPERIMENTAL_CXX0X__
163 /// Construct an array with an initializer_list of values.
164 valarray(initializer_list<_Tp>);
168 valarray(const _Expr<_Dom, _Tp>& __e);
170 ~valarray() _GLIBCXX_NOEXCEPT;
172 // _lib.valarray.assign_ assignment:
174 * @brief Assign elements to an array.
176 * Assign elements of array to values in @a v.
178 * @param __v Valarray to get values from.
180 valarray<_Tp>& operator=(const valarray<_Tp>& __v);
182 #ifdef __GXX_EXPERIMENTAL_CXX0X__
184 * @brief Move assign elements to an array.
186 * Move assign elements of array to values in @a v.
188 * @param __v Valarray to get values from.
190 valarray<_Tp>& operator=(valarray<_Tp>&& __v) noexcept;
194 * @brief Assign elements to a value.
196 * Assign all elements of array to @a t.
198 * @param __t Value for elements.
200 valarray<_Tp>& operator=(const _Tp& __t);
203 * @brief Assign elements to an array subset.
205 * Assign elements of array to values in @a sa. Results are undefined
206 * if @a sa does not have the same size as this array.
208 * @param __sa Array slice to get values from.
210 valarray<_Tp>& operator=(const slice_array<_Tp>& __sa);
213 * @brief Assign elements to an array subset.
215 * Assign elements of array to values in @a ga. Results are undefined
216 * if @a ga does not have the same size as this array.
218 * @param __ga Array slice to get values from.
220 valarray<_Tp>& operator=(const gslice_array<_Tp>& __ga);
223 * @brief Assign elements to an array subset.
225 * Assign elements of array to values in @a ma. Results are undefined
226 * if @a ma does not have the same size as this array.
228 * @param __ma Array slice to get values from.
230 valarray<_Tp>& operator=(const mask_array<_Tp>& __ma);
233 * @brief Assign elements to an array subset.
235 * Assign elements of array to values in @a ia. Results are undefined
236 * if @a ia does not have the same size as this array.
238 * @param __ia Array slice to get values from.
240 valarray<_Tp>& operator=(const indirect_array<_Tp>& __ia);
242 #ifdef __GXX_EXPERIMENTAL_CXX0X__
244 * @brief Assign elements to an initializer_list.
246 * Assign elements of array to values in @a __l. Results are undefined
247 * if @a __l does not have the same size as this array.
249 * @param __l initializer_list to get values from.
251 valarray& operator=(initializer_list<_Tp> __l);
254 template<class _Dom> valarray<_Tp>&
255 operator= (const _Expr<_Dom, _Tp>&);
257 // _lib.valarray.access_ element access:
259 * Return a reference to the i'th array element.
261 * @param __i Index of element to return.
262 * @return Reference to the i'th element.
264 _Tp& operator[](size_t __i);
266 // _GLIBCXX_RESOLVE_LIB_DEFECTS
267 // 389. Const overload of valarray::operator[] returns by value.
268 const _Tp& operator[](size_t) const;
270 // _lib.valarray.sub_ subset operations:
272 * @brief Return an array subset.
274 * Returns a new valarray containing the elements of the array
275 * indicated by the slice argument. The new valarray has the same size
276 * as the input slice. @see slice.
278 * @param __s The source slice.
279 * @return New valarray containing elements in @a __s.
281 _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice __s) const;
284 * @brief Return a reference to an array subset.
286 * Returns a new valarray containing the elements of the array
287 * indicated by the slice argument. The new valarray has the same size
288 * as the input slice. @see slice.
290 * @param __s The source slice.
291 * @return New valarray containing elements in @a __s.
293 slice_array<_Tp> operator[](slice __s);
296 * @brief Return an array subset.
298 * Returns a slice_array referencing the elements of the array
299 * indicated by the slice argument. @see gslice.
301 * @param __s The source slice.
302 * @return Slice_array referencing elements indicated by @a __s.
304 _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice& __s) const;
307 * @brief Return a reference to an array subset.
309 * Returns a new valarray containing the elements of the array
310 * indicated by the gslice argument. The new valarray has
311 * the same size as the input gslice. @see gslice.
313 * @param __s The source gslice.
314 * @return New valarray containing elements in @a __s.
316 gslice_array<_Tp> operator[](const gslice& __s);
319 * @brief Return an array subset.
321 * Returns a new valarray containing the elements of the array
322 * indicated by the argument. The input is a valarray of bool which
323 * represents a bitmask indicating which elements should be copied into
324 * the new valarray. Each element of the array is added to the return
325 * valarray if the corresponding element of the argument is true.
327 * @param __m The valarray bitmask.
328 * @return New valarray containing elements indicated by @a __m.
330 valarray<_Tp> operator[](const valarray<bool>& __m) const;
333 * @brief Return a reference to an array subset.
335 * Returns a new mask_array referencing the elements of the array
336 * indicated by the argument. The input is a valarray of bool which
337 * represents a bitmask indicating which elements are part of the
338 * subset. Elements of the array are part of the subset if the
339 * corresponding element of the argument is true.
341 * @param __m The valarray bitmask.
342 * @return New valarray containing elements indicated by @a __m.
344 mask_array<_Tp> operator[](const valarray<bool>& __m);
347 * @brief Return an array subset.
349 * Returns a new valarray containing the elements of the array
350 * indicated by the argument. The elements in the argument are
351 * interpreted as the indices of elements of this valarray to copy to
352 * the return valarray.
354 * @param __i The valarray element index list.
355 * @return New valarray containing elements in @a __s.
357 _Expr<_IClos<_ValArray, _Tp>, _Tp>
358 operator[](const valarray<size_t>& __i) const;
361 * @brief Return a reference to an array subset.
363 * Returns an indirect_array referencing the elements of the array
364 * indicated by the argument. The elements in the argument are
365 * interpreted as the indices of elements of this valarray to include
366 * in the subset. The returned indirect_array refers to these
369 * @param __i The valarray element index list.
370 * @return Indirect_array referencing elements in @a __i.
372 indirect_array<_Tp> operator[](const valarray<size_t>& __i);
374 // _lib.valarray.unary_ unary operators:
375 /// Return a new valarray by applying unary + to each element.
376 typename _UnaryOp<__unary_plus>::_Rt operator+() const;
378 /// Return a new valarray by applying unary - to each element.
379 typename _UnaryOp<__negate>::_Rt operator-() const;
381 /// Return a new valarray by applying unary ~ to each element.
382 typename _UnaryOp<__bitwise_not>::_Rt operator~() const;
384 /// Return a new valarray by applying unary ! to each element.
385 typename _UnaryOp<__logical_not>::_Rt operator!() const;
387 // _lib.valarray.cassign_ computed assignment:
388 /// Multiply each element of array by @a t.
389 valarray<_Tp>& operator*=(const _Tp&);
391 /// Divide each element of array by @a t.
392 valarray<_Tp>& operator/=(const _Tp&);
394 /// Set each element e of array to e % @a t.
395 valarray<_Tp>& operator%=(const _Tp&);
397 /// Add @a t to each element of array.
398 valarray<_Tp>& operator+=(const _Tp&);
400 /// Subtract @a t to each element of array.
401 valarray<_Tp>& operator-=(const _Tp&);
403 /// Set each element e of array to e ^ @a t.
404 valarray<_Tp>& operator^=(const _Tp&);
406 /// Set each element e of array to e & @a t.
407 valarray<_Tp>& operator&=(const _Tp&);
409 /// Set each element e of array to e | @a t.
410 valarray<_Tp>& operator|=(const _Tp&);
412 /// Left shift each element e of array by @a t bits.
413 valarray<_Tp>& operator<<=(const _Tp&);
415 /// Right shift each element e of array by @a t bits.
416 valarray<_Tp>& operator>>=(const _Tp&);
418 /// Multiply elements of array by corresponding elements of @a v.
419 valarray<_Tp>& operator*=(const valarray<_Tp>&);
421 /// Divide elements of array by corresponding elements of @a v.
422 valarray<_Tp>& operator/=(const valarray<_Tp>&);
424 /// Modulo elements of array by corresponding elements of @a v.
425 valarray<_Tp>& operator%=(const valarray<_Tp>&);
427 /// Add corresponding elements of @a v to elements of array.
428 valarray<_Tp>& operator+=(const valarray<_Tp>&);
430 /// Subtract corresponding elements of @a v from elements of array.
431 valarray<_Tp>& operator-=(const valarray<_Tp>&);
433 /// Logical xor corresponding elements of @a v with elements of array.
434 valarray<_Tp>& operator^=(const valarray<_Tp>&);
436 /// Logical or corresponding elements of @a v with elements of array.
437 valarray<_Tp>& operator|=(const valarray<_Tp>&);
439 /// Logical and corresponding elements of @a v with elements of array.
440 valarray<_Tp>& operator&=(const valarray<_Tp>&);
442 /// Left shift elements of array by corresponding elements of @a v.
443 valarray<_Tp>& operator<<=(const valarray<_Tp>&);
445 /// Right shift elements of array by corresponding elements of @a v.
446 valarray<_Tp>& operator>>=(const valarray<_Tp>&);
449 valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&);
451 valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&);
453 valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&);
455 valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&);
457 valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&);
459 valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&);
461 valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&);
463 valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&);
465 valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&);
467 valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&);
469 // _lib.valarray.members_ member functions:
470 #ifdef __GXX_EXPERIMENTAL_CXX0X__
472 void swap(valarray<_Tp>& __v) noexcept;
475 /// Return the number of elements in array.
479 * @brief Return the sum of all elements in the array.
481 * Accumulates the sum of all elements into a Tp using +=. The order
482 * of adding the elements is unspecified.
486 /// Return the minimum element using operator<().
489 /// Return the maximum element using operator<().
493 * @brief Return a shifted array.
495 * A new valarray is constructed as a copy of this array with elements
496 * in shifted positions. For an element with index i, the new position
497 * is i - n. The new valarray has the same size as the current one.
498 * New elements without a value are set to 0. Elements whose new
499 * position is outside the bounds of the array are discarded.
501 * Positive arguments shift toward index 0, discarding elements [0, n).
502 * Negative arguments discard elements from the top of the array.
504 * @param __n Number of element positions to shift.
505 * @return New valarray with elements in shifted positions.
507 valarray<_Tp> shift (int __n) const;
510 * @brief Return a rotated array.
512 * A new valarray is constructed as a copy of this array with elements
513 * in shifted positions. For an element with index i, the new position
514 * is (i - n) % size(). The new valarray has the same size as the
515 * current one. Elements that are shifted beyond the array bounds are
516 * shifted into the other end of the array. No elements are lost.
518 * Positive arguments shift toward index 0, wrapping around the top.
519 * Negative arguments shift towards the top, wrapping around to 0.
521 * @param __n Number of element positions to rotate.
522 * @return New valarray with elements in shifted positions.
524 valarray<_Tp> cshift(int __n) const;
527 * @brief Apply a function to the array.
529 * Returns a new valarray with elements assigned to the result of
530 * applying func to the corresponding element of this array. The new
531 * array has the same size as this one.
533 * @param func Function of Tp returning Tp to apply.
534 * @return New valarray with transformed elements.
536 _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(_Tp)) const;
539 * @brief Apply a function to the array.
541 * Returns a new valarray with elements assigned to the result of
542 * applying func to the corresponding element of this array. The new
543 * array has the same size as this one.
545 * @param func Function of const Tp& returning Tp to apply.
546 * @return New valarray with transformed elements.
548 _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(const _Tp&)) const;
551 * @brief Resize array.
553 * Resize this array to @a size and set all elements to @a c. All
554 * references and iterators are invalidated.
556 * @param __size New array size.
557 * @param __c New value for all elements.
559 void resize(size_t __size, _Tp __c = _Tp());
563 _Tp* __restrict__ _M_data;
565 friend class _Array<_Tp>;
568 template<typename _Tp>
570 valarray<_Tp>::operator[](size_t __i) const
572 __glibcxx_requires_subscript(__i);
576 template<typename _Tp>
578 valarray<_Tp>::operator[](size_t __i)
580 __glibcxx_requires_subscript(__i);
584 // @} group numeric_arrays
586 _GLIBCXX_END_NAMESPACE_VERSION
589 #include <bits/valarray_after.h>
590 #include <bits/slice_array.h>
591 #include <bits/gslice.h>
592 #include <bits/gslice_array.h>
593 #include <bits/mask_array.h>
594 #include <bits/indirect_array.h>
596 namespace std _GLIBCXX_VISIBILITY(default)
598 _GLIBCXX_BEGIN_NAMESPACE_VERSION
601 * @addtogroup numeric_arrays
605 template<typename _Tp>
607 valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {}
609 template<typename _Tp>
611 valarray<_Tp>::valarray(size_t __n)
612 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
613 { std::__valarray_default_construct(_M_data, _M_data + __n); }
615 template<typename _Tp>
617 valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
618 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
619 { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); }
621 template<typename _Tp>
623 valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
624 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
626 _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0);
627 std::__valarray_copy_construct(__p, __p + __n, _M_data);
630 template<typename _Tp>
632 valarray<_Tp>::valarray(const valarray<_Tp>& __v)
633 : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
634 { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
637 #ifdef __GXX_EXPERIMENTAL_CXX0X__
638 template<typename _Tp>
640 valarray<_Tp>::valarray(valarray<_Tp>&& __v) noexcept
641 : _M_size(__v._M_size), _M_data(__v._M_data)
648 template<typename _Tp>
650 valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
651 : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
653 std::__valarray_copy_construct
654 (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
657 template<typename _Tp>
659 valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
660 : _M_size(__ga._M_index.size()),
661 _M_data(__valarray_get_storage<_Tp>(_M_size))
663 std::__valarray_copy_construct
664 (__ga._M_array, _Array<size_t>(__ga._M_index),
665 _Array<_Tp>(_M_data), _M_size);
668 template<typename _Tp>
670 valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
671 : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
673 std::__valarray_copy_construct
674 (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
677 template<typename _Tp>
679 valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
680 : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
682 std::__valarray_copy_construct
683 (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
686 #ifdef __GXX_EXPERIMENTAL_CXX0X__
687 template<typename _Tp>
689 valarray<_Tp>::valarray(initializer_list<_Tp> __l)
690 : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size()))
691 { std::__valarray_copy_construct(__l.begin(), __l.end(), _M_data); }
694 template<typename _Tp> template<class _Dom>
696 valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
697 : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
698 { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); }
700 template<typename _Tp>
702 valarray<_Tp>::~valarray() _GLIBCXX_NOEXCEPT
704 std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
705 std::__valarray_release_memory(_M_data);
708 template<typename _Tp>
709 inline valarray<_Tp>&
710 valarray<_Tp>::operator=(const valarray<_Tp>& __v)
712 // _GLIBCXX_RESOLVE_LIB_DEFECTS
713 // 630. arrays of valarray.
714 if (_M_size == __v._M_size)
715 std::__valarray_copy(__v._M_data, _M_size, _M_data);
720 std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
721 std::__valarray_release_memory(_M_data);
723 _M_size = __v._M_size;
724 _M_data = __valarray_get_storage<_Tp>(_M_size);
725 std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
731 #ifdef __GXX_EXPERIMENTAL_CXX0X__
732 template<typename _Tp>
733 inline valarray<_Tp>&
734 valarray<_Tp>::operator=(valarray<_Tp>&& __v) noexcept
738 std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
739 std::__valarray_release_memory(_M_data);
741 _M_size = __v._M_size;
742 _M_data = __v._M_data;
748 template<typename _Tp>
749 inline valarray<_Tp>&
750 valarray<_Tp>::operator=(initializer_list<_Tp> __l)
752 // _GLIBCXX_RESOLVE_LIB_DEFECTS
753 // 630. arrays of valarray.
754 if (_M_size == __l.size())
755 std::__valarray_copy(__l.begin(), __l.size(), _M_data);
760 std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
761 std::__valarray_release_memory(_M_data);
763 _M_size = __l.size();
764 _M_data = __valarray_get_storage<_Tp>(_M_size);
765 std::__valarray_copy_construct(__l.begin(), __l.begin() + _M_size,
772 template<typename _Tp>
773 inline valarray<_Tp>&
774 valarray<_Tp>::operator=(const _Tp& __t)
776 std::__valarray_fill(_M_data, _M_size, __t);
780 template<typename _Tp>
781 inline valarray<_Tp>&
782 valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
784 _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz);
785 std::__valarray_copy(__sa._M_array, __sa._M_sz,
786 __sa._M_stride, _Array<_Tp>(_M_data));
790 template<typename _Tp>
791 inline valarray<_Tp>&
792 valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
794 _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size());
795 std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
796 _Array<_Tp>(_M_data), _M_size);
800 template<typename _Tp>
801 inline valarray<_Tp>&
802 valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
804 _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz);
805 std::__valarray_copy(__ma._M_array, __ma._M_mask,
806 _Array<_Tp>(_M_data), _M_size);
810 template<typename _Tp>
811 inline valarray<_Tp>&
812 valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
814 _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz);
815 std::__valarray_copy(__ia._M_array, __ia._M_index,
816 _Array<_Tp>(_M_data), _M_size);
820 template<typename _Tp> template<class _Dom>
821 inline valarray<_Tp>&
822 valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
824 _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size());
825 std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
829 template<typename _Tp>
830 inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
831 valarray<_Tp>::operator[](slice __s) const
833 typedef _SClos<_ValArray,_Tp> _Closure;
834 return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
837 template<typename _Tp>
838 inline slice_array<_Tp>
839 valarray<_Tp>::operator[](slice __s)
840 { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); }
842 template<typename _Tp>
843 inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
844 valarray<_Tp>::operator[](const gslice& __gs) const
846 typedef _GClos<_ValArray,_Tp> _Closure;
847 return _Expr<_Closure, _Tp>
848 (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
851 template<typename _Tp>
852 inline gslice_array<_Tp>
853 valarray<_Tp>::operator[](const gslice& __gs)
855 return gslice_array<_Tp>
856 (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
859 template<typename _Tp>
861 valarray<_Tp>::operator[](const valarray<bool>& __m) const
864 size_t __e = __m.size();
865 for (size_t __i=0; __i<__e; ++__i)
867 return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
868 _Array<bool> (__m)));
871 template<typename _Tp>
872 inline mask_array<_Tp>
873 valarray<_Tp>::operator[](const valarray<bool>& __m)
876 size_t __e = __m.size();
877 for (size_t __i=0; __i<__e; ++__i)
879 return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
882 template<typename _Tp>
883 inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
884 valarray<_Tp>::operator[](const valarray<size_t>& __i) const
886 typedef _IClos<_ValArray,_Tp> _Closure;
887 return _Expr<_Closure, _Tp>(_Closure(*this, __i));
890 template<typename _Tp>
891 inline indirect_array<_Tp>
892 valarray<_Tp>::operator[](const valarray<size_t>& __i)
894 return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
895 _Array<size_t>(__i));
898 #ifdef __GXX_EXPERIMENTAL_CXX0X__
901 valarray<_Tp>::swap(valarray<_Tp>& __v) noexcept
903 std::swap(_M_size, __v._M_size);
904 std::swap(_M_data, __v._M_data);
910 valarray<_Tp>::size() const
915 valarray<_Tp>::sum() const
917 _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
918 return std::__valarray_sum(_M_data, _M_data + _M_size);
923 valarray<_Tp>::shift(int __n) const
930 _Tp* __restrict__ __tmp_M_data =
931 std::__valarray_get_storage<_Tp>(_M_size);
934 std::__valarray_copy_construct(_M_data,
935 _M_data + _M_size, __tmp_M_data);
936 else if (__n > 0) // shift left
938 if (size_t(__n) > _M_size)
941 std::__valarray_copy_construct(_M_data + __n,
942 _M_data + _M_size, __tmp_M_data);
943 std::__valarray_default_construct(__tmp_M_data + _M_size - __n,
944 __tmp_M_data + _M_size);
948 if (-size_t(__n) > _M_size)
951 std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
953 std::__valarray_default_construct(__tmp_M_data,
957 __ret._M_size = _M_size;
958 __ret._M_data = __tmp_M_data;
964 valarray<_Tp>::cshift(int __n) const
971 _Tp* __restrict__ __tmp_M_data =
972 std::__valarray_get_storage<_Tp>(_M_size);
975 std::__valarray_copy_construct(_M_data,
976 _M_data + _M_size, __tmp_M_data);
977 else if (__n > 0) // cshift left
979 if (size_t(__n) > _M_size)
980 __n = int(__n % _M_size);
982 std::__valarray_copy_construct(_M_data, _M_data + __n,
983 __tmp_M_data + _M_size - __n);
984 std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size,
989 if (-size_t(__n) > _M_size)
990 __n = -int(-size_t(__n) % _M_size);
992 std::__valarray_copy_construct(_M_data + _M_size + __n,
993 _M_data + _M_size, __tmp_M_data);
994 std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
998 __ret._M_size = _M_size;
999 __ret._M_data = __tmp_M_data;
1005 valarray<_Tp>::resize(size_t __n, _Tp __c)
1007 // This complication is so to make valarray<valarray<T> > work
1008 // even though it is not required by the standard. Nobody should
1009 // be saying valarray<valarray<T> > anyway. See the specs.
1010 std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
1013 std::__valarray_release_memory(_M_data);
1015 _M_data = __valarray_get_storage<_Tp>(__n);
1017 std::__valarray_fill_construct(_M_data, _M_data + __n, __c);
1020 template<typename _Tp>
1022 valarray<_Tp>::min() const
1024 _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
1025 return *std::min_element(_M_data, _M_data + _M_size);
1028 template<typename _Tp>
1030 valarray<_Tp>::max() const
1032 _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
1033 return *std::max_element(_M_data, _M_data + _M_size);
1037 inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp>
1038 valarray<_Tp>::apply(_Tp func(_Tp)) const
1040 typedef _ValFunClos<_ValArray, _Tp> _Closure;
1041 return _Expr<_Closure, _Tp>(_Closure(*this, func));
1045 inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp>
1046 valarray<_Tp>::apply(_Tp func(const _Tp &)) const
1048 typedef _RefFunClos<_ValArray, _Tp> _Closure;
1049 return _Expr<_Closure, _Tp>(_Closure(*this, func));
1052 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \
1053 template<typename _Tp> \
1054 inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \
1055 valarray<_Tp>::operator _Op() const \
1057 typedef _UnClos<_Name, _ValArray, _Tp> _Closure; \
1058 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1059 return _Expr<_Closure, _Rt>(_Closure(*this)); \
1062 _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
1063 _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
1064 _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
1065 _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
1067 #undef _DEFINE_VALARRAY_UNARY_OPERATOR
1069 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \
1070 template<class _Tp> \
1071 inline valarray<_Tp>& \
1072 valarray<_Tp>::operator _Op##=(const _Tp &__t) \
1074 _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \
1078 template<class _Tp> \
1079 inline valarray<_Tp>& \
1080 valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \
1082 _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); \
1083 _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \
1084 _Array<_Tp>(__v._M_data)); \
1088 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
1089 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
1090 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
1091 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
1092 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
1093 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
1094 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
1095 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
1096 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
1097 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
1099 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
1101 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \
1102 template<class _Tp> template<class _Dom> \
1103 inline valarray<_Tp>& \
1104 valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) \
1106 _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \
1110 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
1111 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
1112 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
1113 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
1114 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
1115 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
1116 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
1117 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
1118 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
1119 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
1121 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
1124 #define _DEFINE_BINARY_OPERATOR(_Op, _Name) \
1125 template<typename _Tp> \
1126 inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>, \
1127 typename __fun<_Name, _Tp>::result_type> \
1128 operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
1130 _GLIBCXX_DEBUG_ASSERT(__v.size() == __w.size()); \
1131 typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \
1132 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1133 return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \
1136 template<typename _Tp> \
1137 inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>, \
1138 typename __fun<_Name, _Tp>::result_type> \
1139 operator _Op(const valarray<_Tp>& __v, const _Tp& __t) \
1141 typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \
1142 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1143 return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \
1146 template<typename _Tp> \
1147 inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>, \
1148 typename __fun<_Name, _Tp>::result_type> \
1149 operator _Op(const _Tp& __t, const valarray<_Tp>& __v) \
1151 typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \
1152 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1153 return _Expr<_Closure, _Rt>(_Closure(__t, __v)); \
1156 _DEFINE_BINARY_OPERATOR(+, __plus)
1157 _DEFINE_BINARY_OPERATOR(-, __minus)
1158 _DEFINE_BINARY_OPERATOR(*, __multiplies)
1159 _DEFINE_BINARY_OPERATOR(/, __divides)
1160 _DEFINE_BINARY_OPERATOR(%, __modulus)
1161 _DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
1162 _DEFINE_BINARY_OPERATOR(&, __bitwise_and)
1163 _DEFINE_BINARY_OPERATOR(|, __bitwise_or)
1164 _DEFINE_BINARY_OPERATOR(<<, __shift_left)
1165 _DEFINE_BINARY_OPERATOR(>>, __shift_right)
1166 _DEFINE_BINARY_OPERATOR(&&, __logical_and)
1167 _DEFINE_BINARY_OPERATOR(||, __logical_or)
1168 _DEFINE_BINARY_OPERATOR(==, __equal_to)
1169 _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
1170 _DEFINE_BINARY_OPERATOR(<, __less)
1171 _DEFINE_BINARY_OPERATOR(>, __greater)
1172 _DEFINE_BINARY_OPERATOR(<=, __less_equal)
1173 _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
1175 #undef _DEFINE_BINARY_OPERATOR
1177 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1179 * @brief Return an iterator pointing to the first element of
1181 * @param __va valarray.
1185 begin(valarray<_Tp>& __va)
1186 { return std::__addressof(__va[0]); }
1189 * @brief Return an iterator pointing to the first element of
1190 * the const valarray.
1191 * @param __va valarray.
1195 begin(const valarray<_Tp>& __va)
1196 { return std::__addressof(__va[0]); }
1199 * @brief Return an iterator pointing to one past the last element of
1201 * @param __va valarray.
1205 end(valarray<_Tp>& __va)
1206 { return std::__addressof(__va[0]) + __va.size(); }
1209 * @brief Return an iterator pointing to one past the last element of
1210 * the const valarray.
1211 * @param __va valarray.
1215 end(const valarray<_Tp>& __va)
1216 { return std::__addressof(__va[0]) + __va.size(); }
1217 #endif // __GXX_EXPERIMENTAL_CXX0X__
1219 // @} group numeric_arrays
1221 _GLIBCXX_END_NAMESPACE_VERSION
1224 #endif /* _GLIBCXX_VALARRAY */