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