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