Fix tests that fail in C++2a mode
[official-gcc.git] / libstdc++-v3 / include / std / valarray
blob86cbb4203a508981511c18886f70271a3165b249
1 // The template and inlines for the -*- C++ -*- valarray class.
3 // Copyright (C) 1997-2019 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.
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.
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.
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/>.
25 /** @file include/valarray
26  *  This is a Standard C++ Library header.
27  */
29 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
31 #ifndef _GLIBCXX_VALARRAY
32 #define _GLIBCXX_VALARRAY 1
34 #pragma GCC system_header
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
44 namespace std _GLIBCXX_VISIBILITY(default)
46 _GLIBCXX_BEGIN_NAMESPACE_VERSION
48   template<class _Clos, typename _Tp>
49     class _Expr;
51   template<typename _Tp1, typename _Tp2>
52     class _ValArray;
54 namespace __detail
56   template<class _Oper, template<class, class> class _Meta, class _Dom>
57     struct _UnClos;
59   template<class _Oper,
60         template<class, class> class _Meta1,
61         template<class, class> class _Meta2,
62         class _Dom1, class _Dom2>
63     class _BinClos;
65   template<template<class, class> class _Meta, class _Dom>
66     class _SClos;
68   template<template<class, class> class _Meta, class _Dom>
69     class _GClos;
71   template<template<class, class> class _Meta, class _Dom>
72     class _IClos;
74   template<template<class, class> class _Meta, class _Dom>
75     class _ValFunClos;
77   template<template<class, class> class _Meta, class _Dom>
78     class _RefFunClos;
79 } // namespace __detail
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;
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
97 _GLIBCXX_END_NAMESPACE_VERSION
98 } // namespace
100 #include <bits/valarray_array.h>
101 #include <bits/valarray_before.h>
103 namespace std _GLIBCXX_VISIBILITY(default)
105 _GLIBCXX_BEGIN_NAMESPACE_VERSION
107   /**
108    * @defgroup numeric_arrays Numeric Arrays
109    * @ingroup numerics
110    *
111    * Classes and functions for representing and manipulating arrays of elements.
112    * @{
113    */
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;
138         // _lib.valarray.cons_ construct/destroy:
139       ///  Construct an empty array.
140       valarray();
142       ///  Construct an array with @a n elements.
143       explicit valarray(size_t);
145       ///  Construct an array with @a n elements initialized to @a t.
146       valarray(const _Tp&, size_t);
148       ///  Construct an array initialized to the first @a n elements of @a t.
149       valarray(const _Tp* __restrict__, size_t);
151       ///  Copy constructor.
152       valarray(const valarray&);
154 #if __cplusplus >= 201103L
155       ///  Move constructor.
156       valarray(valarray&&) noexcept;
157 #endif
159       ///  Construct an array with the same size and values in @a sa.
160       valarray(const slice_array<_Tp>&);
162       ///  Construct an array with the same size and values in @a ga.
163       valarray(const gslice_array<_Tp>&);
165       ///  Construct an array with the same size and values in @a ma.
166       valarray(const mask_array<_Tp>&);
168       ///  Construct an array with the same size and values in @a ia.
169       valarray(const indirect_array<_Tp>&);
171 #if __cplusplus >= 201103L
172       ///  Construct an array with an initializer_list of values.
173       valarray(initializer_list<_Tp>);
174 #endif
176       template<class _Dom>
177         valarray(const _Expr<_Dom, _Tp>& __e);
179       ~valarray() _GLIBCXX_NOEXCEPT;
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);
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
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);
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);
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);
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);
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);
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
263       template<class _Dom> valarray<_Tp>&
264         operator= (const _Expr<_Dom, _Tp>&);
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);
275       // _GLIBCXX_RESOLVE_LIB_DEFECTS
276       // 389. Const overload of valarray::operator[] returns by value.
277       const _Tp&          operator[](size_t) const;
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;
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);
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;
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);
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;
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);
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;
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);
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;
387       ///  Return a new valarray by applying unary - to each element.
388       typename _UnaryOp<__negate>::_Rt      operator-() const;
390       ///  Return a new valarray by applying unary ~ to each element.
391       typename _UnaryOp<__bitwise_not>::_Rt operator~() const;
393       ///  Return a new valarray by applying unary ! to each element.
394       typename _UnaryOp<__logical_not>::_Rt operator!() const;
396       // _lib.valarray.cassign_ computed assignment:
397       ///  Multiply each element of array by @a t.
398       valarray<_Tp>& operator*=(const _Tp&);
400       ///  Divide each element of array by @a t.
401       valarray<_Tp>& operator/=(const _Tp&);
403       ///  Set each element e of array to e % @a t.
404       valarray<_Tp>& operator%=(const _Tp&);
406       ///  Add @a t to each element of array.
407       valarray<_Tp>& operator+=(const _Tp&);
409       ///  Subtract @a t to each element of array.
410       valarray<_Tp>& operator-=(const _Tp&);
412       ///  Set each element e of array to e ^ @a t.
413       valarray<_Tp>& operator^=(const _Tp&);
415       ///  Set each element e of array to e & @a t.
416       valarray<_Tp>& operator&=(const _Tp&);
418       ///  Set each element e of array to e | @a t.
419       valarray<_Tp>& operator|=(const _Tp&);
421       ///  Left shift each element e of array by @a t bits.
422       valarray<_Tp>& operator<<=(const _Tp&);
424       ///  Right shift each element e of array by @a t bits.
425       valarray<_Tp>& operator>>=(const _Tp&);
427       ///  Multiply elements of array by corresponding elements of @a v.
428       valarray<_Tp>& operator*=(const valarray<_Tp>&);
430       ///  Divide elements of array by corresponding elements of @a v.
431       valarray<_Tp>& operator/=(const valarray<_Tp>&);
433       ///  Modulo elements of array by corresponding elements of @a v.
434       valarray<_Tp>& operator%=(const valarray<_Tp>&);
436       ///  Add corresponding elements of @a v to elements of array.
437       valarray<_Tp>& operator+=(const valarray<_Tp>&);
439       ///  Subtract corresponding elements of @a v from elements of array.
440       valarray<_Tp>& operator-=(const valarray<_Tp>&);
442       ///  Logical xor corresponding elements of @a v with elements of array.
443       valarray<_Tp>& operator^=(const valarray<_Tp>&);
445       ///  Logical or corresponding elements of @a v with elements of array.
446       valarray<_Tp>& operator|=(const valarray<_Tp>&);
448       ///  Logical and corresponding elements of @a v with elements of array.
449       valarray<_Tp>& operator&=(const valarray<_Tp>&);
451       ///  Left shift elements of array by corresponding elements of @a v.
452       valarray<_Tp>& operator<<=(const valarray<_Tp>&);
454       ///  Right shift elements of array by corresponding elements of @a v.
455       valarray<_Tp>& operator>>=(const valarray<_Tp>&);
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>&);
478       // _lib.valarray.members_ member functions:
479 #if __cplusplus >= 201103L
480       ///  Swap.
481       void swap(valarray<_Tp>& __v) noexcept;
482 #endif
484       ///  Return the number of elements in array.
485       size_t size() const;
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;
495       ///  Return the minimum element using operator<().
496       _Tp    min() const;
498       ///  Return the maximum element using operator<().
499       _Tp    max() const;
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;
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;
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;
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;
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());
570     private:
571       size_t _M_size;
572       _Tp* __restrict__ _M_data;
574       friend class _Array<_Tp>;
575     };
577 #if __cpp_deduction_guides >= 201606
578   template<typename _Tp, size_t _Nm>
579     valarray(const _Tp(&)[_Nm], size_t) -> valarray<_Tp>;
580 #endif
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     }
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     }
598   // @} group numeric_arrays
600 _GLIBCXX_END_NAMESPACE_VERSION
601 } // namespace
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>
610 namespace std _GLIBCXX_VISIBILITY(default)
612 _GLIBCXX_BEGIN_NAMESPACE_VERSION
614   /**
615    * @addtogroup numeric_arrays
616    * @{
617    */
619   template<typename _Tp>
620     inline
621     valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {}
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); }
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); }
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     }
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); }
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
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     }
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     }
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     }
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     }
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
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)); }
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(_M_data);
720     }
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(_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     }
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(_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     }
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(_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
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     }
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     }
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     }
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     }
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     }
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(_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     }
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     }
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); }
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     }
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     }
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     }
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     }
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     }
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     }
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
935   template<class _Tp>
936     inline size_t
937     valarray<_Tp>::size() const
938     { return _M_size; }
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     }
948   template<class _Tp>
949      inline valarray<_Tp>
950      valarray<_Tp>::shift(int __n) const
951      {
952        valarray<_Tp> __ret;
954        if (_M_size == 0)
955          return __ret;
957        _Tp* __restrict__ __tmp_M_data =
958          std::__valarray_get_storage<_Tp>(_M_size);
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);
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);
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          }
984        __ret._M_size = _M_size;
985        __ret._M_data = __tmp_M_data;
986        return __ret;
987      }
989   template<class _Tp>
990      inline valarray<_Tp>
991      valarray<_Tp>::cshift(int __n) const
992      {
993        valarray<_Tp> __ret;
995        if (_M_size == 0)
996          return __ret;
998        _Tp* __restrict__ __tmp_M_data =
999          std::__valarray_get_storage<_Tp>(_M_size);
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);
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);
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          }
1025        __ret._M_size = _M_size;
1026        __ret._M_data = __tmp_M_data;
1027        return __ret;
1028      }
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(_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     }
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     }
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     }
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     }
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     }
1079 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name)                     \
1080   template<typename _Tp>                                                \
1081     inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt        \
1082     valarray<_Tp>::operator _Op() const                                 \
1083     {                                                                   \
1084       typedef _UnClos<_Name, _ValArray, _Tp> _Closure;                  \
1085       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
1086       return _Expr<_Closure, _Rt>(_Closure(*this));                     \
1087     }
1089     _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
1090     _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
1091     _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
1092     _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
1094 #undef _DEFINE_VALARRAY_UNARY_OPERATOR
1096 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name)               \
1097   template<class _Tp>                                                   \
1098     inline valarray<_Tp>&                                               \
1099     valarray<_Tp>::operator _Op##=(const _Tp &__t)                      \
1100     {                                                                   \
1101       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t);     \
1102       return *this;                                                     \
1103     }                                                                   \
1104                                                                         \
1105   template<class _Tp>                                                   \
1106     inline valarray<_Tp>&                                               \
1107     valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v)            \
1108     {                                                                   \
1109       __glibcxx_assert(_M_size == __v._M_size);                         \
1110       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size,           \
1111                                _Array<_Tp>(__v._M_data));               \
1112       return *this;                                                     \
1113     }
1115 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
1116 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
1117 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
1118 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
1119 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
1120 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
1121 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
1122 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
1123 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
1124 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
1126 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
1128 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name)          \
1129   template<class _Tp> template<class _Dom>                              \
1130     inline valarray<_Tp>&                                               \
1131     valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e)         \
1132     {                                                                   \
1133       _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size);     \
1134       return *this;                                                     \
1135     }
1137 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
1138 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
1139 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
1140 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
1141 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
1142 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
1143 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
1144 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
1145 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
1146 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
1148 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
1151 #define _DEFINE_BINARY_OPERATOR(_Op, _Name)                             \
1152   template<typename _Tp>                                                \
1153     inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>,       \
1154                  typename __fun<_Name, _Tp>::result_type>               \
1155     operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w)    \
1156     {                                                                   \
1157       __glibcxx_assert(__v.size() == __w.size());                       \
1158       typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \
1159       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
1160       return _Expr<_Closure, _Rt>(_Closure(__v, __w));                  \
1161     }                                                                   \
1162                                                                         \
1163   template<typename _Tp>                                                \
1164     inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>,        \
1165                  typename __fun<_Name, _Tp>::result_type>               \
1166     operator _Op(const valarray<_Tp>& __v,                              \
1167                  const typename valarray<_Tp>::value_type& __t)         \
1168     {                                                                   \
1169       typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \
1170       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
1171       return _Expr<_Closure, _Rt>(_Closure(__v, __t));                  \
1172     }                                                                   \
1173                                                                         \
1174   template<typename _Tp>                                                \
1175     inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>,       \
1176                  typename __fun<_Name, _Tp>::result_type>               \
1177     operator _Op(const typename valarray<_Tp>::value_type& __t,         \
1178                  const valarray<_Tp>& __v)                              \
1179     {                                                                   \
1180       typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \
1181       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
1182       return _Expr<_Closure, _Rt>(_Closure(__t, __v));                  \
1183     }
1185 _DEFINE_BINARY_OPERATOR(+, __plus)
1186 _DEFINE_BINARY_OPERATOR(-, __minus)
1187 _DEFINE_BINARY_OPERATOR(*, __multiplies)
1188 _DEFINE_BINARY_OPERATOR(/, __divides)
1189 _DEFINE_BINARY_OPERATOR(%, __modulus)
1190 _DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
1191 _DEFINE_BINARY_OPERATOR(&, __bitwise_and)
1192 _DEFINE_BINARY_OPERATOR(|, __bitwise_or)
1193 _DEFINE_BINARY_OPERATOR(<<, __shift_left)
1194 _DEFINE_BINARY_OPERATOR(>>, __shift_right)
1195 _DEFINE_BINARY_OPERATOR(&&, __logical_and)
1196 _DEFINE_BINARY_OPERATOR(||, __logical_or)
1197 _DEFINE_BINARY_OPERATOR(==, __equal_to)
1198 _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
1199 _DEFINE_BINARY_OPERATOR(<, __less)
1200 _DEFINE_BINARY_OPERATOR(>, __greater)
1201 _DEFINE_BINARY_OPERATOR(<=, __less_equal)
1202 _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
1204 #undef _DEFINE_BINARY_OPERATOR
1206 #if __cplusplus >= 201103L
1207   /**
1208    *  @brief  Return an iterator pointing to the first element of
1209    *          the valarray.
1210    *  @param  __va  valarray.
1211    */
1212   template<class _Tp>
1213     inline _Tp*
1214     begin(valarray<_Tp>& __va)
1215     { return std::__addressof(__va[0]); }
1217   /**
1218    *  @brief  Return an iterator pointing to the first element of
1219    *          the const valarray.
1220    *  @param  __va  valarray.
1221    */
1222   template<class _Tp>
1223     inline const _Tp*
1224     begin(const valarray<_Tp>& __va)
1225     { return std::__addressof(__va[0]); }
1227   /**
1228    *  @brief  Return an iterator pointing to one past the last element of
1229    *          the valarray.
1230    *  @param  __va  valarray.
1231    */
1232   template<class _Tp>
1233     inline _Tp*
1234     end(valarray<_Tp>& __va)
1235     { return std::__addressof(__va[0]) + __va.size(); }
1237   /**
1238    *  @brief  Return an iterator pointing to one past the last element of
1239    *          the const valarray.
1240    *  @param  __va  valarray.
1241    */
1242   template<class _Tp>
1243     inline const _Tp*
1244     end(const valarray<_Tp>& __va)
1245     { return std::__addressof(__va[0]) + __va.size(); }
1246 #endif // C++11
1248   // @} group numeric_arrays
1250 _GLIBCXX_END_NAMESPACE_VERSION
1251 } // namespace
1253 #endif /* _GLIBCXX_VALARRAY */