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 _VALARRAY_AFTER_H
00039 #define _VALARRAY_AFTER_H 1
00040 
00041 #pragma GCC system_header
00042 
00043 namespace std
00044 {
00045   
00046   
00047   
00048   template<class _Dom>
00049     class _GBase
00050     {
00051     public:
00052       typedef typename _Dom::value_type value_type;
00053       
00054       _GBase (const _Dom& __e, const valarray<size_t>& __i)
00055       : _M_expr (__e), _M_index(__i) {}
00056       
00057       value_type
00058       operator[] (size_t __i) const
00059       { return _M_expr[_M_index[__i]]; }
00060       
00061       size_t
00062       size () const
00063       { return _M_index.size(); }
00064 
00065     private:
00066       const _Dom&         _M_expr;
00067       const valarray<size_t>& _M_index;
00068     };
00069 
00070   template<typename _Tp>
00071     class _GBase<_Array<_Tp> >
00072     {
00073     public:
00074       typedef _Tp value_type;
00075       
00076       _GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
00077       : _M_array (__a), _M_index(__i) {}
00078       
00079       value_type
00080       operator[] (size_t __i) const
00081       { return _M_array._M_data[_M_index[__i]]; }
00082       
00083       size_t
00084       size () const
00085       { return _M_index.size(); }
00086 
00087     private:
00088       const _Array<_Tp>       _M_array;
00089       const valarray<size_t>& _M_index;
00090     };
00091 
00092   template<class _Dom>
00093     struct _GClos<_Expr, _Dom>
00094     : _GBase<_Dom>
00095     {
00096       typedef _GBase<_Dom> _Base;
00097       typedef typename _Base::value_type value_type;
00098       
00099       _GClos (const _Dom& __e, const valarray<size_t>& __i)
00100       : _Base (__e, __i) {}
00101     };
00102 
00103   template<typename _Tp>
00104     struct _GClos<_ValArray, _Tp>
00105     : _GBase<_Array<_Tp> >
00106     {
00107       typedef _GBase<_Array<_Tp> > _Base;
00108       typedef typename _Base::value_type value_type;
00109       
00110       _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
00111       : _Base (__a, __i) {}
00112     };
00113 
00114   
00115   
00116   
00117   template<class _Dom>
00118     class _IBase
00119     {
00120     public:
00121       typedef typename _Dom::value_type value_type;
00122 
00123       _IBase (const _Dom& __e, const valarray<size_t>& __i)
00124       : _M_expr (__e), _M_index (__i) {}
00125       
00126       value_type
00127       operator[] (size_t __i) const
00128       { return _M_expr[_M_index[__i]]; }
00129       
00130       size_t
00131       size() const
00132       { return _M_index.size(); }
00133 
00134     private:
00135       const _Dom&         _M_expr;
00136       const valarray<size_t>& _M_index;
00137     };
00138 
00139   template<class _Dom>
00140     struct _IClos<_Expr, _Dom>
00141     : _IBase<_Dom>
00142     {
00143       typedef _IBase<_Dom> _Base;
00144       typedef typename _Base::value_type value_type;
00145       
00146       _IClos (const _Dom& __e, const valarray<size_t>& __i)
00147       : _Base (__e, __i) {}
00148     };
00149 
00150   template<typename _Tp>
00151     struct _IClos<_ValArray, _Tp>
00152     : _IBase<valarray<_Tp> >
00153     {
00154       typedef _IBase<valarray<_Tp> > _Base;
00155       typedef _Tp value_type;
00156       
00157       _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
00158       : _Base (__a, __i) {}
00159     };
00160   
00161   
00162   
00163   
00164   template<class _Clos, typename _Tp>
00165     class _Expr
00166     {
00167     public:
00168       typedef _Tp value_type;
00169 
00170       _Expr(const _Clos&);
00171 
00172       const _Clos& operator()() const;
00173 
00174       value_type operator[](size_t) const;
00175       valarray<value_type> operator[](slice) const;
00176       valarray<value_type> operator[](const gslice&) const;
00177       valarray<value_type> operator[](const valarray<bool>&) const;
00178       valarray<value_type> operator[](const valarray<size_t>&) const;
00179 
00180       _Expr<_UnClos<__unary_plus, std::_Expr, _Clos>, value_type>
00181       operator+() const;
00182 
00183       _Expr<_UnClos<__negate, std::_Expr, _Clos>, value_type>
00184       operator-() const;
00185 
00186       _Expr<_UnClos<__bitwise_not, std::_Expr, _Clos>, value_type>
00187       operator~() const;
00188 
00189       _Expr<_UnClos<__logical_not, std::_Expr, _Clos>, bool>
00190       operator!() const;
00191 
00192       size_t size() const;
00193       value_type sum() const;
00194 
00195       valarray<value_type> shift(int) const;
00196       valarray<value_type> cshift(int) const;
00197 
00198       value_type min() const;
00199       value_type max() const;
00200 
00201       valarray<value_type> apply(value_type (*)(const value_type&)) const;
00202       valarray<value_type> apply(value_type (*)(value_type)) const;
00203 
00204     private:
00205       const _Clos _M_closure;
00206     };
00207 
00208   template<class _Clos, typename _Tp>
00209     inline
00210     _Expr<_Clos, _Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {}
00211 
00212   template<class _Clos, typename _Tp>
00213     inline const _Clos&
00214     _Expr<_Clos, _Tp>::operator()() const
00215     { return _M_closure; }
00216 
00217   template<class _Clos, typename _Tp>
00218     inline _Tp
00219     _Expr<_Clos, _Tp>::operator[](size_t __i) const
00220     { return _M_closure[__i]; }
00221 
00222   template<class _Clos, typename _Tp>
00223     inline valarray<_Tp>
00224     _Expr<_Clos, _Tp>::operator[](slice __s) const
00225     {
00226       valarray<_Tp> __v = valarray<_Tp>(*this)[__s];
00227       return __v;
00228     }
00229 
00230   template<class _Clos, typename _Tp>
00231     inline valarray<_Tp>
00232     _Expr<_Clos, _Tp>::operator[](const gslice& __gs) const
00233     {
00234       valarray<_Tp> __v = valarray<_Tp>(*this)[__gs];
00235       return __v;
00236     }
00237 
00238   template<class _Clos, typename _Tp>
00239     inline valarray<_Tp>
00240     _Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const
00241     {
00242       valarray<_Tp> __v = valarray<_Tp>(*this)[__m];
00243       return __v;
00244     }
00245 
00246   template<class _Clos, typename _Tp>
00247     inline valarray<_Tp>
00248     _Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const
00249     {
00250       valarray<_Tp> __v = valarray<_Tp>(*this)[__i];
00251       return __v;
00252     }
00253 
00254   template<class _Clos, typename _Tp>
00255     inline size_t
00256     _Expr<_Clos, _Tp>::size() const
00257     { return _M_closure.size(); }
00258 
00259   template<class _Clos, typename _Tp>
00260     inline valarray<_Tp>
00261     _Expr<_Clos, _Tp>::shift(int __n) const
00262     {
00263       valarray<_Tp> __v = valarray<_Tp>(*this).shift(__n);
00264       return __v;
00265     }
00266 
00267   template<class _Clos, typename _Tp>
00268     inline valarray<_Tp>
00269     _Expr<_Clos, _Tp>::cshift(int __n) const
00270     {
00271       valarray<_Tp> __v = valarray<_Tp>(*this).cshift(__n);
00272       return __v;
00273     }
00274 
00275   template<class _Clos, typename _Tp>
00276     inline valarray<_Tp>
00277     _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
00278     {
00279       valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
00280       return __v;
00281     }
00282 
00283   template<class _Clos, typename _Tp>
00284     inline valarray<_Tp>
00285     _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
00286     {
00287       valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
00288       return __v;
00289     }
00290 
00291   
00292   template<class _Clos, typename _Tp>
00293     inline _Tp
00294     _Expr<_Clos, _Tp>::sum() const
00295     {
00296       size_t __n = _M_closure.size();
00297       if (__n == 0)
00298     return _Tp();
00299       else
00300     {
00301       _Tp __s = _M_closure[--__n];
00302       while (__n != 0)
00303         __s += _M_closure[--__n];
00304       return __s;
00305         }
00306     }
00307 
00308   template<class _Clos, typename _Tp>
00309     inline _Tp
00310     _Expr<_Clos, _Tp>::min() const
00311     { return __valarray_min(_M_closure); }
00312 
00313   template<class _Clos, typename _Tp>
00314     inline _Tp
00315     _Expr<_Clos, _Tp>::max() const
00316     { return __valarray_max(_M_closure); }
00317 
00318   template<class _Dom, typename _Tp>
00319     inline _Expr<_UnClos<__logical_not, _Expr, _Dom>, bool>
00320     _Expr<_Dom, _Tp>::operator!() const
00321     {
00322       typedef _UnClos<__logical_not, std::_Expr, _Dom> _Closure;
00323       return _Expr<_Closure, _Tp>(_Closure(this->_M_closure));
00324     }
00325 
00326 #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name)                           \
00327   template<class _Dom, typename _Tp>                                      \
00328     inline _Expr<_UnClos<_Name, std::_Expr, _Dom>, _Tp>                   \
00329     _Expr<_Dom, _Tp>::operator _Op() const                                \
00330     {                                                                     \
00331       typedef _UnClos<_Name, std::_Expr, _Dom> _Closure;                  \
00332       return _Expr<_Closure, _Tp>(_Closure(this->_M_closure));            \
00333     }
00334 
00335     _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus)
00336     _DEFINE_EXPR_UNARY_OPERATOR(-, __negate)
00337     _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not)
00338 
00339 #undef _DEFINE_EXPR_UNARY_OPERATOR
00340 
00341 #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name)                        \
00342   template<class _Dom1, class _Dom2>                    \
00343     inline _Expr<_BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2>,           \
00344            typename __fun<_Name, typename _Dom1::value_type>::result_type> \
00345     operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v,   \
00346              const _Expr<_Dom2, typename _Dom2::value_type>& __w)   \
00347     {                                                                   \
00348       typedef typename _Dom1::value_type _Arg;                          \
00349       typedef typename __fun<_Name, _Arg>::result_type _Value;          \
00350       typedef _BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2> _Closure;     \
00351       return _Expr<_Closure, _Value>(_Closure(__v(), __w()));           \
00352     }                                                                   \
00353                                                                         \
00354   template<class _Dom>                                                  \
00355     inline _Expr<_BinClos<_Name, _Expr, _Constant, _Dom,                \
00356                           typename _Dom::value_type>,                   \
00357              typename __fun<_Name, typename _Dom::value_type>::result_type> \
00358     operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v,     \
00359                  const typename _Dom::value_type& __t)                  \
00360     {                                                                   \
00361       typedef typename _Dom::value_type _Arg;                           \
00362       typedef typename __fun<_Name, _Arg>::result_type _Value;          \
00363       typedef _BinClos<_Name, _Expr, _Constant, _Dom, _Arg> _Closure;   \
00364       return _Expr<_Closure, _Value>(_Closure(__v(), __t));             \
00365     }                                                                   \
00366                                                                         \
00367   template<class _Dom>                                                  \
00368     inline _Expr<_BinClos<_Name, _Constant, _Expr,                      \
00369                           typename _Dom::value_type, _Dom>,             \
00370              typename __fun<_Name, typename _Dom::value_type>::result_type> \
00371     operator _Op(const typename _Dom::value_type& __t,                  \
00372                  const _Expr<_Dom, typename _Dom::value_type>& __v)     \
00373     {                                                                   \
00374       typedef typename _Dom::value_type _Arg;                           \
00375       typedef typename __fun<_Name, _Arg>::result_type _Value;          \
00376       typedef _BinClos<_Name, _Constant, _Expr, _Arg, _Dom> _Closure;   \
00377       return _Expr<_Closure, _Value>(_Closure(__t, __v()));             \
00378     }                                                                   \
00379                                                                         \
00380   template<class _Dom>                                                  \
00381     inline _Expr<_BinClos<_Name, _Expr, _ValArray,                      \
00382                           _Dom, typename _Dom::value_type>,             \
00383              typename __fun<_Name, typename _Dom::value_type>::result_type> \
00384     operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e,      \
00385                  const valarray<typename _Dom::value_type>& __v)        \
00386     {                                                                   \
00387       typedef typename _Dom::value_type _Arg;                           \
00388       typedef typename __fun<_Name, _Arg>::result_type _Value;          \
00389       typedef _BinClos<_Name, _Expr, _ValArray, _Dom, _Arg> _Closure;   \
00390       return _Expr<_Closure, _Value>(_Closure(__e(), __v));             \
00391     }                                                                   \
00392                                                                         \
00393   template<class _Dom>                                                  \
00394     inline _Expr<_BinClos<_Name, _ValArray, _Expr,                      \
00395                  typename _Dom::value_type, _Dom>,                      \
00396              typename __fun<_Name, typename _Dom::value_type>::result_type> \
00397     operator _Op(const valarray<typename _Dom::value_type>& __v,        \
00398                  const _Expr<_Dom, typename _Dom::value_type>& __e)     \
00399     {                                                                   \
00400       typedef typename _Dom::value_type _Tp;                            \
00401       typedef typename __fun<_Name, _Tp>::result_type _Value;           \
00402       typedef _BinClos<_Name, _ValArray, _Expr, _Tp, _Dom> _Closure;    \
00403       return _Expr<_Closure, _Value>(_Closure(__v, __e ()));            \
00404     }
00405 
00406     _DEFINE_EXPR_BINARY_OPERATOR(+, __plus)
00407     _DEFINE_EXPR_BINARY_OPERATOR(-, __minus)
00408     _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies)
00409     _DEFINE_EXPR_BINARY_OPERATOR(/, __divides)
00410     _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus)
00411     _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor)
00412     _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and)
00413     _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or)
00414     _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)
00415     _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right)
00416     _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and)
00417     _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or)
00418     _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to)
00419     _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to)
00420     _DEFINE_EXPR_BINARY_OPERATOR(<, __less)
00421     _DEFINE_EXPR_BINARY_OPERATOR(>, __greater)
00422     _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal)
00423     _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal)
00424 
00425 #undef _DEFINE_EXPR_BINARY_OPERATOR
00426 
00427 #define _DEFINE_EXPR_UNARY_FUNCTION(_Name)                               \
00428   template<class _Dom>                                                   \
00429     inline _Expr<_UnClos<__##_Name, _Expr, _Dom>,                        \
00430                  typename _Dom::value_type>                              \
00431     _Name(const _Expr<_Dom, typename _Dom::value_type>& __e)             \
00432     {                                                                    \
00433       typedef typename _Dom::value_type _Tp;                             \
00434       typedef _UnClos<__##_Name, _Expr, _Dom> _Closure;                  \
00435       return _Expr<_Closure, _Tp>(_Closure(__e()));                      \
00436     }                                                                    \
00437                                                                          \
00438   template<typename _Tp>                                                 \
00439     inline _Expr<_UnClos<__##_Name, _ValArray, _Tp>, _Tp>                \
00440     _Name(const valarray<_Tp>& __v)                                      \
00441     {                                                                    \
00442       typedef _UnClos<__##_Name, _ValArray, _Tp> _Closure;               \
00443       return _Expr<_Closure, _Tp>(_Closure(__v));                        \
00444     }
00445 
00446     _DEFINE_EXPR_UNARY_FUNCTION(abs)
00447     _DEFINE_EXPR_UNARY_FUNCTION(cos)
00448     _DEFINE_EXPR_UNARY_FUNCTION(acos)
00449     _DEFINE_EXPR_UNARY_FUNCTION(cosh)
00450     _DEFINE_EXPR_UNARY_FUNCTION(sin)
00451     _DEFINE_EXPR_UNARY_FUNCTION(asin)
00452     _DEFINE_EXPR_UNARY_FUNCTION(sinh)
00453     _DEFINE_EXPR_UNARY_FUNCTION(tan)
00454     _DEFINE_EXPR_UNARY_FUNCTION(tanh)
00455     _DEFINE_EXPR_UNARY_FUNCTION(atan)
00456     _DEFINE_EXPR_UNARY_FUNCTION(exp)
00457     _DEFINE_EXPR_UNARY_FUNCTION(log)
00458     _DEFINE_EXPR_UNARY_FUNCTION(log10)
00459     _DEFINE_EXPR_UNARY_FUNCTION(sqrt)
00460 
00461 #undef _DEFINE_EXPR_UNARY_FUNCTION
00462 
00463 #define _DEFINE_EXPR_BINARY_FUNCTION(_Fun)                             \
00464   template<class _Dom1, class _Dom2>                                   \
00465     inline _Expr<_BinClos<__##_Fun, _Expr, _Expr, _Dom1, _Dom2>,       \
00466          typename _Dom1::value_type>                           \
00467     _Fun(const _Expr<_Dom1, typename _Dom1::value_type>& __e1,         \
00468       const _Expr<_Dom2, typename _Dom2::value_type>& __e2)        \
00469     {                                                                  \
00470       typedef typename _Dom1::value_type _Tp;                          \
00471       typedef _BinClos<__##_Fun, _Expr, _Expr, _Dom1, _Dom2> _Closure; \
00472       return _Expr<_Closure, _Tp>(_Closure(__e1(), __e2()));           \
00473     }                                                                  \
00474                                                                        \
00475   template<class _Dom>                                                 \
00476     inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom,            \
00477               typename _Dom::value_type>,                  \
00478          typename _Dom::value_type>                            \
00479     _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e,            \
00480      const valarray<typename _Dom::value_type>& __v)               \
00481     {                                                                  \
00482       typedef typename _Dom::value_type _Tp;                           \
00483       typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure; \
00484       return _Expr<_Closure, _Tp>(_Closure(__e(), __v));               \
00485     }                                                                  \
00486                                                                        \
00487   template<class _Dom>                                                 \
00488     inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr,                  \
00489               typename _Dom::value_type, _Dom>,            \
00490          typename _Dom::value_type>                            \
00491     _Fun(const valarray<typename _Dom::valarray>& __v,                 \
00492      const _Expr<_Dom, typename _Dom::value_type>& __e)            \
00493     {                                                                  \
00494       typedef typename _Dom::value_type _Tp;                           \
00495       typedef _BinClos<__##_Fun, _ValArray, _Expr, _Tp, _Dom> _Closure; \
00496       return _Expr<_Closure, _Tp>(_Closure(__v, __e()));               \
00497     }                                                                  \
00498                                                                        \
00499   template<class _Dom>                                                 \
00500     inline _Expr<_BinClos<__##_Fun, _Expr, _Constant, _Dom,            \
00501               typename _Dom::value_type>,                  \
00502          typename _Dom::value_type>                            \
00503     _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e,            \
00504      const typename _Dom::value_type& __t)                         \
00505     {                                                                  \
00506       typedef typename _Dom::value_type _Tp;                           \
00507       typedef _BinClos<__##_Fun, _Expr, _Constant, _Dom, _Tp> _Closure;\
00508       return _Expr<_Closure, _Tp>(_Closure(__e(), __t));               \
00509     }                                                                  \
00510                                                                        \
00511   template<class _Dom>                                                 \
00512     inline _Expr<_BinClos<__##_Fun, _Constant, _Expr,                  \
00513               typename _Dom::value_type, _Dom>,            \
00514          typename _Dom::value_type>                            \
00515     _Fun(const typename _Dom::value_type& __t,                         \
00516      const _Expr<_Dom, typename _Dom::value_type>& __e)            \
00517     {                                                                  \
00518       typedef typename _Dom::value_type _Tp;                           \
00519       typedef _BinClos<__##_Fun, _Constant, _Expr, _Tp, _Dom> _Closure; \
00520       return _Expr<_Closure, _Tp>(_Closure(__t, __e()));               \
00521     }                                                                  \
00522                                                                        \
00523   template<typename _Tp>                                               \
00524     inline _Expr<_BinClos<__##_Fun, _ValArray, _ValArray, _Tp, _Tp>, _Tp> \
00525     _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w)           \
00526     {                                                                  \
00527       typedef _BinClos<__##_Fun, _ValArray, _ValArray, _Tp, _Tp> _Closure; \
00528       return _Expr<_Closure, _Tp>(_Closure(__v, __w));                 \
00529     }                                                                  \
00530                                                                        \
00531   template<typename _Tp>                                               \
00532     inline _Expr<_BinClos<__##_Fun, _ValArray, _Constant, _Tp, _Tp>, _Tp> \
00533     _Fun(const valarray<_Tp>& __v, const _Tp& __t)                     \
00534     {                                                                  \
00535       typedef _BinClos<__##_Fun, _ValArray, _Constant, _Tp, _Tp> _Closure; \
00536       return _Expr<_Closure, _Tp>(_Closure(__v, __t));                 \
00537     }                                                                  \
00538                                        \
00539   template<typename _Tp>                                               \
00540     inline _Expr<_BinClos<__##_Fun, _Constant, _ValArray, _Tp, _Tp>, _Tp> \
00541     _Fun(const _Tp& __t, const valarray<_Tp>& __v)                     \
00542     {                                                                  \
00543       typedef _BinClos<__##_Fun, _Constant, _ValArray, _Tp, _Tp> _Closure; \
00544       return _Expr<_Closure, _Tp>(_Closure(__t, __v));                 \
00545     }
00546 
00547 _DEFINE_EXPR_BINARY_FUNCTION(atan2)
00548 _DEFINE_EXPR_BINARY_FUNCTION(pow)
00549 
00550 #undef _DEFINE_EXPR_BINARY_FUNCTION
00551 
00552 } 
00553 
00554 #endif 
00555 
00556 
00557 
00558