# 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 <algorithm>
    00049
    00050 namespace std
    00051 {
    00052   template<class _Clos, typename _Tp>
    00053     class _Expr;
    00054
    00055   template<typename _Tp1, typename _Tp2>
    00056     class _ValArray;
    00057
    00058   template<class _Oper, template<class, class> class _Meta, class _Dom>
    00059     struct _UnClos;
    00060
    00061   template<class _Oper,
    00062         template<class, class> class _Meta1,
    00063         template<class, class> class _Meta2,
    00064         class _Dom1, class _Dom2>
    00065     class _BinClos;
    00066
    00067   template<template<class, class> class _Meta, class _Dom>
    00068     class _SClos;
    00069
    00070   template<template<class, class> class _Meta, class _Dom>
    00071     class _GClos;
    00072
    00073   template<template<class, class> class _Meta, class _Dom>
    00074     class _IClos;
    00075
    00076   template<template<class, class> class _Meta, class _Dom>
    00077     class _ValFunClos;
    00078
    00079   template<template<class, class> class _Meta, class _Dom>
    00080     class _RefFunClos;
    00081
    00082   template<class _Tp> class valarray;   // An array of type _Tp
    00083   class slice;                          // BLAS-like slice out of an array
    00084   template<class _Tp> class slice_array;
    00085   class gslice;                         // generalized slice out of an array
    00086   template<class _Tp> class gslice_array;
    00087   template<class _Tp> class mask_array;     // masked array
    00088   template<class _Tp> class indirect_array; // indirected array
    00089
    00090 } // namespace std
    00091
    00092 #include <bits/valarray_array.h>
    00093 #include <bits/valarray_meta.h>
    00094
    00095 namespace std
    00096 {
    00097   template<class _Tp>
    00098     class valarray
    00099     {
    00100       template<class _Op>
    00101     struct _UnaryOp
    00102     {
    00103       typedef typename __fun<_Op, _Tp>::result_type __rt;
    00104       typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt;
    00105     };
    00106     public:
    00107       typedef _Tp value_type;
    00108
    00109     // _lib.valarray.cons_ construct/destroy:
    00110       valarray();
    00111       explicit valarray(size_t);
    00112       valarray(const _Tp&, size_t);
    00113       valarray(const _Tp* __restrict__, size_t);
    00114       valarray(const valarray&);
    00115       valarray(const slice_array<_Tp>&);
    00116       valarray(const gslice_array<_Tp>&);
    00117       valarray(const mask_array<_Tp>&);
    00118       valarray(const indirect_array<_Tp>&);
    00119       template<class _Dom>
    00120     valarray(const _Expr<_Dom,_Tp>& __e);
    00121       ~valarray();
    00122
    00123       // _lib.valarray.assign_ assignment:
    00124       valarray<_Tp>& operator=(const valarray<_Tp>&);
    00125       valarray<_Tp>& operator=(const _Tp&);
    00126       valarray<_Tp>& operator=(const slice_array<_Tp>&);
    00127       valarray<_Tp>& operator=(const gslice_array<_Tp>&);
    00128       valarray<_Tp>& operator=(const mask_array<_Tp>&);
    00129       valarray<_Tp>& operator=(const indirect_array<_Tp>&);
    00130
    00131       template<class _Dom> valarray<_Tp>&
    00132     operator= (const _Expr<_Dom,_Tp>&);
    00133
    00134       // _lib.valarray.access_ element access:
    00135       // XXX: LWG to be resolved.
    00136       const _Tp&                 operator[](size_t) const;
    00137       _Tp&                operator[](size_t);
    00138       // _lib.valarray.sub_ subset operations:
    00139       _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const;
    00140       slice_array<_Tp>    operator[](slice);
    00141       _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const;
    00142       gslice_array<_Tp>   operator[](const gslice&);
    00143       valarray<_Tp>          operator[](const valarray<bool>&) const;
    00144       mask_array<_Tp>     operator[](const valarray<bool>&);
    00145       _Expr<_IClos<_ValArray, _Tp>, _Tp>
    00146         operator[](const valarray<size_t>&) const;
    00147       indirect_array<_Tp> operator[](const valarray<size_t>&);
    00148
    00149       // _lib.valarray.unary_ unary operators:
    00150       typename _UnaryOp<__unary_plus>::_Rt  operator+() const;
    00151       typename _UnaryOp<__negate>::_Rt      operator-() const;
    00152       typename _UnaryOp<__bitwise_not>::_Rt operator~() const;
    00153       typename _UnaryOp<__logical_not>::_Rt operator!() const;
    00154
    00155       // _lib.valarray.cassign_ computed assignment:
    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 _Tp&);
    00161       valarray<_Tp>& operator^=(const _Tp&);
    00162       valarray<_Tp>& operator&=(const _Tp&);
    00163       valarray<_Tp>& operator|=(const _Tp&);
    00164       valarray<_Tp>& operator<<=(const _Tp&);
    00165       valarray<_Tp>& operator>>=(const _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       valarray<_Tp>& operator-=(const valarray<_Tp>&);
    00171       valarray<_Tp>& operator^=(const valarray<_Tp>&);
    00172       valarray<_Tp>& operator|=(const valarray<_Tp>&);
    00173       valarray<_Tp>& operator&=(const valarray<_Tp>&);
    00174       valarray<_Tp>& operator<<=(const valarray<_Tp>&);
    00175       valarray<_Tp>& operator>>=(const valarray<_Tp>&);
    00176
    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       template<class _Dom>
    00192     valarray<_Tp>& operator&=(const _Expr<_Dom,_Tp>&);
    00193       template<class _Dom>
    00194       valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&);
    00195       template<class _Dom>
    00196     valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&);
    00197
    00198
    00199       // _lib.valarray.members_ member functions:
    00200       size_t size() const;
    00201       _Tp    sum() const;
    00202       _Tp    min() const;
    00203       _Tp    max() const;
    00204
    00205   //           // FIXME: Extension
    00206   //       _Tp    product () const;
    00207
    00208       valarray<_Tp> shift (int) const;
    00209       valarray<_Tp> cshift(int) const;
    00210       _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const;
    00211       _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const;
    00212       void resize(size_t __size, _Tp __c = _Tp());
    00213
    00214     private:
    00215       size_t _M_size;
    00216       _Tp* __restrict__ _M_data;
    00217
    00218       friend class _Array<_Tp>;
    00219     };
    00220
    00221   template<typename _Tp>
    00222     inline const _Tp&
    00223     valarray<_Tp>::operator[](size_t __i) const
    00224     { return _M_data[__i]; }
    00225
    00226   template<typename _Tp>
    00227     inline _Tp&
    00228     valarray<_Tp>::operator[](size_t __i)
    00229     { return _M_data[__i]; }
    00230
    00231 } // std::
    00232
    00233 #include <bits/slice_array.h>
    00234 #include <bits/gslice.h>
    00235 #include <bits/gslice_array.h>
    00236 #include <bits/mask_array.h>
    00237 #include <bits/indirect_array.h>
    00238
    00239 namespace std
    00240 {
    00241   template<typename _Tp>
    00242     inline
    00243     valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {}
    00244
    00245   template<typename _Tp>
    00246     inline
    00247     valarray<_Tp>::valarray(size_t __n)
    00248     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
    00249     { __valarray_default_construct(_M_data, _M_data + __n); }
    00250
    00251   template<typename _Tp>
    00252     inline
    00253     valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
    00254       : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
    00255     { __valarray_fill_construct(_M_data, _M_data + __n, __t); }
    00256
    00257   template<typename _Tp>
    00258     inline
    00259     valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
    00260       : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
    00261     { __valarray_copy_construct(__p, __p + __n, _M_data); }
    00262
    00263   template<typename _Tp>
    00264     inline
    00265     valarray<_Tp>::valarray(const valarray<_Tp>& __v)
    00266       : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
    00267     { __valarray_copy_construct(__v._M_data, __v._M_data + _M_size, _M_data); }
    00268
    00269   template<typename _Tp>
    00270     inline
    00271     valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
    00272       : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
    00273     {
    00274       __valarray_copy
    00275     (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
    00276     }
    00277
    00278   template<typename _Tp>
    00279     inline
    00280     valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
    00281       : _M_size(__ga._M_index.size()),
    00282     _M_data(__valarray_get_storage<_Tp>(_M_size))
    00283     {
    00284       __valarray_copy
    00285     (__ga._M_array, _Array<size_t>(__ga._M_index),
    00286      _Array<_Tp>(_M_data), _M_size);
    00287     }
    00288
    00289   template<typename _Tp>
    00290     inline
    00291     valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
    00292       : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
    00293     {
    00294       __valarray_copy
    00295     (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
    00296     }
    00297
    00298   template<typename _Tp>
    00299     inline
    00300     valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
    00301       : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
    00302     {
    00303       __valarray_copy
    00304     (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
    00305     }
    00306
    00307   template<typename _Tp> template<class _Dom>
    00308     inline
    00309     valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
    00310       : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
    00311     { __valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); }
    00312
    00313   template<typename _Tp>
    00314     inline
    00315     valarray<_Tp>::~valarray()
    00316     {
    00317       __valarray_destroy_elements(_M_data, _M_data + _M_size);
    00318       __valarray_release_memory(_M_data);
    00319     }
    00320
    00321   template<typename _Tp>
    00322     inline valarray<_Tp>&
    00323     valarray<_Tp>::operator=(const valarray<_Tp>& __v)
    00324     {
    00325       __valarray_copy(__v._M_data, _M_size, _M_data);
    00326       return *this;
    00327     }
    00328
    00329   template<typename _Tp>
    00330     inline valarray<_Tp>&
    00331     valarray<_Tp>::operator=(const _Tp& __t)
    00332     {
    00333       __valarray_fill(_M_data, _M_size, __t);
    00334       return *this;
    00335     }
    00336
    00337   template<typename _Tp>
    00338     inline valarray<_Tp>&
    00339     valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
    00340     {
    00341       __valarray_copy(__sa._M_array, __sa._M_sz,
    00342               __sa._M_stride, _Array<_Tp>(_M_data));
    00343       return *this;
    00344     }
    00345
    00346   template<typename _Tp>
    00347     inline valarray<_Tp>&
    00348     valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
    00349     {
    00350       __valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
    00351               _Array<_Tp>(_M_data), _M_size);
    00352       return *this;
    00353     }
    00354
    00355   template<typename _Tp>
    00356     inline valarray<_Tp>&
    00357     valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
    00358     {
    00359       __valarray_copy(__ma._M_array, __ma._M_mask,
    00360               _Array<_Tp>(_M_data), _M_size);
    00361       return *this;
    00362     }
    00363
    00364   template<typename _Tp>
    00365     inline valarray<_Tp>&
    00366     valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
    00367     {
    00368       __valarray_copy(__ia._M_array, __ia._M_index,
    00369                _Array<_Tp>(_M_data), _M_size);
    00370       return *this;
    00371     }
    00372
    00373   template<typename _Tp> template<class _Dom>
    00374     inline valarray<_Tp>&
    00375     valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
    00376     {
    00377       __valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
    00378     return *this;
    00379     }
    00380
    00381   template<typename _Tp>
    00382     inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
    00383     valarray<_Tp>::operator[](slice __s) const
    00384     {
    00385       typedef _SClos<_ValArray,_Tp> _Closure;
    00386       return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
    00387     }
    00388
    00389   template<typename _Tp>
    00390     inline slice_array<_Tp>
    00391     valarray<_Tp>::operator[](slice __s)
    00392     {
    00393       return slice_array<_Tp>(_Array<_Tp>(_M_data), __s);
    00394     }
    00395
    00396   template<typename _Tp>
    00397     inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
    00398     valarray<_Tp>::operator[](const gslice& __gs) const
    00399     {
    00400       typedef _GClos<_ValArray,_Tp> _Closure;
    00401       return _Expr<_Closure, _Tp>
    00402     (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
    00403     }
    00404
    00405   template<typename _Tp>
    00406     inline gslice_array<_Tp>
    00407     valarray<_Tp>::operator[](const gslice& __gs)
    00408     {
    00409       return gslice_array<_Tp>
    00410     (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
    00411     }
    00412
    00413   template<typename _Tp>
    00414     inline valarray<_Tp>
    00415     valarray<_Tp>::operator[](const valarray<bool>& __m) const
    00416     {
    00417       size_t __s = 0;
    00418       size_t __e = __m.size();
    00419       for (size_t __i=0; __i<__e; ++__i)
    00420     if (__m[__i]) ++__s;
    00421       return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
    00422                        _Array<bool> (__m)));
    00423     }
    00424
    00425   template<typename _Tp>
    00426     inline mask_array<_Tp>
    00427     valarray<_Tp>::operator[](const valarray<bool>& __m)
    00428     {
    00429       size_t __s = 0;
    00430       size_t __e = __m.size();
    00431       for (size_t __i=0; __i<__e; ++__i)
    00432     if (__m[__i]) ++__s;
    00433       return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
    00434     }
    00435
    00436   template<typename _Tp>
    00437     inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
    00438     valarray<_Tp>::operator[](const valarray<size_t>& __i) const
    00439     {
    00440       typedef _IClos<_ValArray,_Tp> _Closure;
    00441       return _Expr<_Closure, _Tp>(_Closure(*this, __i));
    00442     }
    00443
    00444   template<typename _Tp>
    00445     inline indirect_array<_Tp>
    00446     valarray<_Tp>::operator[](const valarray<size_t>& __i)
    00447     {
    00448       return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
    00449                  _Array<size_t>(__i));
    00450     }
    00451
    00452   template<class _Tp>
    00453     inline size_t
    00454     valarray<_Tp>::size() const
    00455     { return _M_size; }
    00456
    00457   template<class _Tp>
    00458     inline _Tp
    00459     valarray<_Tp>::sum() const
    00460     {
    00461       return __valarray_sum(_M_data, _M_data + _M_size);
    00462     }
    00463
    00464 //   template<typename _Tp>
    00465 //   inline _Tp
    00466 //   valarray<_Tp>::product () const
    00467 //   {
    00468 //       return __valarray_product(_M_data, _M_data + _M_size);
    00469 //   }
    00470
    00471   template <class _Tp>
    00472      inline valarray<_Tp>
    00473      valarray<_Tp>::shift(int __n) const
    00474      {
    00475        _Tp* const __a = static_cast<_Tp*>
    00476          (__builtin_alloca(sizeof(_Tp) * _M_size));
    00477        if (__n == 0)                          // no shift
    00478          __valarray_copy_construct(_M_data, _M_data + _M_size, __a);
    00479        else if (__n > 0)         // __n > 0: shift left
    00480          {
    00481            if (size_t(__n) > _M_size)
    00482              __valarray_default_construct(__a, __a + __n);
    00483            else
    00484              {
    00485                __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
    00486                __valarray_default_construct(__a+_M_size-__n, __a + _M_size);
    00487              }
    00488          }
    00489        else                        // __n < 0: shift right
    00490          {
    00491            __valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n);
    00492            __valarray_default_construct(__a, __a - __n);
    00493          }
    00494        return valarray<_Tp> (__a, _M_size);
    00495      }
    00496
    00497   template <class _Tp>
    00498      inline valarray<_Tp>
    00499      valarray<_Tp>::cshift (int __n) const
    00500      {
    00501        _Tp* const __a = static_cast<_Tp*>
    00502          (__builtin_alloca (sizeof(_Tp) * _M_size));
    00503        if (__n == 0)               // no cshift
    00504          __valarray_copy_construct(_M_data, _M_data + _M_size, __a);
    00505        else if (__n > 0)           // cshift left
    00506          {
    00507            __valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n);
    00508            __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
    00509          }
    00510        else                        // cshift right
    00511          {
    00512            __valarray_copy_construct
    00513              (_M_data + _M_size+__n, _M_data + _M_size, __a);
    00514            __valarray_copy_construct
    00515              (_M_data, _M_data + _M_size+__n, __a - __n);
    00516          }
    00517        return valarray<_Tp>(__a, _M_size);
    00518      }
    00519
    00520   template <class _Tp>
    00521     inline void
    00522     valarray<_Tp>::resize (size_t __n, _Tp __c)
    00523     {
    00524       // This complication is so to make valarray<valarray<T> > work
    00525       // even though it is not required by the standard.  Nobody should
    00526       // be saying valarray<valarray<T> > anyway.  See the specs.
    00527       __valarray_destroy_elements(_M_data, _M_data + _M_size);
    00528       if (_M_size != __n)
    00529     {
    00530       __valarray_release_memory(_M_data);
    00531       _M_size = __n;
    00532       _M_data = __valarray_get_storage<_Tp>(__n);
    00533     }
    00534       __valarray_fill_construct(_M_data, _M_data + __n, __c);
    00535     }
    00536
    00537   template<typename _Tp>
    00538     inline _Tp
    00539     valarray<_Tp>::min() const
    00540     {
    00541       return *min_element (_M_data, _M_data+_M_size);
    00542     }
    00543
    00544   template<typename _Tp>
    00545     inline _Tp
    00546     valarray<_Tp>::max() const
    00547     {
    00548       return *max_element (_M_data, _M_data+_M_size);
    00549     }
    00550
    00551   template<class _Tp>
    00552     inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp>
    00553     valarray<_Tp>::apply(_Tp func(_Tp)) const
    00554     {
    00555       typedef _ValFunClos<_ValArray,_Tp> _Closure;
    00556       return _Expr<_Closure,_Tp>(_Closure(*this, func));
    00557     }
    00558
    00559   template<class _Tp>
    00560     inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp>
    00561     valarray<_Tp>::apply(_Tp func(const _Tp &)) const
    00562     {
    00563       typedef _RefFunClos<_ValArray,_Tp> _Closure;
    00564       return _Expr<_Closure,_Tp>(_Closure(*this, func));
    00565     }
    00566
    00567 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name)                     \
    00568   template<typename _Tp>                        \
    00569   inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt          \
    00570   valarray<_Tp>::operator _Op() const                   \
    00571   {                                 \
    00572     typedef _UnClos<_Name,_ValArray,_Tp> _Closure;                  \
    00573     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
    00574     return _Expr<_Closure, _Rt>(_Closure(*this));           \
    00575   }
    00576
    00577     _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
    00578     _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
    00579     _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
    00580     _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
    00581
    00582 #undef _DEFINE_VALARRAY_UNARY_OPERATOR
    00583
    00584 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name)               \
    00585   template<class _Tp>                           \
    00586     inline valarray<_Tp>&                       \
    00587     valarray<_Tp>::operator _Op##=(const _Tp &__t)          \
    00588     {                                   \
    00589       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \
    00590       return *this;                         \
    00591     }                                   \
    00592                                     \
    00593   template<class _Tp>                           \
    00594     inline valarray<_Tp>&                       \
    00595     valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v)        \
    00596     {                                   \
    00597       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size,       \
    00598                    _Array<_Tp>(__v._M_data));       \
    00599       return *this;                         \
    00600     }
    00601
    00602 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
    00603 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
    00604 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
    00605 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
    00606 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
    00607 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
    00608 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
    00609 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
    00610 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
    00611 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
    00612
    00613 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
    00614
    00615 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name)          \
    00616   template<class _Tp> template<class _Dom>              \
    00617     inline valarray<_Tp>&                       \
    00618     valarray<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e)      \
    00619     {                                   \
    00620       _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \
    00621       return *this;                         \
    00622     }
    00623
    00624 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
    00625 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
    00626 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
    00627 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
    00628 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
    00629 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
    00630 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
    00631 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
    00632 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
    00633 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
    00634
    00635 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
    00636
    00637
    00638 #define _DEFINE_BINARY_OPERATOR(_Op, _Name)             \
    00639   template<typename _Tp>                        \
    00640     inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>,           \
    00641                  typename __fun<_Name, _Tp>::result_type>               \
    00642     operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w)    \
    00643     {                                   \
    00644       typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure;     \
    00645       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
    00646       return _Expr<_Closure, _Rt>(_Closure(__v, __w));                  \
    00647     }                                   \
    00648                                     \
    00649   template<typename _Tp>                        \
    00650   inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,             \
    00651                typename __fun<_Name, _Tp>::result_type>                 \
    00652   operator _Op(const valarray<_Tp>& __v, const _Tp& __t)        \
    00653   {                                 \
    00654     typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure;   \
    00655     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
    00656     return _Expr<_Closure, _Rt>(_Closure(__v, __t));                    \
    00657   }                                 \
    00658                                     \
    00659   template<typename _Tp>                        \
    00660   inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,             \
    00661                typename __fun<_Name, _Tp>::result_type>                 \
    00662   operator _Op(const _Tp& __t, const valarray<_Tp>& __v)        \
    00663   {                                 \
    00664     typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure;       \
    00665     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
    00666     return _Expr<_Closure, _Tp>(_Closure(__t, __v));                    \
    00667   }
    00668
    00669 _DEFINE_BINARY_OPERATOR(+, __plus)
    00670 _DEFINE_BINARY_OPERATOR(-, __minus)
    00671 _DEFINE_BINARY_OPERATOR(*, __multiplies)
    00672 _DEFINE_BINARY_OPERATOR(/, __divides)
    00673 _DEFINE_BINARY_OPERATOR(%, __modulus)
    00674 _DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
    00675 _DEFINE_BINARY_OPERATOR(&, __bitwise_and)
    00676 _DEFINE_BINARY_OPERATOR(|, __bitwise_or)
    00677 _DEFINE_BINARY_OPERATOR(<<, __shift_left)
    00678 _DEFINE_BINARY_OPERATOR(>>, __shift_right)
    00679 _DEFINE_BINARY_OPERATOR(&&, __logical_and)
    00680 _DEFINE_BINARY_OPERATOR(||, __logical_or)
    00681 _DEFINE_BINARY_OPERATOR(==, __equal_to)
    00682 _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
    00683 _DEFINE_BINARY_OPERATOR(<, __less)
    00684 _DEFINE_BINARY_OPERATOR(>, __greater)
    00685 _DEFINE_BINARY_OPERATOR(<=, __less_equal)
    00686 _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
    00687
    00688 } // namespace std
    00689
    00690 #endif // _CPP_VALARRAY
    00691
    00692 // Local Variables:
    00693 // mode:c++
    00694 // End: