libstdc++
valarray
Go to the documentation of this file.
00001 // The template and inlines for the -*- C++ -*- valarray class.
00002 
00003 // Copyright (C) 1997-2019 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file include/valarray
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
00030 
00031 #ifndef _GLIBCXX_VALARRAY
00032 #define _GLIBCXX_VALARRAY 1
00033 
00034 #pragma GCC system_header
00035 
00036 #include <bits/c++config.h>
00037 #include <cmath>
00038 #include <algorithm>
00039 #include <debug/debug.h>
00040 #if __cplusplus >= 201103L
00041 #include <initializer_list>
00042 #endif
00043 
00044 namespace std _GLIBCXX_VISIBILITY(default)
00045 {
00046 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00047 
00048   template<class _Clos, typename _Tp>
00049     class _Expr;
00050 
00051   template<typename _Tp1, typename _Tp2>
00052     class _ValArray;
00053 
00054 namespace __detail
00055 {
00056   template<class _Oper, template<class, class> class _Meta, class _Dom>
00057     struct _UnClos;
00058 
00059   template<class _Oper,
00060         template<class, class> class _Meta1,
00061         template<class, class> class _Meta2,
00062         class _Dom1, class _Dom2>
00063     class _BinClos;
00064 
00065   template<template<class, class> class _Meta, class _Dom>
00066     class _SClos;
00067 
00068   template<template<class, class> class _Meta, class _Dom>
00069     class _GClos;
00070 
00071   template<template<class, class> class _Meta, class _Dom>
00072     class _IClos;
00073 
00074   template<template<class, class> class _Meta, class _Dom>
00075     class _ValFunClos;
00076 
00077   template<template<class, class> class _Meta, class _Dom>
00078     class _RefFunClos;
00079 } // namespace __detail
00080 
00081   using __detail::_UnClos;
00082   using __detail::_BinClos;
00083   using __detail::_SClos;
00084   using __detail::_GClos;
00085   using __detail::_IClos;
00086   using __detail::_ValFunClos;
00087   using __detail::_RefFunClos;
00088 
00089   template<class _Tp> class valarray;   // An array of type _Tp
00090   class slice;                          // BLAS-like slice out of an array
00091   template<class _Tp> class slice_array;
00092   class gslice;                         // generalized slice out of an array
00093   template<class _Tp> class gslice_array;
00094   template<class _Tp> class mask_array;     // masked array
00095   template<class _Tp> class indirect_array; // indirected array
00096 
00097 _GLIBCXX_END_NAMESPACE_VERSION
00098 } // namespace
00099 
00100 #include <bits/valarray_array.h>
00101 #include <bits/valarray_before.h>
00102 
00103 namespace std _GLIBCXX_VISIBILITY(default)
00104 {
00105 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00106 
00107   /**
00108    * @defgroup numeric_arrays Numeric Arrays
00109    * @ingroup numerics
00110    *
00111    * Classes and functions for representing and manipulating arrays of elements.
00112    * @{
00113    */
00114 
00115   /**
00116    *  @brief  Smart array designed to support numeric processing.
00117    *
00118    *  A valarray is an array that provides constraints intended to allow for
00119    *  effective optimization of numeric array processing by reducing the
00120    *  aliasing that can result from pointer representations.  It represents a
00121    *  one-dimensional array from which different multidimensional subsets can
00122    *  be accessed and modified.
00123    *
00124    *  @tparam  _Tp  Type of object in the array.
00125    */
00126   template<class _Tp>
00127     class valarray
00128     {
00129       template<class _Op>
00130         struct _UnaryOp
00131         {
00132           typedef typename __fun<_Op, _Tp>::result_type __rt;
00133           typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt;
00134         };
00135     public:
00136       typedef _Tp value_type;
00137 
00138         // _lib.valarray.cons_ construct/destroy:
00139       ///  Construct an empty array.
00140       valarray();
00141 
00142       ///  Construct an array with @a n elements.
00143       explicit valarray(size_t);
00144 
00145       ///  Construct an array with @a n elements initialized to @a t.
00146       valarray(const _Tp&, size_t);
00147 
00148       ///  Construct an array initialized to the first @a n elements of @a t.
00149       valarray(const _Tp* __restrict__, size_t);
00150 
00151       ///  Copy constructor.
00152       valarray(const valarray&);
00153 
00154 #if __cplusplus >= 201103L
00155       ///  Move constructor.
00156       valarray(valarray&&) noexcept;
00157 #endif
00158 
00159       ///  Construct an array with the same size and values in @a sa.
00160       valarray(const slice_array<_Tp>&);
00161 
00162       ///  Construct an array with the same size and values in @a ga.
00163       valarray(const gslice_array<_Tp>&);
00164 
00165       ///  Construct an array with the same size and values in @a ma.
00166       valarray(const mask_array<_Tp>&);
00167 
00168       ///  Construct an array with the same size and values in @a ia.
00169       valarray(const indirect_array<_Tp>&);
00170 
00171 #if __cplusplus >= 201103L
00172       ///  Construct an array with an initializer_list of values.
00173       valarray(initializer_list<_Tp>);
00174 #endif
00175 
00176       template<class _Dom>
00177         valarray(const _Expr<_Dom, _Tp>& __e);
00178 
00179       ~valarray() _GLIBCXX_NOEXCEPT;
00180 
00181       // _lib.valarray.assign_ assignment:
00182       /**
00183        *  @brief  Assign elements to an array.
00184        *
00185        *  Assign elements of array to values in @a v.
00186        *
00187        *  @param  __v  Valarray to get values from.
00188        */
00189       valarray<_Tp>& operator=(const valarray<_Tp>& __v);
00190 
00191 #if __cplusplus >= 201103L
00192       /**
00193        *  @brief  Move assign elements to an array.
00194        *
00195        *  Move assign elements of array to values in @a v.
00196        *
00197        *  @param  __v  Valarray to get values from.
00198        */
00199       valarray<_Tp>& operator=(valarray<_Tp>&& __v) noexcept;
00200 #endif
00201 
00202       /**
00203        *  @brief  Assign elements to a value.
00204        *
00205        *  Assign all elements of array to @a t.
00206        *
00207        *  @param  __t  Value for elements.
00208        */
00209       valarray<_Tp>& operator=(const _Tp& __t);
00210 
00211       /**
00212        *  @brief  Assign elements to an array subset.
00213        *
00214        *  Assign elements of array to values in @a sa.  Results are undefined
00215        *  if @a sa does not have the same size as this array.
00216        *
00217        *  @param  __sa  Array slice to get values from.
00218        */
00219       valarray<_Tp>& operator=(const slice_array<_Tp>& __sa);
00220 
00221       /**
00222        *  @brief  Assign elements to an array subset.
00223        *
00224        *  Assign elements of array to values in @a ga.  Results are undefined
00225        *  if @a ga does not have the same size as this array.
00226        *
00227        *  @param  __ga  Array slice to get values from.
00228        */
00229       valarray<_Tp>& operator=(const gslice_array<_Tp>& __ga);
00230 
00231       /**
00232        *  @brief  Assign elements to an array subset.
00233        *
00234        *  Assign elements of array to values in @a ma.  Results are undefined
00235        *  if @a ma does not have the same size as this array.
00236        *
00237        *  @param  __ma  Array slice to get values from.
00238        */
00239       valarray<_Tp>& operator=(const mask_array<_Tp>& __ma);
00240 
00241       /**
00242        *  @brief  Assign elements to an array subset.
00243        *
00244        *  Assign elements of array to values in @a ia.  Results are undefined
00245        *  if @a ia does not have the same size as this array.
00246        *
00247        *  @param  __ia  Array slice to get values from.
00248        */
00249       valarray<_Tp>& operator=(const indirect_array<_Tp>& __ia);
00250 
00251 #if __cplusplus >= 201103L
00252       /**
00253        *  @brief  Assign elements to an initializer_list.
00254        *
00255        *  Assign elements of array to values in @a __l.  Results are undefined
00256        *  if @a __l does not have the same size as this array.
00257        *
00258        *  @param  __l  initializer_list to get values from.
00259        */
00260       valarray& operator=(initializer_list<_Tp> __l);
00261 #endif
00262 
00263       template<class _Dom> valarray<_Tp>&
00264         operator= (const _Expr<_Dom, _Tp>&);
00265 
00266       // _lib.valarray.access_ element access:
00267       /**
00268        *  Return a reference to the i'th array element.
00269        *
00270        *  @param  __i  Index of element to return.
00271        *  @return  Reference to the i'th element.
00272        */
00273       _Tp&                operator[](size_t __i);
00274 
00275       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00276       // 389. Const overload of valarray::operator[] returns by value.
00277       const _Tp&          operator[](size_t) const;
00278 
00279       // _lib.valarray.sub_ subset operations:
00280       /**
00281        *  @brief  Return an array subset.
00282        *
00283        *  Returns a new valarray containing the elements of the array
00284        *  indicated by the slice argument.  The new valarray has the same size
00285        *  as the input slice.  @see slice.
00286        *
00287        *  @param  __s  The source slice.
00288        *  @return  New valarray containing elements in @a __s.
00289        */
00290       _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice __s) const;
00291 
00292       /**
00293        *  @brief  Return a reference to an array subset.
00294        *
00295        *  Returns a new valarray containing the elements of the array
00296        *  indicated by the slice argument.  The new valarray has the same size
00297        *  as the input slice.  @see slice.
00298        *
00299        *  @param  __s  The source slice.
00300        *  @return  New valarray containing elements in @a __s.
00301        */
00302       slice_array<_Tp>    operator[](slice __s);
00303 
00304       /**
00305        *  @brief  Return an array subset.
00306        *
00307        *  Returns a slice_array referencing the elements of the array
00308        *  indicated by the slice argument.  @see gslice.
00309        *
00310        *  @param  __s  The source slice.
00311        *  @return  Slice_array referencing elements indicated by @a __s.
00312        */
00313       _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice& __s) const;
00314 
00315       /**
00316        *  @brief  Return a reference to an array subset.
00317        *
00318        *  Returns a new valarray containing the elements of the array
00319        *  indicated by the gslice argument.  The new valarray has
00320        *  the same size as the input gslice.  @see gslice.
00321        *
00322        *  @param  __s  The source gslice.
00323        *  @return  New valarray containing elements in @a __s.
00324        */
00325       gslice_array<_Tp>   operator[](const gslice& __s);
00326 
00327       /**
00328        *  @brief  Return an array subset.
00329        *
00330        *  Returns a new valarray containing the elements of the array
00331        *  indicated by the argument.  The input is a valarray of bool which
00332        *  represents a bitmask indicating which elements should be copied into
00333        *  the new valarray.  Each element of the array is added to the return
00334        *  valarray if the corresponding element of the argument is true.
00335        *
00336        *  @param  __m  The valarray bitmask.
00337        *  @return  New valarray containing elements indicated by @a __m.
00338        */
00339       valarray<_Tp>       operator[](const valarray<bool>& __m) const;
00340 
00341       /**
00342        *  @brief  Return a reference to an array subset.
00343        *
00344        *  Returns a new mask_array referencing the elements of the array
00345        *  indicated by the argument.  The input is a valarray of bool which
00346        *  represents a bitmask indicating which elements are part of the
00347        *  subset.  Elements of the array are part of the subset if the
00348        *  corresponding element of the argument is true.
00349        *
00350        *  @param  __m  The valarray bitmask.
00351        *  @return  New valarray containing elements indicated by @a __m.
00352        */
00353       mask_array<_Tp>     operator[](const valarray<bool>& __m);
00354 
00355       /**
00356        *  @brief  Return an array subset.
00357        *
00358        *  Returns a new valarray containing the elements of the array
00359        *  indicated by the argument.  The elements in the argument are
00360        *  interpreted as the indices of elements of this valarray to copy to
00361        *  the return valarray.
00362        *
00363        *  @param  __i  The valarray element index list.
00364        *  @return  New valarray containing elements in @a __s.
00365        */
00366       _Expr<_IClos<_ValArray, _Tp>, _Tp>
00367         operator[](const valarray<size_t>& __i) const;
00368 
00369       /**
00370        *  @brief  Return a reference to an array subset.
00371        *
00372        *  Returns an indirect_array referencing the elements of the array
00373        *  indicated by the argument.  The elements in the argument are
00374        *  interpreted as the indices of elements of this valarray to include
00375        *  in the subset.  The returned indirect_array refers to these
00376        *  elements.
00377        *
00378        *  @param  __i  The valarray element index list.
00379        *  @return  Indirect_array referencing elements in @a __i.
00380        */
00381       indirect_array<_Tp> operator[](const valarray<size_t>& __i);
00382 
00383       // _lib.valarray.unary_ unary operators:
00384       ///  Return a new valarray by applying unary + to each element.
00385       typename _UnaryOp<__unary_plus>::_Rt  operator+() const;
00386 
00387       ///  Return a new valarray by applying unary - to each element.
00388       typename _UnaryOp<__negate>::_Rt      operator-() const;
00389 
00390       ///  Return a new valarray by applying unary ~ to each element.
00391       typename _UnaryOp<__bitwise_not>::_Rt operator~() const;
00392 
00393       ///  Return a new valarray by applying unary ! to each element.
00394       typename _UnaryOp<__logical_not>::_Rt operator!() const;
00395 
00396       // _lib.valarray.cassign_ computed assignment:
00397       ///  Multiply each element of array by @a t.
00398       valarray<_Tp>& operator*=(const _Tp&);
00399 
00400       ///  Divide each element of array by @a t.
00401       valarray<_Tp>& operator/=(const _Tp&);
00402 
00403       ///  Set each element e of array to e % @a t.
00404       valarray<_Tp>& operator%=(const _Tp&);
00405 
00406       ///  Add @a t to each element of array.
00407       valarray<_Tp>& operator+=(const _Tp&);
00408 
00409       ///  Subtract @a t to each element of array.
00410       valarray<_Tp>& operator-=(const _Tp&);
00411 
00412       ///  Set each element e of array to e ^ @a t.
00413       valarray<_Tp>& operator^=(const _Tp&);
00414 
00415       ///  Set each element e of array to e & @a t.
00416       valarray<_Tp>& operator&=(const _Tp&);
00417 
00418       ///  Set each element e of array to e | @a t.
00419       valarray<_Tp>& operator|=(const _Tp&);
00420 
00421       ///  Left shift each element e of array by @a t bits.
00422       valarray<_Tp>& operator<<=(const _Tp&);
00423 
00424       ///  Right shift each element e of array by @a t bits.
00425       valarray<_Tp>& operator>>=(const _Tp&);
00426 
00427       ///  Multiply elements of array by corresponding elements of @a v.
00428       valarray<_Tp>& operator*=(const valarray<_Tp>&);
00429 
00430       ///  Divide elements of array by corresponding elements of @a v.
00431       valarray<_Tp>& operator/=(const valarray<_Tp>&);
00432 
00433       ///  Modulo elements of array by corresponding elements of @a v.
00434       valarray<_Tp>& operator%=(const valarray<_Tp>&);
00435 
00436       ///  Add corresponding elements of @a v to elements of array.
00437       valarray<_Tp>& operator+=(const valarray<_Tp>&);
00438 
00439       ///  Subtract corresponding elements of @a v from elements of array.
00440       valarray<_Tp>& operator-=(const valarray<_Tp>&);
00441 
00442       ///  Logical xor corresponding elements of @a v with elements of array.
00443       valarray<_Tp>& operator^=(const valarray<_Tp>&);
00444 
00445       ///  Logical or corresponding elements of @a v with elements of array.
00446       valarray<_Tp>& operator|=(const valarray<_Tp>&);
00447 
00448       ///  Logical and corresponding elements of @a v with elements of array.
00449       valarray<_Tp>& operator&=(const valarray<_Tp>&);
00450 
00451       ///  Left shift elements of array by corresponding elements of @a v.
00452       valarray<_Tp>& operator<<=(const valarray<_Tp>&);
00453 
00454       ///  Right shift elements of array by corresponding elements of @a v.
00455       valarray<_Tp>& operator>>=(const valarray<_Tp>&);
00456 
00457       template<class _Dom>
00458         valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&);
00459       template<class _Dom>
00460         valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&);
00461       template<class _Dom>
00462         valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&);
00463       template<class _Dom>
00464         valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&);
00465       template<class _Dom>
00466         valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&);
00467       template<class _Dom>
00468         valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&);
00469       template<class _Dom>
00470         valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&);
00471       template<class _Dom>
00472         valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&);
00473       template<class _Dom>
00474         valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&);
00475       template<class _Dom>
00476         valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&);
00477 
00478       // _lib.valarray.members_ member functions:
00479 #if __cplusplus >= 201103L
00480       ///  Swap.
00481       void swap(valarray<_Tp>& __v) noexcept;
00482 #endif
00483 
00484       ///  Return the number of elements in array.
00485       size_t size() const;
00486 
00487       /**
00488        *  @brief  Return the sum of all elements in the array.
00489        *
00490        *  Accumulates the sum of all elements into a Tp using +=.  The order
00491        *  of adding the elements is unspecified.
00492        */
00493       _Tp    sum() const;
00494 
00495       ///  Return the minimum element using operator<().
00496       _Tp    min() const;
00497 
00498       ///  Return the maximum element using operator<().
00499       _Tp    max() const;
00500 
00501       /**
00502        *  @brief  Return a shifted array.
00503        *
00504        *  A new valarray is constructed as a copy of this array with elements
00505        *  in shifted positions.  For an element with index i, the new position
00506        *  is i - n.  The new valarray has the same size as the current one.
00507        *  New elements without a value are set to 0.  Elements whose new
00508        *  position is outside the bounds of the array are discarded.
00509        *
00510        *  Positive arguments shift toward index 0, discarding elements [0, n).
00511        *  Negative arguments discard elements from the top of the array.
00512        *
00513        *  @param  __n  Number of element positions to shift.
00514        *  @return  New valarray with elements in shifted positions.
00515        */
00516       valarray<_Tp> shift (int __n) const;
00517 
00518       /**
00519        *  @brief  Return a rotated array.
00520        *
00521        *  A new valarray is constructed as a copy of this array with elements
00522        *  in shifted positions.  For an element with index i, the new position
00523        *  is (i - n) % size().  The new valarray has the same size as the
00524        *  current one.  Elements that are shifted beyond the array bounds are
00525        *  shifted into the other end of the array.  No elements are lost.
00526        *
00527        *  Positive arguments shift toward index 0, wrapping around the top.
00528        *  Negative arguments shift towards the top, wrapping around to 0.
00529        *
00530        *  @param  __n  Number of element positions to rotate.
00531        *  @return  New valarray with elements in shifted positions.
00532        */
00533       valarray<_Tp> cshift(int __n) const;
00534 
00535       /**
00536        *  @brief  Apply a function to the array.
00537        *
00538        *  Returns a new valarray with elements assigned to the result of
00539        *  applying func to the corresponding element of this array.  The new
00540        *  array has the same size as this one.
00541        *
00542        *  @param  func  Function of Tp returning Tp to apply.
00543        *  @return  New valarray with transformed elements.
00544        */
00545       _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(_Tp)) const;
00546 
00547       /**
00548        *  @brief  Apply a function to the array.
00549        *
00550        *  Returns a new valarray with elements assigned to the result of
00551        *  applying func to the corresponding element of this array.  The new
00552        *  array has the same size as this one.
00553        *
00554        *  @param  func  Function of const Tp& returning Tp to apply.
00555        *  @return  New valarray with transformed elements.
00556        */
00557       _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(const _Tp&)) const;
00558 
00559       /**
00560        *  @brief  Resize array.
00561        *
00562        *  Resize this array to @a size and set all elements to @a c.  All
00563        *  references and iterators are invalidated.
00564        *
00565        *  @param  __size  New array size.
00566        *  @param  __c  New value for all elements.
00567        */
00568       void resize(size_t __size, _Tp __c = _Tp());
00569 
00570     private:
00571       size_t _M_size;
00572       _Tp* __restrict__ _M_data;
00573 
00574       friend class _Array<_Tp>;
00575     };
00576 
00577 #if __cpp_deduction_guides >= 201606
00578   template<typename _Tp, size_t _Nm>
00579     valarray(const _Tp(&)[_Nm], size_t) -> valarray<_Tp>;
00580 #endif
00581 
00582   template<typename _Tp>
00583     inline const _Tp&
00584     valarray<_Tp>::operator[](size_t __i) const
00585     {
00586       __glibcxx_requires_subscript(__i);
00587       return _M_data[__i];
00588     }
00589 
00590   template<typename _Tp>
00591     inline _Tp&
00592     valarray<_Tp>::operator[](size_t __i)
00593     {
00594       __glibcxx_requires_subscript(__i);
00595       return _M_data[__i];
00596     }
00597 
00598   // @} group numeric_arrays
00599 
00600 _GLIBCXX_END_NAMESPACE_VERSION
00601 } // namespace
00602 
00603 #include <bits/valarray_after.h>
00604 #include <bits/slice_array.h>
00605 #include <bits/gslice.h>
00606 #include <bits/gslice_array.h>
00607 #include <bits/mask_array.h>
00608 #include <bits/indirect_array.h>
00609 
00610 namespace std _GLIBCXX_VISIBILITY(default)
00611 {
00612 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00613 
00614   /**
00615    * @addtogroup numeric_arrays
00616    * @{
00617    */
00618 
00619   template<typename _Tp>
00620     inline
00621     valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {}
00622 
00623   template<typename _Tp>
00624     inline
00625     valarray<_Tp>::valarray(size_t __n)
00626     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
00627     { std::__valarray_default_construct(_M_data, _M_data + __n); }
00628 
00629   template<typename _Tp>
00630     inline
00631     valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
00632     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
00633     { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); }
00634 
00635   template<typename _Tp>
00636     inline
00637     valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
00638     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
00639     {
00640       __glibcxx_assert(__p != 0 || __n == 0);
00641       std::__valarray_copy_construct(__p, __p + __n, _M_data);
00642     }
00643 
00644   template<typename _Tp>
00645     inline
00646     valarray<_Tp>::valarray(const valarray<_Tp>& __v)
00647     : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
00648     { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
00649                                      _M_data); }
00650 
00651 #if __cplusplus >= 201103L
00652   template<typename _Tp>
00653     inline
00654     valarray<_Tp>::valarray(valarray<_Tp>&& __v) noexcept
00655     : _M_size(__v._M_size), _M_data(__v._M_data)
00656     {
00657       __v._M_size = 0;
00658       __v._M_data = 0;
00659     }
00660 #endif
00661 
00662   template<typename _Tp>
00663     inline
00664     valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
00665     : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
00666     {
00667       std::__valarray_copy_construct
00668         (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
00669     }
00670 
00671   template<typename _Tp>
00672     inline
00673     valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
00674     : _M_size(__ga._M_index.size()),
00675       _M_data(__valarray_get_storage<_Tp>(_M_size))
00676     {
00677       std::__valarray_copy_construct
00678         (__ga._M_array, _Array<size_t>(__ga._M_index),
00679          _Array<_Tp>(_M_data), _M_size);
00680     }
00681 
00682   template<typename _Tp>
00683     inline
00684     valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
00685     : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
00686     {
00687       std::__valarray_copy_construct
00688         (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
00689     }
00690 
00691   template<typename _Tp>
00692     inline
00693     valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
00694     : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
00695     {
00696       std::__valarray_copy_construct
00697         (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
00698     }
00699 
00700 #if __cplusplus >= 201103L
00701   template<typename _Tp>
00702     inline
00703     valarray<_Tp>::valarray(initializer_list<_Tp> __l)
00704     : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size()))
00705     { std::__valarray_copy_construct(__l.begin(), __l.end(), _M_data); }
00706 #endif
00707 
00708   template<typename _Tp> template<class _Dom>
00709     inline
00710     valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
00711     : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
00712     { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); }
00713 
00714   template<typename _Tp>
00715     inline
00716     valarray<_Tp>::~valarray() _GLIBCXX_NOEXCEPT
00717     {
00718       std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
00719       std::__valarray_release_memory(_M_data);
00720     }
00721 
00722   template<typename _Tp>
00723     inline valarray<_Tp>&
00724     valarray<_Tp>::operator=(const valarray<_Tp>& __v)
00725     {
00726       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00727       // 630. arrays of valarray.
00728       if (_M_size == __v._M_size)
00729         std::__valarray_copy(__v._M_data, _M_size, _M_data);
00730       else
00731         {
00732           if (_M_data)
00733             {
00734               std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
00735               std::__valarray_release_memory(_M_data);
00736             }
00737           _M_size = __v._M_size;
00738           _M_data = __valarray_get_storage<_Tp>(_M_size);
00739           std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
00740                                          _M_data);
00741         }
00742       return *this;
00743     }
00744 
00745 #if __cplusplus >= 201103L
00746   template<typename _Tp>
00747     inline valarray<_Tp>&
00748     valarray<_Tp>::operator=(valarray<_Tp>&& __v) noexcept
00749     {
00750       if (_M_data)
00751         {
00752           std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
00753           std::__valarray_release_memory(_M_data);
00754         }
00755       _M_size = __v._M_size;
00756       _M_data = __v._M_data;
00757       __v._M_size = 0;
00758       __v._M_data = 0;
00759       return *this;
00760     }
00761 
00762   template<typename _Tp>
00763     inline valarray<_Tp>&
00764     valarray<_Tp>::operator=(initializer_list<_Tp> __l)
00765     {
00766       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00767       // 630. arrays of valarray.
00768       if (_M_size == __l.size())
00769         std::__valarray_copy(__l.begin(), __l.size(), _M_data);
00770       else
00771         {
00772           if (_M_data)
00773             {
00774               std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
00775               std::__valarray_release_memory(_M_data);
00776             }
00777           _M_size = __l.size();
00778           _M_data = __valarray_get_storage<_Tp>(_M_size);
00779           std::__valarray_copy_construct(__l.begin(), __l.begin() + _M_size,
00780                                          _M_data);
00781         }
00782       return *this;
00783     }
00784 #endif
00785 
00786   template<typename _Tp>
00787     inline valarray<_Tp>&
00788     valarray<_Tp>::operator=(const _Tp& __t)
00789     {
00790       std::__valarray_fill(_M_data, _M_size, __t);
00791       return *this;
00792     }
00793 
00794   template<typename _Tp>
00795     inline valarray<_Tp>&
00796     valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
00797     {
00798       __glibcxx_assert(_M_size == __sa._M_sz);
00799       std::__valarray_copy(__sa._M_array, __sa._M_sz,
00800                            __sa._M_stride, _Array<_Tp>(_M_data));
00801       return *this;
00802     }
00803 
00804   template<typename _Tp>
00805     inline valarray<_Tp>&
00806     valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
00807     {
00808       __glibcxx_assert(_M_size == __ga._M_index.size());
00809       std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
00810                            _Array<_Tp>(_M_data), _M_size);
00811       return *this;
00812     }
00813 
00814   template<typename _Tp>
00815     inline valarray<_Tp>&
00816     valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
00817     {
00818       __glibcxx_assert(_M_size == __ma._M_sz);
00819       std::__valarray_copy(__ma._M_array, __ma._M_mask,
00820                            _Array<_Tp>(_M_data), _M_size);
00821       return *this;
00822     }
00823 
00824   template<typename _Tp>
00825     inline valarray<_Tp>&
00826     valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
00827     {
00828       __glibcxx_assert(_M_size == __ia._M_sz);
00829       std::__valarray_copy(__ia._M_array, __ia._M_index,
00830                            _Array<_Tp>(_M_data), _M_size);
00831       return *this;
00832     }
00833 
00834   template<typename _Tp> template<class _Dom>
00835     inline valarray<_Tp>&
00836     valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
00837     {
00838       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00839       // 630. arrays of valarray.
00840       if (_M_size == __e.size())
00841         std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
00842       else
00843         {
00844           if (_M_data)
00845             {
00846               std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
00847               std::__valarray_release_memory(_M_data);
00848             }
00849           _M_size = __e.size();
00850           _M_data = __valarray_get_storage<_Tp>(_M_size);
00851           std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data));
00852         }
00853       return *this;
00854     }
00855 
00856   template<typename _Tp>
00857     inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
00858     valarray<_Tp>::operator[](slice __s) const
00859     {
00860       typedef _SClos<_ValArray,_Tp> _Closure;
00861       return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
00862     }
00863 
00864   template<typename _Tp>
00865     inline slice_array<_Tp>
00866     valarray<_Tp>::operator[](slice __s)
00867     { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); }
00868 
00869   template<typename _Tp>
00870     inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
00871     valarray<_Tp>::operator[](const gslice& __gs) const
00872     {
00873       typedef _GClos<_ValArray,_Tp> _Closure;
00874       return _Expr<_Closure, _Tp>
00875         (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
00876     }
00877 
00878   template<typename _Tp>
00879     inline gslice_array<_Tp>
00880     valarray<_Tp>::operator[](const gslice& __gs)
00881     {
00882       return gslice_array<_Tp>
00883         (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
00884     }
00885 
00886   template<typename _Tp>
00887     inline valarray<_Tp>
00888     valarray<_Tp>::operator[](const valarray<bool>& __m) const
00889     {
00890       size_t __s = 0;
00891       size_t __e = __m.size();
00892       for (size_t __i=0; __i<__e; ++__i)
00893         if (__m[__i]) ++__s;
00894       return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
00895                                            _Array<bool> (__m)));
00896     }
00897 
00898   template<typename _Tp>
00899     inline mask_array<_Tp>
00900     valarray<_Tp>::operator[](const valarray<bool>& __m)
00901     {
00902       size_t __s = 0;
00903       size_t __e = __m.size();
00904       for (size_t __i=0; __i<__e; ++__i)
00905         if (__m[__i]) ++__s;
00906       return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
00907     }
00908 
00909   template<typename _Tp>
00910     inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
00911     valarray<_Tp>::operator[](const valarray<size_t>& __i) const
00912     {
00913       typedef _IClos<_ValArray,_Tp> _Closure;
00914       return _Expr<_Closure, _Tp>(_Closure(*this, __i));
00915     }
00916 
00917   template<typename _Tp>
00918     inline indirect_array<_Tp>
00919     valarray<_Tp>::operator[](const valarray<size_t>& __i)
00920     {
00921       return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
00922                                  _Array<size_t>(__i));
00923     }
00924 
00925 #if __cplusplus >= 201103L
00926   template<class _Tp>
00927     inline void
00928     valarray<_Tp>::swap(valarray<_Tp>& __v) noexcept
00929     {
00930       std::swap(_M_size, __v._M_size);
00931       std::swap(_M_data, __v._M_data);
00932     }
00933 #endif
00934 
00935   template<class _Tp>
00936     inline size_t
00937     valarray<_Tp>::size() const
00938     { return _M_size; }
00939 
00940   template<class _Tp>
00941     inline _Tp
00942     valarray<_Tp>::sum() const
00943     {
00944       __glibcxx_assert(_M_size > 0);
00945       return std::__valarray_sum(_M_data, _M_data + _M_size);
00946     }
00947 
00948   template<class _Tp>
00949      inline valarray<_Tp>
00950      valarray<_Tp>::shift(int __n) const
00951      {
00952        valarray<_Tp> __ret;
00953 
00954        if (_M_size == 0)
00955          return __ret;
00956 
00957        _Tp* __restrict__ __tmp_M_data =
00958          std::__valarray_get_storage<_Tp>(_M_size);
00959 
00960        if (__n == 0)
00961          std::__valarray_copy_construct(_M_data,
00962                                         _M_data + _M_size, __tmp_M_data);
00963        else if (__n > 0)      // shift left
00964          {
00965            if (size_t(__n) > _M_size)
00966              __n = int(_M_size);
00967 
00968            std::__valarray_copy_construct(_M_data + __n,
00969                                           _M_data + _M_size, __tmp_M_data);
00970            std::__valarray_default_construct(__tmp_M_data + _M_size - __n,
00971                                              __tmp_M_data + _M_size);
00972          }
00973        else                   // shift right
00974          {
00975            if (-size_t(__n) > _M_size)
00976              __n = -int(_M_size);
00977 
00978            std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
00979                                           __tmp_M_data - __n);
00980            std::__valarray_default_construct(__tmp_M_data,
00981                                              __tmp_M_data - __n);
00982          }
00983 
00984        __ret._M_size = _M_size;
00985        __ret._M_data = __tmp_M_data;
00986        return __ret;
00987      }
00988 
00989   template<class _Tp>
00990      inline valarray<_Tp>
00991      valarray<_Tp>::cshift(int __n) const
00992      {
00993        valarray<_Tp> __ret;
00994 
00995        if (_M_size == 0)
00996          return __ret;
00997 
00998        _Tp* __restrict__ __tmp_M_data =
00999          std::__valarray_get_storage<_Tp>(_M_size);
01000 
01001        if (__n == 0)
01002          std::__valarray_copy_construct(_M_data,
01003                                         _M_data + _M_size, __tmp_M_data);
01004        else if (__n > 0)      // cshift left
01005          {
01006            if (size_t(__n) > _M_size)
01007              __n = int(__n % _M_size);
01008 
01009            std::__valarray_copy_construct(_M_data, _M_data + __n,
01010                                           __tmp_M_data + _M_size - __n);
01011            std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size,
01012                                           __tmp_M_data);
01013          }
01014        else                   // cshift right
01015          {
01016            if (-size_t(__n) > _M_size)
01017              __n = -int(-size_t(__n) % _M_size);
01018 
01019            std::__valarray_copy_construct(_M_data + _M_size + __n,
01020                                           _M_data + _M_size, __tmp_M_data);
01021            std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
01022                                           __tmp_M_data - __n);
01023          }
01024 
01025        __ret._M_size = _M_size;
01026        __ret._M_data = __tmp_M_data;
01027        return __ret;
01028      }
01029 
01030   template<class _Tp>
01031     inline void
01032     valarray<_Tp>::resize(size_t __n, _Tp __c)
01033     {
01034       // This complication is so to make valarray<valarray<T> > work
01035       // even though it is not required by the standard.  Nobody should
01036       // be saying valarray<valarray<T> > anyway.  See the specs.
01037       std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
01038       if (_M_size != __n)
01039         {
01040           std::__valarray_release_memory(_M_data);
01041           _M_size = __n;
01042           _M_data = __valarray_get_storage<_Tp>(__n);
01043         }
01044       std::__valarray_fill_construct(_M_data, _M_data + __n, __c);
01045     }
01046 
01047   template<typename _Tp>
01048     inline _Tp
01049     valarray<_Tp>::min() const
01050     {
01051       __glibcxx_assert(_M_size > 0);
01052       return *std::min_element(_M_data, _M_data + _M_size);
01053     }
01054 
01055   template<typename _Tp>
01056     inline _Tp
01057     valarray<_Tp>::max() const
01058     {
01059       __glibcxx_assert(_M_size > 0);
01060       return *std::max_element(_M_data, _M_data + _M_size);
01061     }
01062 
01063   template<class _Tp>
01064     inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp>
01065     valarray<_Tp>::apply(_Tp func(_Tp)) const
01066     {
01067       typedef _ValFunClos<_ValArray, _Tp> _Closure;
01068       return _Expr<_Closure, _Tp>(_Closure(*this, func));
01069     }
01070 
01071   template<class _Tp>
01072     inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp>
01073     valarray<_Tp>::apply(_Tp func(const _Tp &)) const
01074     {
01075       typedef _RefFunClos<_ValArray, _Tp> _Closure;
01076       return _Expr<_Closure, _Tp>(_Closure(*this, func));
01077     }
01078 
01079 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name)                     \
01080   template<typename _Tp>                                                \
01081     inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt        \
01082     valarray<_Tp>::operator _Op() const                                 \
01083     {                                                                   \
01084       typedef _UnClos<_Name, _ValArray, _Tp> _Closure;                  \
01085       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
01086       return _Expr<_Closure, _Rt>(_Closure(*this));                     \
01087     }
01088 
01089     _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
01090     _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
01091     _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
01092     _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
01093 
01094 #undef _DEFINE_VALARRAY_UNARY_OPERATOR
01095 
01096 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name)               \
01097   template<class _Tp>                                                   \
01098     inline valarray<_Tp>&                                               \
01099     valarray<_Tp>::operator _Op##=(const _Tp &__t)                      \
01100     {                                                                   \
01101       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t);     \
01102       return *this;                                                     \
01103     }                                                                   \
01104                                                                         \
01105   template<class _Tp>                                                   \
01106     inline valarray<_Tp>&                                               \
01107     valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v)            \
01108     {                                                                   \
01109       __glibcxx_assert(_M_size == __v._M_size);                         \
01110       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size,           \
01111                                _Array<_Tp>(__v._M_data));               \
01112       return *this;                                                     \
01113     }
01114 
01115 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
01116 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
01117 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
01118 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
01119 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
01120 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
01121 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
01122 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
01123 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
01124 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
01125 
01126 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
01127 
01128 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name)          \
01129   template<class _Tp> template<class _Dom>                              \
01130     inline valarray<_Tp>&                                               \
01131     valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e)         \
01132     {                                                                   \
01133       _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size);     \
01134       return *this;                                                     \
01135     }
01136 
01137 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
01138 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
01139 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
01140 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
01141 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
01142 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
01143 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
01144 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
01145 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
01146 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
01147 
01148 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
01149 
01150 
01151 #define _DEFINE_BINARY_OPERATOR(_Op, _Name)                             \
01152   template<typename _Tp>                                                \
01153     inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>,       \
01154                  typename __fun<_Name, _Tp>::result_type>               \
01155     operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w)    \
01156     {                                                                   \
01157       __glibcxx_assert(__v.size() == __w.size());                       \
01158       typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \
01159       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
01160       return _Expr<_Closure, _Rt>(_Closure(__v, __w));                  \
01161     }                                                                   \
01162                                                                         \
01163   template<typename _Tp>                                                \
01164     inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>,        \
01165                  typename __fun<_Name, _Tp>::result_type>               \
01166     operator _Op(const valarray<_Tp>& __v,                              \
01167                  const typename valarray<_Tp>::value_type& __t)         \
01168     {                                                                   \
01169       typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \
01170       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
01171       return _Expr<_Closure, _Rt>(_Closure(__v, __t));                  \
01172     }                                                                   \
01173                                                                         \
01174   template<typename _Tp>                                                \
01175     inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>,       \
01176                  typename __fun<_Name, _Tp>::result_type>               \
01177     operator _Op(const typename valarray<_Tp>::value_type& __t,         \
01178                  const valarray<_Tp>& __v)                              \
01179     {                                                                   \
01180       typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \
01181       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
01182       return _Expr<_Closure, _Rt>(_Closure(__t, __v));                  \
01183     }
01184 
01185 _DEFINE_BINARY_OPERATOR(+, __plus)
01186 _DEFINE_BINARY_OPERATOR(-, __minus)
01187 _DEFINE_BINARY_OPERATOR(*, __multiplies)
01188 _DEFINE_BINARY_OPERATOR(/, __divides)
01189 _DEFINE_BINARY_OPERATOR(%, __modulus)
01190 _DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
01191 _DEFINE_BINARY_OPERATOR(&, __bitwise_and)
01192 _DEFINE_BINARY_OPERATOR(|, __bitwise_or)
01193 _DEFINE_BINARY_OPERATOR(<<, __shift_left)
01194 _DEFINE_BINARY_OPERATOR(>>, __shift_right)
01195 _DEFINE_BINARY_OPERATOR(&&, __logical_and)
01196 _DEFINE_BINARY_OPERATOR(||, __logical_or)
01197 _DEFINE_BINARY_OPERATOR(==, __equal_to)
01198 _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
01199 _DEFINE_BINARY_OPERATOR(<, __less)
01200 _DEFINE_BINARY_OPERATOR(>, __greater)
01201 _DEFINE_BINARY_OPERATOR(<=, __less_equal)
01202 _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
01203 
01204 #undef _DEFINE_BINARY_OPERATOR
01205 
01206 #if __cplusplus >= 201103L
01207   /**
01208    *  @brief  Return an iterator pointing to the first element of
01209    *          the valarray.
01210    *  @param  __va  valarray.
01211    */
01212   template<class _Tp>
01213     inline _Tp*
01214     begin(valarray<_Tp>& __va)
01215     { return std::__addressof(__va[0]); }
01216 
01217   /**
01218    *  @brief  Return an iterator pointing to the first element of
01219    *          the const valarray.
01220    *  @param  __va  valarray.
01221    */
01222   template<class _Tp>
01223     inline const _Tp*
01224     begin(const valarray<_Tp>& __va)
01225     { return std::__addressof(__va[0]); }
01226 
01227   /**
01228    *  @brief  Return an iterator pointing to one past the last element of
01229    *          the valarray.
01230    *  @param  __va  valarray.
01231    */
01232   template<class _Tp>
01233     inline _Tp*
01234     end(valarray<_Tp>& __va)
01235     { return std::__addressof(__va[0]) + __va.size(); }
01236 
01237   /**
01238    *  @brief  Return an iterator pointing to one past the last element of
01239    *          the const valarray.
01240    *  @param  __va  valarray.
01241    */
01242   template<class _Tp>
01243     inline const _Tp*
01244     end(const valarray<_Tp>& __va)
01245     { return std::__addressof(__va[0]) + __va.size(); }
01246 #endif // C++11
01247 
01248   // @} group numeric_arrays
01249 
01250 _GLIBCXX_END_NAMESPACE_VERSION
01251 } // namespace
01252 
01253 #endif /* _GLIBCXX_VALARRAY */