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