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:

Generated on Wed May 1 19:19:39 2002 for libstdc++-v3 Source by doxygen1.2.15