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