# 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
    00004 // Free Software Foundation, Inc.
    00005 //
    00006 // This file is part of the GNU ISO C++ Library.  This library is free
    00007 // software; you can redistribute it and/or modify it under the
    00008 // terms of the GNU General Public License as published by the
    00009 // Free Software Foundation; either version 2, or (at your option)
    00010 // any later version.
    00011
    00012 // This library is distributed in the hope that it will be useful,
    00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00015 // GNU General Public License for more details.
    00016
    00017 // You should have received a copy of the GNU General Public License along
    00018 // with this library; see the file COPYING.  If not, write to the Free
    00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
    00020 // USA.
    00021
    00022 // As a special exception, you may use this file as part of a free software
    00023 // library without restriction.  Specifically, if other files instantiate
    00024 // templates or use macros or inline functions from this file, or you compile
    00025 // this file and link it with other files to produce an executable, this
    00026 // file does not by itself cause the resulting executable to be covered by
    00027 // the GNU General Public License.  This exception does not however
    00028 // invalidate any other reasons why the executable file might be covered by
    00029 // the GNU General Public License.
    00030
    00031 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
    00032
    00038 #ifndef _CPP_VALARRAY
    00039 #define _CPP_VALARRAY 1
    00040
    00041 #pragma GCC system_header
    00042
    00043 #include <bits/c++config.h>
    00044 #include <cstddef>
    00045 #include <cmath>
    00046 #include <cstdlib>
    00047 #include <numeric>
    00048 #include <functional>
    00049 #include <algorithm>
    00050
    00051 namespace std
    00052 {
    00053     template<class _Clos, typename _Tp> class _Expr;
    00054
    00055     template<typename _Tp1, typename _Tp2> class _ValArray;
    00056
    00057     template<template<class> class _Oper,
    00058         template<class, class> class _Meta, class _Dom> struct _UnClos;
    00059
    00060     template<template<class> class _Oper,
    00061         template<class, class> class _Meta1,
    00062         template<class, class> class _Meta2,
    00063         class _Dom1, class _Dom2> class _BinClos;
    00064
    00065     template<template<class, class> class _Meta, class _Dom> class _SClos;
    00066
    00067     template<template<class, class> class _Meta, class _Dom> class _GClos;
    00068
    00069     template<template<class, class> class _Meta, class _Dom> class _IClos;
    00070
    00071     template<template<class, class> class _Meta, class _Dom> class _ValFunClos;
    00072
    00073     template<template<class, class> class _Meta, class _Dom> class _RefFunClos;
    00074
    00075     template<class _Tp> struct _Unary_plus;
    00076     template<class _Tp> struct _Bitwise_and;
    00077     template<class _Tp> struct _Bitwise_or;
    00078     template<class _Tp> struct _Bitwise_xor;
    00079     template<class _Tp> struct _Bitwise_not;
    00080     template<class _Tp> struct _Shift_left;
    00081     template<class _Tp> struct _Shift_right;
    00082
    00083     template<class _Tp> class valarray;   // An array of type _Tp
    00084     class slice;                          // BLAS-like slice out of an array
    00085     template<class _Tp> class slice_array;
    00086     class gslice;                         // generalized slice out of an array
    00087     template<class _Tp> class gslice_array;
    00088     template<class _Tp> class mask_array;     // masked array
    00089     template<class _Tp> class indirect_array; // indirected array
    00090
    00091 } // namespace std
    00092
    00093 #include <bits/valarray_array.h>
    00094 #include <bits/valarray_meta.h>
    00095
    00096 namespace std
    00097 {
    00098   template<class _Tp> class valarray
    00099   {
    00100   public:
    00101       typedef _Tp value_type;
    00102
    00103       // _lib.valarray.cons_ construct/destroy:
    00104       valarray();
    00105       explicit valarray(size_t);
    00106       valarray(const _Tp&, size_t);
    00107       valarray(const _Tp* __restrict__, size_t);
    00108       valarray(const valarray&);
    00109       valarray(const slice_array<_Tp>&);
    00110       valarray(const gslice_array<_Tp>&);
    00111       valarray(const mask_array<_Tp>&);
    00112       valarray(const indirect_array<_Tp>&);
    00113       template<class _Dom>
    00114       valarray(const _Expr<_Dom,_Tp>& __e);
    00115      ~valarray();
    00116
    00117       // _lib.valarray.assign_ assignment:
    00118       valarray<_Tp>& operator=(const valarray<_Tp>&);
    00119       valarray<_Tp>& operator=(const _Tp&);
    00120       valarray<_Tp>& operator=(const slice_array<_Tp>&);
    00121       valarray<_Tp>& operator=(const gslice_array<_Tp>&);
    00122       valarray<_Tp>& operator=(const mask_array<_Tp>&);
    00123       valarray<_Tp>& operator=(const indirect_array<_Tp>&);
    00124
    00125       template<class _Dom> valarray<_Tp>&
    00126         operator= (const _Expr<_Dom,_Tp>&);
    00127
    00128       // _lib.valarray.access_ element access:
    00129       // XXX: LWG to be resolved.
    00130       const _Tp&                 operator[](size_t) const;
    00131       _Tp&                operator[](size_t);
    00132       // _lib.valarray.sub_ subset operations:
    00133       _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const;
    00134       slice_array<_Tp>    operator[](slice);
    00135       _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const;
    00136       gslice_array<_Tp>   operator[](const gslice&);
    00137       valarray<_Tp>          operator[](const valarray<bool>&) const;
    00138       mask_array<_Tp>     operator[](const valarray<bool>&);
    00139       _Expr<_IClos<_ValArray, _Tp>, _Tp>
    00140         operator[](const valarray<size_t>&) const;
    00141       indirect_array<_Tp> operator[](const valarray<size_t>&);
    00142
    00143       // _lib.valarray.unary_ unary operators:
    00144       _Expr<_UnClos<_Unary_plus,_ValArray,_Tp>,_Tp>  operator+ () const;
    00145       _Expr<_UnClos<negate,_ValArray,_Tp>,_Tp> operator- () const;
    00146       _Expr<_UnClos<_Bitwise_not,_ValArray,_Tp>,_Tp> operator~ () const;
    00147       _Expr<_UnClos<logical_not,_ValArray,_Tp>,bool> operator! () const;
    00148
    00149       // _lib.valarray.cassign_ computed assignment:
    00150       valarray<_Tp>& operator*= (const _Tp&);
    00151       valarray<_Tp>& operator/= (const _Tp&);
    00152       valarray<_Tp>& operator%= (const _Tp&);
    00153       valarray<_Tp>& operator+= (const _Tp&);
    00154       valarray<_Tp>& operator-= (const _Tp&);
    00155       valarray<_Tp>& operator^= (const _Tp&);
    00156       valarray<_Tp>& operator&= (const _Tp&);
    00157       valarray<_Tp>& operator|= (const _Tp&);
    00158       valarray<_Tp>& operator<<=(const _Tp&);
    00159       valarray<_Tp>& operator>>=(const _Tp&);
    00160       valarray<_Tp>& operator*= (const valarray<_Tp>&);
    00161       valarray<_Tp>& operator/= (const valarray<_Tp>&);
    00162       valarray<_Tp>& operator%= (const valarray<_Tp>&);
    00163       valarray<_Tp>& operator+= (const valarray<_Tp>&);
    00164       valarray<_Tp>& operator-= (const valarray<_Tp>&);
    00165       valarray<_Tp>& operator^= (const valarray<_Tp>&);
    00166       valarray<_Tp>& operator|= (const valarray<_Tp>&);
    00167       valarray<_Tp>& operator&= (const valarray<_Tp>&);
    00168       valarray<_Tp>& operator<<=(const valarray<_Tp>&);
    00169       valarray<_Tp>& operator>>=(const valarray<_Tp>&);
    00170
    00171       template<class _Dom>
    00172         valarray<_Tp>& operator*= (const _Expr<_Dom,_Tp>&);
    00173       template<class _Dom>
    00174         valarray<_Tp>& operator/= (const _Expr<_Dom,_Tp>&);
    00175       template<class _Dom>
    00176         valarray<_Tp>& operator%= (const _Expr<_Dom,_Tp>&);
    00177       template<class _Dom>
    00178         valarray<_Tp>& operator+= (const _Expr<_Dom,_Tp>&);
    00179       template<class _Dom>
    00180         valarray<_Tp>& operator-= (const _Expr<_Dom,_Tp>&);
    00181       template<class _Dom>
    00182         valarray<_Tp>& operator^= (const _Expr<_Dom,_Tp>&);
    00183       template<class _Dom>
    00184         valarray<_Tp>& operator|= (const _Expr<_Dom,_Tp>&);
    00185       template<class _Dom>
    00186         valarray<_Tp>& operator&= (const _Expr<_Dom,_Tp>&);
    00187       template<class _Dom>
    00188         valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&);
    00189       template<class _Dom>
    00190         valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&);
    00191
    00192
    00193       // _lib.valarray.members_ member functions:
    00194       size_t size() const;
    00195       _Tp    sum() const;
    00196       _Tp    min() const;
    00197       _Tp    max() const;
    00198
    00199 //           // FIXME: Extension
    00200 //       _Tp    product () const;
    00201
    00202       valarray<_Tp> shift (int) const;
    00203       valarray<_Tp> cshift(int) const;
    00204       _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const;
    00205       _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const;
    00206       void resize(size_t __size, _Tp __c = _Tp());
    00207
    00208   private:
    00209       size_t _M_size;
    00210       _Tp* __restrict__ _M_data;
    00211
    00212       friend class _Array<_Tp>;
    00213   };
    00214
    00215
    00216   template<typename _Tp> struct _Unary_plus : unary_function<_Tp,_Tp> {
    00217       _Tp operator() (const _Tp& __t) const { return __t; }
    00218   };
    00219
    00220   template<typename _Tp> struct _Bitwise_and : binary_function<_Tp,_Tp,_Tp> {
    00221       _Tp operator() (_Tp __x, _Tp __y) const { return __x & __y; }
    00222   };
    00223
    00224   template<typename _Tp> struct _Bitwise_or : binary_function<_Tp,_Tp,_Tp> {
    00225       _Tp operator() (_Tp __x, _Tp __y) const { return __x | __y; }
    00226   };
    00227
    00228   template<typename _Tp> struct _Bitwise_xor : binary_function<_Tp,_Tp,_Tp> {
    00229       _Tp operator() (_Tp __x, _Tp __y) const { return __x ^ __y; }
    00230   };
    00231
    00232   template<typename _Tp> struct _Bitwise_not : unary_function<_Tp,_Tp> {
    00233       _Tp operator() (_Tp __t) const { return ~__t; }
    00234   };
    00235
    00236   template<typename _Tp> struct _Shift_left : unary_function<_Tp,_Tp> {
    00237       _Tp operator() (_Tp __x, _Tp __y) const { return __x << __y; }
    00238   };
    00239
    00240   template<typename _Tp> struct _Shift_right : unary_function<_Tp,_Tp> {
    00241       _Tp operator() (_Tp __x, _Tp __y) const { return __x >> __y; }
    00242   };
    00243
    00244
    00245   template<typename _Tp>
    00246   inline const _Tp&
    00247   valarray<_Tp>::operator[] (size_t __i) const
    00248   { return _M_data[__i]; }
    00249
    00250   template<typename _Tp>
    00251   inline _Tp&
    00252   valarray<_Tp>::operator[] (size_t __i)
    00253   { return _M_data[__i]; }
    00254
    00255 } // std::
    00256
    00257 #include <bits/slice.h>
    00258 #include <bits/slice_array.h>
    00259 #include <bits/gslice.h>
    00260 #include <bits/gslice_array.h>
    00261 #include <bits/mask_array.h>
    00262 #include <bits/indirect_array.h>
    00263
    00264 namespace std
    00265 {
    00266   template<typename _Tp>
    00267   inline valarray<_Tp>::valarray () : _M_size (0), _M_data (0) {}
    00268
    00269   template<typename _Tp>
    00270   inline valarray<_Tp>::valarray (size_t __n)
    00271       : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
    00272   { __valarray_default_construct(_M_data, _M_data + __n); }
    00273
    00274   template<typename _Tp>
    00275   inline valarray<_Tp>::valarray (const _Tp& __t, size_t __n)
    00276     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
    00277   { __valarray_fill_construct (_M_data, _M_data + __n, __t); }
    00278
    00279   template<typename _Tp>
    00280   inline valarray<_Tp>::valarray (const _Tp* __restrict__ __p, size_t __n)
    00281     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
    00282   { __valarray_copy_construct (__p, __p + __n, _M_data); }
    00283
    00284   template<typename _Tp>
    00285   inline valarray<_Tp>::valarray (const valarray<_Tp>& __v)
    00286     : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
    00287   { __valarray_copy_construct (__v._M_data, __v._M_data + _M_size, _M_data); }
    00288
    00289   template<typename _Tp>
    00290   inline valarray<_Tp>::valarray (const slice_array<_Tp>& __sa)
    00291     : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
    00292   {
    00293     __valarray_copy
    00294       (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
    00295   }
    00296
    00297   template<typename _Tp>
    00298   inline valarray<_Tp>::valarray (const gslice_array<_Tp>& __ga)
    00299     : _M_size(__ga._M_index.size()),
    00300       _M_data(__valarray_get_storage<_Tp>(_M_size))
    00301   {
    00302     __valarray_copy
    00303       (__ga._M_array, _Array<size_t>(__ga._M_index),
    00304        _Array<_Tp>(_M_data), _M_size);
    00305   }
    00306
    00307   template<typename _Tp>
    00308   inline valarray<_Tp>::valarray (const mask_array<_Tp>& __ma)
    00309     : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
    00310   {
    00311     __valarray_copy
    00312       (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
    00313   }
    00314
    00315   template<typename _Tp>
    00316   inline valarray<_Tp>::valarray (const indirect_array<_Tp>& __ia)
    00317     : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
    00318   {
    00319     __valarray_copy
    00320       (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
    00321   }
    00322
    00323   template<typename _Tp> template<class _Dom>
    00324   inline valarray<_Tp>::valarray (const _Expr<_Dom, _Tp>& __e)
    00325     : _M_size(__e.size ()), _M_data(__valarray_get_storage<_Tp>(_M_size))
    00326   { __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); }
    00327
    00328   template<typename _Tp>
    00329   inline valarray<_Tp>::~valarray ()
    00330   {
    00331       __valarray_destroy_elements(_M_data, _M_data + _M_size);
    00332       __valarray_release_memory(_M_data);
    00333   }
    00334
    00335   template<typename _Tp>
    00336   inline valarray<_Tp>&
    00337   valarray<_Tp>::operator= (const valarray<_Tp>& __v)
    00338   {
    00339       __valarray_copy(__v._M_data, _M_size, _M_data);
    00340       return *this;
    00341   }
    00342
    00343   template<typename _Tp>
    00344   inline valarray<_Tp>&
    00345   valarray<_Tp>::operator= (const _Tp& __t)
    00346   {
    00347       __valarray_fill (_M_data, _M_size, __t);
    00348       return *this;
    00349   }
    00350
    00351   template<typename _Tp>
    00352   inline valarray<_Tp>&
    00353   valarray<_Tp>::operator= (const slice_array<_Tp>& __sa)
    00354   {
    00355       __valarray_copy (__sa._M_array, __sa._M_sz,
    00356               __sa._M_stride, _Array<_Tp>(_M_data));
    00357       return *this;
    00358   }
    00359
    00360   template<typename _Tp>
    00361   inline valarray<_Tp>&
    00362   valarray<_Tp>::operator= (const gslice_array<_Tp>& __ga)
    00363   {
    00364       __valarray_copy (__ga._M_array, _Array<size_t>(__ga._M_index),
    00365               _Array<_Tp>(_M_data), _M_size);
    00366       return *this;
    00367   }
    00368
    00369   template<typename _Tp>
    00370   inline valarray<_Tp>&
    00371   valarray<_Tp>::operator= (const mask_array<_Tp>& __ma)
    00372   {
    00373       __valarray_copy (__ma._M_array, __ma._M_mask,
    00374               _Array<_Tp>(_M_data), _M_size);
    00375       return *this;
    00376   }
    00377
    00378   template<typename _Tp>
    00379   inline valarray<_Tp>&
    00380   valarray<_Tp>::operator= (const indirect_array<_Tp>& __ia)
    00381   {
    00382       __valarray_copy (__ia._M_array, __ia._M_index,
    00383                _Array<_Tp>(_M_data), _M_size);
    00384       return *this;
    00385   }
    00386
    00387   template<typename _Tp> template<class _Dom>
    00388   inline valarray<_Tp>&
    00389   valarray<_Tp>::operator= (const _Expr<_Dom, _Tp>& __e)
    00390   {
    00391       __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data));
    00392       return *this;
    00393   }
    00394
    00395   template<typename _Tp>
    00396   inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
    00397   valarray<_Tp>::operator[] (slice __s) const
    00398   {
    00399       typedef _SClos<_ValArray,_Tp> _Closure;
    00400       return _Expr<_Closure, _Tp> (_Closure (_Array<_Tp>(_M_data), __s));
    00401   }
    00402
    00403   template<typename _Tp>
    00404   inline slice_array<_Tp>
    00405   valarray<_Tp>::operator[] (slice __s)
    00406   {
    00407       return slice_array<_Tp> (_Array<_Tp>(_M_data), __s);
    00408   }
    00409
    00410   template<typename _Tp>
    00411   inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
    00412   valarray<_Tp>::operator[] (const gslice& __gs) const
    00413   {
    00414       typedef _GClos<_ValArray,_Tp> _Closure;
    00415       return _Expr<_Closure, _Tp>
    00416           (_Closure (_Array<_Tp>(_M_data), __gs._M_index->_M_index));
    00417   }
    00418
    00419   template<typename _Tp>
    00420   inline gslice_array<_Tp>
    00421   valarray<_Tp>::operator[] (const gslice& __gs)
    00422   {
    00423       return gslice_array<_Tp>
    00424           (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
    00425   }
    00426
    00427   template<typename _Tp>
    00428   inline valarray<_Tp>
    00429   valarray<_Tp>::operator[] (const valarray<bool>& __m) const
    00430   {
    00431       size_t __s (0);
    00432       size_t __e (__m.size ());
    00433       for (size_t __i=0; __i<__e; ++__i)
    00434           if (__m[__i]) ++__s;
    00435       return valarray<_Tp> (mask_array<_Tp> (_Array<_Tp>(_M_data), __s,
    00436                                          _Array<bool> (__m)));
    00437   }
    00438
    00439   template<typename _Tp>
    00440   inline mask_array<_Tp>
    00441   valarray<_Tp>::operator[] (const valarray<bool>& __m)
    00442   {
    00443       size_t __s (0);
    00444       size_t __e (__m.size ());
    00445       for (size_t __i=0; __i<__e; ++__i)
    00446           if (__m[__i]) ++__s;
    00447       return mask_array<_Tp> (_Array<_Tp>(_M_data), __s, _Array<bool> (__m));
    00448   }
    00449
    00450   template<typename _Tp>
    00451   inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
    00452   valarray<_Tp>::operator[] (const valarray<size_t>& __i) const
    00453   {
    00454       typedef _IClos<_ValArray,_Tp> _Closure;
    00455       return _Expr<_Closure, _Tp> (_Closure (*this, __i));
    00456   }
    00457
    00458   template<typename _Tp>
    00459   inline indirect_array<_Tp>
    00460   valarray<_Tp>::operator[] (const valarray<size_t>& __i)
    00461   {
    00462       return indirect_array<_Tp> (_Array<_Tp>(_M_data), __i.size(),
    00463                                 _Array<size_t> (__i));
    00464   }
    00465
    00466   template<class _Tp>
    00467   inline size_t valarray<_Tp>::size () const { return _M_size; }
    00468
    00469   template<class _Tp>
    00470   inline _Tp
    00471   valarray<_Tp>::sum () const
    00472   {
    00473       return __valarray_sum(_M_data, _M_data + _M_size);
    00474   }
    00475
    00476 //   template<typename _Tp>
    00477 //   inline _Tp
    00478 //   valarray<_Tp>::product () const
    00479 //   {
    00480 //       return __valarray_product(_M_data, _M_data + _M_size);
    00481 //   }
    00482
    00483   template <class _Tp>
    00484      inline valarray<_Tp>
    00485      valarray<_Tp>::shift(int __n) const
    00486      {
    00487        _Tp* const __a = static_cast<_Tp*>
    00488          (__builtin_alloca(sizeof(_Tp) * _M_size));
    00489        if (__n == 0)                          // no shift
    00490          __valarray_copy_construct(_M_data, _M_data + _M_size, __a);
    00491        else if (__n > 0)         // __n > 0: shift left
    00492          {
    00493            if (size_t(__n) > _M_size)
    00494              __valarray_default_construct(__a, __a + __n);
    00495            else
    00496              {
    00497                __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
    00498                __valarray_default_construct(__a+_M_size-__n, __a + _M_size);
    00499              }
    00500          }
    00501        else                        // __n < 0: shift right
    00502          {
    00503            __valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n);
    00504            __valarray_default_construct(__a, __a - __n);
    00505          }
    00506        return valarray<_Tp> (__a, _M_size);
    00507      }
    00508
    00509   template <class _Tp>
    00510      inline valarray<_Tp>
    00511      valarray<_Tp>::cshift (int __n) const
    00512      {
    00513        _Tp* const __a = static_cast<_Tp*>
    00514          (__builtin_alloca (sizeof(_Tp) * _M_size));
    00515        if (__n == 0)               // no cshift
    00516          __valarray_copy_construct(_M_data, _M_data + _M_size, __a);
    00517        else if (__n > 0)           // cshift left
    00518          {
    00519            __valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n);
    00520            __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
    00521          }
    00522        else                        // cshift right
    00523          {
    00524            __valarray_copy_construct
    00525              (_M_data + _M_size+__n, _M_data + _M_size, __a);
    00526            __valarray_copy_construct
    00527              (_M_data, _M_data + _M_size+__n, __a - __n);
    00528          }
    00529        return valarray<_Tp>(__a, _M_size);
    00530      }
    00531
    00532   template <class _Tp>
    00533   inline void
    00534   valarray<_Tp>::resize (size_t __n, _Tp __c)
    00535   {
    00536     // This complication is so to make valarray<valarray<T> > work
    00537     // even though it is not required by the standard.  Nobody should
    00538     // be saying valarray<valarray<T> > anyway.  See the specs.
    00539     __valarray_destroy_elements(_M_data, _M_data + _M_size);
    00540     if (_M_size != __n)
    00541       {
    00542         __valarray_release_memory(_M_data);
    00543         _M_size = __n;
    00544         _M_data = __valarray_get_storage<_Tp>(__n);
    00545       }
    00546     __valarray_fill_construct(_M_data, _M_data + __n, __c);
    00547   }
    00548
    00549   template<typename _Tp>
    00550   inline _Tp
    00551   valarray<_Tp>::min() const
    00552   {
    00553       return *min_element (_M_data, _M_data+_M_size);
    00554   }
    00555
    00556   template<typename _Tp>
    00557   inline _Tp
    00558   valarray<_Tp>::max() const
    00559   {
    00560       return *max_element (_M_data, _M_data+_M_size);
    00561   }
    00562
    00563   template<class _Tp>
    00564   inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp>
    00565   valarray<_Tp>::apply (_Tp func (_Tp)) const
    00566   {
    00567       typedef _ValFunClos<_ValArray,_Tp> _Closure;
    00568       return _Expr<_Closure,_Tp> (_Closure (*this, func));
    00569   }
    00570
    00571   template<class _Tp>
    00572   inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp>
    00573   valarray<_Tp>::apply (_Tp func (const _Tp &)) const
    00574   {
    00575       typedef _RefFunClos<_ValArray,_Tp> _Closure;
    00576       return _Expr<_Closure,_Tp> (_Closure (*this, func));
    00577   }
    00578
    00579 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name)                     \
    00580   template<typename _Tp>                        \
    00581   inline _Expr<_UnClos<_Name,_ValArray,_Tp>, _Tp>                   \
    00582   valarray<_Tp>::operator _Op() const                   \
    00583   {                                 \
    00584       typedef _UnClos<_Name,_ValArray,_Tp> _Closure;                    \
    00585       return _Expr<_Closure, _Tp> (_Closure (*this));           \
    00586   }
    00587
    00588     _DEFINE_VALARRAY_UNARY_OPERATOR(+, _Unary_plus)
    00589     _DEFINE_VALARRAY_UNARY_OPERATOR(-, negate)
    00590     _DEFINE_VALARRAY_UNARY_OPERATOR(~, _Bitwise_not)
    00591
    00592 #undef _DEFINE_VALARRAY_UNARY_OPERATOR
    00593
    00594   template<typename _Tp>
    00595   inline _Expr<_UnClos<logical_not,_ValArray,_Tp>, bool>
    00596   valarray<_Tp>::operator!() const
    00597   {
    00598       typedef _UnClos<logical_not,_ValArray,_Tp> _Closure;
    00599       return _Expr<_Closure, bool> (_Closure (*this));
    00600   }
    00601
    00602 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name)               \
    00603   template<class _Tp>                           \
    00604   inline valarray<_Tp> &                        \
    00605   valarray<_Tp>::operator _Op##= (const _Tp &__t)           \
    00606   {                                 \
    00607       _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size, __t);    \
    00608       return *this;                         \
    00609   }                                 \
    00610                                     \
    00611   template<class _Tp>                           \
    00612   inline valarray<_Tp> &                        \
    00613   valarray<_Tp>::operator _Op##= (const valarray<_Tp> &__v)     \
    00614   {                                 \
    00615       _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size,      \
    00616                                _Array<_Tp>(__v._M_data));       \
    00617       return *this;                         \
    00618   }
    00619
    00620 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, plus)
    00621 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, minus)
    00622 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, multiplies)
    00623 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, divides)
    00624 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, modulus)
    00625 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, xor)
    00626 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, and)
    00627 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, or)
    00628 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, shift_left)
    00629 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, shift_right)
    00630
    00631 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
    00632
    00633
    00634 } // std::
    00635
    00636
    00637 namespace std
    00638 {
    00639
    00640 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name)          \
    00641   template<class _Tp> template<class _Dom>              \
    00642   inline valarray<_Tp> &                        \
    00643   valarray<_Tp>::operator _Op##= (const _Expr<_Dom,_Tp> &__e)       \
    00644   {                                 \
    00645       _Array_augmented_##_Name (_Array<_Tp>(_M_data), __e, _M_size);    \
    00646       return *this;                         \
    00647   }
    00648
    00649 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, plus)
    00650 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, minus)
    00651 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, multiplies)
    00652 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, divides)
    00653 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, modulus)
    00654 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, xor)
    00655 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, and)
    00656 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, or)
    00657 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, shift_left)
    00658 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, shift_right)
    00659
    00660 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
    00661
    00662
    00663 #define _DEFINE_BINARY_OPERATOR(_Op, _Name)             \
    00664   template<typename _Tp>                        \
    00665   inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>, _Tp>        \
    00666   operator _Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w) \
    00667   {                                 \
    00668       typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure;     \
    00669       return _Expr<_Closure, _Tp> (_Closure (__v, __w));        \
    00670   }                                 \
    00671                                     \
    00672   template<typename _Tp>                        \
    00673   inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,_Tp>         \
    00674   operator _Op (const valarray<_Tp> &__v, const _Tp &__t)       \
    00675   {                                 \
    00676       typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure; \
    00677       return _Expr<_Closure, _Tp> (_Closure (__v, __t));            \
    00678   }                                 \
    00679                                     \
    00680   template<typename _Tp>                        \
    00681   inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,_Tp>         \
    00682   operator _Op (const _Tp &__t, const valarray<_Tp> &__v)       \
    00683   {                                 \
    00684       typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure;     \
    00685       return _Expr<_Closure, _Tp> (_Closure (__t, __v));            \
    00686   }
    00687
    00688 _DEFINE_BINARY_OPERATOR(+, plus)
    00689 _DEFINE_BINARY_OPERATOR(-, minus)
    00690 _DEFINE_BINARY_OPERATOR(*, multiplies)
    00691 _DEFINE_BINARY_OPERATOR(/, divides)
    00692 _DEFINE_BINARY_OPERATOR(%, modulus)
    00693 _DEFINE_BINARY_OPERATOR(^, _Bitwise_xor)
    00694 _DEFINE_BINARY_OPERATOR(&, _Bitwise_and)
    00695 _DEFINE_BINARY_OPERATOR(|, _Bitwise_or)
    00696 _DEFINE_BINARY_OPERATOR(<<, _Shift_left)
    00697 _DEFINE_BINARY_OPERATOR(>>, _Shift_right)
    00698
    00699 #undef _DEFINE_BINARY_OPERATOR
    00700
    00701 #define _DEFINE_LOGICAL_OPERATOR(_Op, _Name)                \
    00702   template<typename _Tp>                        \
    00703   inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>,bool>        \
    00704   operator _Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w) \
    00705   {                                 \
    00706       typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure;     \
    00707       return _Expr<_Closure, bool> (_Closure (__v, __w));               \
    00708   }                                 \
    00709                                     \
    00710   template<class _Tp>                           \
    00711   inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,bool>        \
    00712   operator _Op (const valarray<_Tp> &__v, const _Tp &__t)       \
    00713   {                                 \
    00714       typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure;     \
    00715       return _Expr<_Closure, bool> (_Closure (__v, __t));           \
    00716   }                                 \
    00717                                     \
    00718   template<class _Tp>                           \
    00719   inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,bool>        \
    00720   operator _Op (const _Tp &__t, const valarray<_Tp> &__v)       \
    00721   {                                 \
    00722       typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure;     \
    00723       return _Expr<_Closure, bool> (_Closure (__t, __v));           \
    00724   }
    00725
    00726 _DEFINE_LOGICAL_OPERATOR(&&, logical_and)
    00727 _DEFINE_LOGICAL_OPERATOR(||, logical_or)
    00728 _DEFINE_LOGICAL_OPERATOR(==, equal_to)
    00729 _DEFINE_LOGICAL_OPERATOR(!=, not_equal_to)
    00730 _DEFINE_LOGICAL_OPERATOR(<, less)
    00731 _DEFINE_LOGICAL_OPERATOR(>, greater)
    00732 _DEFINE_LOGICAL_OPERATOR(<=, less_equal)
    00733 _DEFINE_LOGICAL_OPERATOR(>=, greater_equal)
    00734
    00735 #undef _DEFINE_LOGICAL_OPERATOR
    00736
    00737 } // namespace std
    00738
    00739 #endif // _CPP_VALARRAY
    00740
    00741 // Local Variables:
    00742 // mode:c++
    00743 // End: