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