00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
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;   
00084     class slice;                          
00085     template<class _Tp> class slice_array;
00086     class gslice;                         
00087     template<class _Tp> class gslice_array;
00088     template<class _Tp> class mask_array;     
00089     template<class _Tp> class indirect_array; 
00090 
00091 } 
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       
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       
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       
00129       
00130       const _Tp&                 operator[](size_t) const;
00131       _Tp&                operator[](size_t);       
00132       
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       
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       
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       
00194       size_t size() const;
00195       _Tp    sum() const;   
00196       _Tp    min() const;   
00197       _Tp    max() const;   
00198 
00199 
00200 
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 } 
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 
00477 
00478 
00479 
00480 
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)                          
00490          __valarray_copy_construct(_M_data, _M_data + _M_size, __a);
00491        else if (__n > 0)         
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                        
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)               
00516          __valarray_copy_construct(_M_data, _M_data + _M_size, __a);
00517        else if (__n > 0)           
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                        
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     
00537     
00538     
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 } 
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 } 
00738 
00739 #endif // _CPP_VALARRAY
00740 
00741 
00742 
00743