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