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