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 #ifndef _CPP_VALARRAY_META_H
00033 #define _CPP_VALARRAY_META_H 1
00034
00035 #pragma GCC system_header
00036
00037 namespace std
00038 {
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 template<typename _Tp1, typename _Tp2> class _Constant;
00052
00053
00054
00055
00056 template<class _Dom> class _UnFunBase {
00057 public:
00058 typedef typename _Dom::value_type value_type;
00059 typedef value_type _Vt;
00060
00061 _UnFunBase (const _Dom& __e, _Vt __f(_Vt))
00062 : _M_expr(__e), _M_func(__f) {}
00063
00064 _Vt operator[] (size_t __i) const { return _M_func(_M_expr[__i]); }
00065 size_t size () const { return _M_expr.size(); }
00066
00067 private:
00068 const _Dom& _M_expr;
00069 _Vt (*_M_func)(_Vt);
00070 };
00071
00072 template<template<class, class> class _Meta, class _Dom>
00073 class _UnFunClos;
00074
00075 template<class _Dom>
00076 struct _UnFunClos<_Expr,_Dom> : _UnFunBase<_Dom> {
00077 typedef _UnFunBase<_Dom> _Base;
00078 typedef typename _Base::value_type value_type;
00079
00080 _UnFunClos (const _Dom& __e, value_type __f(value_type))
00081 : _Base (__e, __f) {}
00082 };
00083
00084 template<typename _Tp>
00085 struct _UnFunClos<_ValArray,_Tp> : _UnFunBase<valarray<_Tp> > {
00086 typedef _UnFunBase<valarray<_Tp> > _Base;
00087 typedef typename _Base::value_type value_type;
00088
00089 _UnFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
00090 : _Base (__v, __f) {}
00091 };
00092
00093
00094
00095
00096 template<template<class, class> class _Meta1,
00097 template<class, class> class Meta2,
00098 class _Dom1, class _Dom2> class _BinFunClos;
00099
00100 template<class _Dom1, class _Dom2> class _BinFunBase {
00101 public:
00102 typedef typename _Dom1::value_type value_type;
00103 typedef value_type _Vt;
00104
00105 _BinFunBase (const _Dom1& __e1, const _Dom2& __e2,
00106 _Vt __f (_Vt, _Vt))
00107 : _M_expr1 (__e1), _M_expr2 (__e2), _M_func (__f) {}
00108
00109 value_type operator[] (size_t __i) const
00110 { return _M_func (_M_expr1[__i], _M_expr2[__i]); }
00111 size_t size () const { return _M_expr1.size (); }
00112
00113 private:
00114 const _Dom1& _M_expr1;
00115 const _Dom2& _M_expr2;
00116 _Vt (*_M_func)(_Vt, _Vt);
00117 };
00118
00119 template<class _Dom> class _BinFunBase1 {
00120 public:
00121 typedef typename _Dom::value_type value_type ;
00122 typedef value_type _Vt;
00123
00124 _BinFunBase1 (const _Vt& __c, const _Dom& __e, _Vt __f(_Vt, _Vt))
00125 : _M_expr1 (__c), _M_expr2 (__e), _M_func (__f) {}
00126
00127 value_type operator[] (size_t __i) const
00128 { return _M_func (_M_expr1, _M_expr2[__i]); }
00129 size_t size () const { return _M_expr2.size (); }
00130
00131 private:
00132 const _Vt& _M_expr1;
00133 const _Dom& _M_expr2;
00134 _Vt (*_M_func)(_Vt, _Vt);
00135 };
00136
00137 template<class _Dom> class _BinFunBase2 {
00138 public:
00139 typedef typename _Dom::value_type value_type;
00140 typedef value_type _Vt;
00141
00142 _BinFunBase2 (const _Dom& __e, const _Vt& __c, _Vt __f(_Vt, _Vt))
00143 : _M_expr1 (__e), _M_expr2 (__c), _M_func (__f) {}
00144
00145 value_type operator[] (size_t __i) const
00146 { return _M_func (_M_expr1[__i], _M_expr2); }
00147 size_t size () const { return _M_expr1.size (); }
00148
00149 private:
00150 const _Dom& _M_expr1;
00151 const _Vt& _M_expr2;
00152 _Vt (*_M_func)(_Vt, _Vt);
00153 };
00154
00155 template<class _Dom1, class _Dom2>
00156 struct _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> : _BinFunBase<_Dom1,_Dom2> {
00157 typedef _BinFunBase<_Dom1,_Dom2> _Base;
00158 typedef typename _Base::value_type value_type;
00159 typedef value_type _Tp;
00160
00161 _BinFunClos (const _Dom1& __e1, const _Dom2& __e2,
00162 _Tp __f(_Tp, _Tp))
00163 : _Base (__e1, __e2, __f) {}
00164 };
00165
00166 template<typename _Tp>
00167 struct _BinFunClos<_ValArray,_ValArray,_Tp,_Tp>
00168 : _BinFunBase<valarray<_Tp>, valarray<_Tp> > {
00169 typedef _BinFunBase<valarray<_Tp>, valarray<_Tp> > _Base;
00170 typedef _Tp value_type;
00171
00172 _BinFunClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w,
00173 _Tp __f(_Tp, _Tp))
00174 : _Base (__v, __w, __f) {}
00175 };
00176
00177 template<class _Dom>
00178 struct _BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>
00179 : _BinFunBase<_Dom,valarray<typename _Dom::value_type> > {
00180 typedef typename _Dom::value_type _Tp;
00181 typedef _BinFunBase<_Dom,valarray<_Tp> > _Base;
00182 typedef _Tp value_type;
00183
00184 _BinFunClos (const _Dom& __e, const valarray<_Tp>& __v,
00185 _Tp __f(_Tp, _Tp))
00186 : _Base (__e, __v, __f) {}
00187 };
00188
00189 template<class _Dom>
00190 struct _BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>
00191 : _BinFunBase<valarray<typename _Dom::value_type>,_Dom> {
00192 typedef typename _Dom::value_type _Tp;
00193 typedef _BinFunBase<_Dom,valarray<_Tp> > _Base;
00194 typedef _Tp value_type;
00195
00196 _BinFunClos (const valarray<_Tp>& __v, const _Dom& __e,
00197 _Tp __f(_Tp, _Tp))
00198 : _Base (__v, __e, __f) {}
00199 };
00200
00201 template<class _Dom>
00202 struct _BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>
00203 : _BinFunBase2<_Dom> {
00204 typedef typename _Dom::value_type _Tp;
00205 typedef _Tp value_type;
00206 typedef _BinFunBase2<_Dom> _Base;
00207
00208 _BinFunClos (const _Dom& __e, const _Tp& __t, _Tp __f (_Tp, _Tp))
00209 : _Base (__e, __t, __f) {}
00210 };
00211
00212 template<class _Dom>
00213 struct _BinFunClos<_Constant,_Expr,_Dom,typename _Dom::value_type>
00214 : _BinFunBase1<_Dom> {
00215 typedef typename _Dom::value_type _Tp;
00216 typedef _Tp value_type;
00217 typedef _BinFunBase1<_Dom> _Base;
00218
00219 _BinFunClos (const _Tp& __t, const _Dom& __e, _Tp __f (_Tp, _Tp))
00220 : _Base (__t, __e, __f) {}
00221 };
00222
00223 template<typename _Tp>
00224 struct _BinFunClos<_ValArray,_Constant,_Tp,_Tp>
00225 : _BinFunBase2<valarray<_Tp> > {
00226 typedef _BinFunBase2<valarray<_Tp> > _Base;
00227 typedef _Tp value_type;
00228
00229 _BinFunClos (const valarray<_Tp>& __v, const _Tp& __t,
00230 _Tp __f(_Tp, _Tp))
00231 : _Base (__v, __t, __f) {}
00232 };
00233
00234 template<typename _Tp>
00235 struct _BinFunClos<_Constant,_ValArray,_Tp,_Tp>
00236 : _BinFunBase1<valarray<_Tp> > {
00237 typedef _BinFunBase1<valarray<_Tp> > _Base;
00238 typedef _Tp value_type;
00239
00240 _BinFunClos (const _Tp& __t, const valarray<_Tp>& __v,
00241 _Tp __f (_Tp, _Tp))
00242 : _Base (__t, __v, __f) {}
00243 };
00244
00245
00246
00247
00248
00249 template<typename _Dom, typename _Arg> class _FunBase {
00250 public:
00251 typedef typename _Dom::value_type value_type;
00252
00253 _FunBase (const _Dom& __e, value_type __f(_Arg))
00254 : _M_expr (__e), _M_func (__f) {}
00255
00256 value_type operator[] (size_t __i) const
00257 { return _M_func (_M_expr[__i]); }
00258 size_t size() const { return _M_expr.size ();}
00259
00260 private:
00261 const _Dom& _M_expr;
00262 value_type (*_M_func)(_Arg);
00263 };
00264
00265 template<class _Dom>
00266 struct _ValFunClos<_Expr,_Dom>
00267 : _FunBase<_Dom, typename _Dom::value_type> {
00268 typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
00269 typedef typename _Base::value_type value_type;
00270 typedef value_type _Tp;
00271
00272 _ValFunClos (const _Dom& __e, _Tp __f (_Tp)) : _Base (__e, __f) {}
00273 };
00274
00275 template<typename _Tp>
00276 struct _ValFunClos<_ValArray,_Tp>
00277 : _FunBase<valarray<_Tp>, _Tp> {
00278 typedef _FunBase<valarray<_Tp>, _Tp> _Base;
00279 typedef _Tp value_type;
00280
00281 _ValFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
00282 : _Base (__v, __f) {}
00283 };
00284
00285 template<class _Dom>
00286 struct _RefFunClos<_Expr,_Dom> :
00287 _FunBase<_Dom, const typename _Dom::value_type&> {
00288 typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
00289 typedef typename _Base::value_type value_type;
00290 typedef value_type _Tp;
00291
00292 _RefFunClos (const _Dom& __e, _Tp __f (const _Tp&))
00293 : _Base (__e, __f) {}
00294 };
00295
00296 template<typename _Tp>
00297 struct _RefFunClos<_ValArray,_Tp>
00298 : _FunBase<valarray<_Tp>, const _Tp&> {
00299 typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
00300 typedef _Tp value_type;
00301
00302 _RefFunClos (const valarray<_Tp>& __v, _Tp __f(const _Tp&))
00303 : _Base (__v, __f) {}
00304 };
00305
00306
00307
00308
00309
00310 template<template<class> class _Oper, typename _Arg>
00311 class _UnBase {
00312 public:
00313 typedef _Oper<typename _Arg::value_type> _Op;
00314 typedef typename _Op::result_type value_type;
00315
00316 _UnBase (const _Arg& __e) : _M_expr(__e) {}
00317 value_type operator[] (size_t) const;
00318 size_t size () const { return _M_expr.size (); }
00319
00320 private:
00321 const _Arg& _M_expr;
00322 };
00323
00324 template<template<class> class _Oper, typename _Arg>
00325 inline typename _UnBase<_Oper, _Arg>::value_type
00326 _UnBase<_Oper, _Arg>::operator[] (size_t __i) const
00327 { return _Op() (_M_expr[__i]); }
00328
00329 template<template<class> class _Oper, class _Dom>
00330 struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> {
00331 typedef _Dom _Arg;
00332 typedef _UnBase<_Oper, _Dom> _Base;
00333 typedef typename _Base::value_type value_type;
00334
00335 _UnClos (const _Arg& __e) : _Base(__e) {}
00336 };
00337
00338 template<template<class> class _Oper, typename _Tp>
00339 struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > {
00340 typedef valarray<_Tp> _Arg;
00341 typedef _UnBase<_Oper, valarray<_Tp> > _Base;
00342 typedef typename _Base::value_type value_type;
00343
00344 _UnClos (const _Arg& __e) : _Base(__e) {}
00345 };
00346
00347
00348
00349
00350
00351
00352 template<template<class> class _Oper,
00353 typename _FirstArg, typename _SecondArg>
00354 class _BinBase {
00355 public:
00356 typedef _Oper<typename _FirstArg::value_type> _Op;
00357 typedef typename _Op::result_type value_type;
00358
00359 _BinBase (const _FirstArg& __e1, const _SecondArg& __e2)
00360 : _M_expr1 (__e1), _M_expr2 (__e2) {}
00361 value_type operator[] (size_t) const;
00362 size_t size () const { return _M_expr1.size (); }
00363
00364 private:
00365 const _FirstArg& _M_expr1;
00366 const _SecondArg& _M_expr2;
00367 };
00368
00369 template<template<class> class _Oper,
00370 typename _FirstArg, typename _SecondArg>
00371 inline typename _BinBase<_Oper,_FirstArg,_SecondArg>::value_type
00372 _BinBase<_Oper,_FirstArg,_SecondArg>::operator[] (size_t __i) const
00373 { return _Op() (_M_expr1[__i], _M_expr2[__i]); }
00374
00375
00376 template<template<class> class _Oper, class _Clos>
00377 class _BinBase2 {
00378 public:
00379 typedef typename _Clos::value_type _Vt;
00380 typedef _Oper<_Vt> _Op;
00381 typedef typename _Op::result_type value_type;
00382
00383 _BinBase2 (const _Clos& __e, const _Vt& __t)
00384 : _M_expr1 (__e), _M_expr2 (__t) {}
00385 value_type operator[] (size_t) const;
00386 size_t size () const { return _M_expr1.size (); }
00387
00388 private:
00389 const _Clos& _M_expr1;
00390 const _Vt& _M_expr2;
00391 };
00392
00393 template<template<class> class _Oper, class _Clos>
00394 inline typename _BinBase2<_Oper,_Clos>::value_type
00395 _BinBase2<_Oper,_Clos>::operator[] (size_t __i) const
00396 { return _Op() (_M_expr1[__i], _M_expr2); }
00397
00398
00399 template<template<class> class _Oper, class _Clos>
00400 class _BinBase1 {
00401 public:
00402 typedef typename _Clos::value_type _Vt;
00403 typedef _Oper<_Vt> _Op;
00404 typedef typename _Op::result_type value_type;
00405
00406 _BinBase1 (const _Vt& __t, const _Clos& __e)
00407 : _M_expr1 (__t), _M_expr2 (__e) {}
00408 value_type operator[] (size_t) const;
00409 size_t size () const { return _M_expr2.size (); }
00410
00411 private:
00412 const _Vt& _M_expr1;
00413 const _Clos& _M_expr2;
00414 };
00415
00416 template<template<class> class _Oper, class _Clos>
00417 inline typename
00418 _BinBase1<_Oper,_Clos>::value_type
00419 _BinBase1<_Oper,_Clos>:: operator[] (size_t __i) const
00420 { return _Op() (_M_expr1, _M_expr2[__i]); }
00421
00422
00423 template<template<class> class _Oper, class _Dom1, class _Dom2>
00424 struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
00425 : _BinBase<_Oper,_Dom1,_Dom2> {
00426 typedef _BinBase<_Oper,_Dom1,_Dom2> _Base;
00427 typedef typename _Base::value_type value_type;
00428
00429 _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
00430 };
00431
00432 template<template<class> class _Oper, typename _Tp>
00433 struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp>
00434 : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > {
00435 typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base;
00436 typedef _Tp value_type;
00437
00438 _BinClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w)
00439 : _Base (__v, __w) {}
00440 };
00441
00442 template<template<class> class _Oper, class _Dom>
00443 struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type>
00444 : _BinBase<_Oper,_Dom,valarray<typename _Dom::value_type> > {
00445 typedef typename _Dom::value_type _Tp;
00446 typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
00447 typedef typename _Base::value_type value_type;
00448
00449 _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
00450 : _Base (__e1, __e2) {}
00451 };
00452
00453 template<template<class> class _Oper, class _Dom>
00454 struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom>
00455 : _BinBase<_Oper,valarray<typename _Dom::value_type>,_Dom> {
00456 typedef typename _Dom::value_type _Tp;
00457 typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base;
00458 typedef typename _Base::value_type value_type;
00459
00460 _BinClos (const valarray<_Tp>& __e1, const _Dom& __e2)
00461 : _Base (__e1, __e2) {}
00462 };
00463
00464 template<template<class> class _Oper, class _Dom>
00465 struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type>
00466 : _BinBase2<_Oper,_Dom> {
00467 typedef typename _Dom::value_type _Tp;
00468 typedef _BinBase2<_Oper,_Dom> _Base;
00469 typedef typename _Base::value_type value_type;
00470
00471 _BinClos (const _Dom& __e1, const _Tp& __e2) : _Base (__e1, __e2) {}
00472 };
00473
00474 template<template<class> class _Oper, class _Dom>
00475 struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom>
00476 : _BinBase1<_Oper,_Dom> {
00477 typedef typename _Dom::value_type _Tp;
00478 typedef _BinBase1<_Oper,_Dom> _Base;
00479 typedef typename _Base::value_type value_type;
00480
00481 _BinClos (const _Tp& __e1, const _Dom& __e2) : _Base (__e1, __e2) {}
00482 };
00483
00484 template<template<class> class _Oper, typename _Tp>
00485 struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp>
00486 : _BinBase2<_Oper,valarray<_Tp> > {
00487 typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
00488 typedef typename _Base::value_type value_type;
00489
00490 _BinClos (const valarray<_Tp>& __v, const _Tp& __t)
00491 : _Base (__v, __t) {}
00492 };
00493
00494 template<template<class> class _Oper, typename _Tp>
00495 struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp>
00496 : _BinBase1<_Oper,valarray<_Tp> > {
00497 typedef _BinBase1<_Oper,valarray<_Tp> > _Base;
00498 typedef typename _Base::value_type value_type;
00499
00500 _BinClos (const _Tp& __t, const valarray<_Tp>& __v)
00501 : _Base (__t, __v) {}
00502 };
00503
00504
00505
00506
00507
00508 template<typename _Dom> class _SBase {
00509 public:
00510 typedef typename _Dom::value_type value_type;
00511
00512 _SBase (const _Dom& __e, const slice& __s)
00513 : _M_expr (__e), _M_slice (__s) {}
00514 value_type operator[] (size_t __i) const
00515 { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
00516 size_t size() const { return _M_slice.size (); }
00517
00518 private:
00519 const _Dom& _M_expr;
00520 const slice& _M_slice;
00521 };
00522
00523 template<typename _Tp> class _SBase<_Array<_Tp> > {
00524 public:
00525 typedef _Tp value_type;
00526
00527 _SBase (_Array<_Tp> __a, const slice& __s)
00528 : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
00529 _M_stride (__s.stride()) {}
00530 value_type operator[] (size_t __i) const
00531 { return _M_array._M_data[__i * _M_stride]; }
00532 size_t size() const { return _M_size; }
00533
00534 private:
00535 const _Array<_Tp> _M_array;
00536 const size_t _M_size;
00537 const size_t _M_stride;
00538 };
00539
00540 template<class _Dom> struct _SClos<_Expr,_Dom> : _SBase<_Dom> {
00541 typedef _SBase<_Dom> _Base;
00542 typedef typename _Base::value_type value_type;
00543
00544 _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
00545 };
00546
00547 template<typename _Tp>
00548 struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > {
00549 typedef _SBase<_Array<_Tp> > _Base;
00550 typedef _Tp value_type;
00551
00552 _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
00553 };
00554
00555
00556
00557
00558 template<class _Dom> class _GBase {
00559 public:
00560 typedef typename _Dom::value_type value_type;
00561
00562 _GBase (const _Dom& __e, const valarray<size_t>& __i)
00563 : _M_expr (__e), _M_index(__i) {}
00564 value_type operator[] (size_t __i) const
00565 { return _M_expr[_M_index[__i]]; }
00566 size_t size () const { return _M_index.size(); }
00567
00568 private:
00569 const _Dom& _M_expr;
00570 const valarray<size_t>& _M_index;
00571 };
00572
00573 template<typename _Tp> class _GBase<_Array<_Tp> > {
00574 public:
00575 typedef _Tp value_type;
00576
00577 _GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
00578 : _M_array (__a), _M_index(__i) {}
00579 value_type operator[] (size_t __i) const
00580 { return _M_array._M_data[_M_index[__i]]; }
00581 size_t size () const { return _M_index.size(); }
00582
00583 private:
00584 const _Array<_Tp> _M_array;
00585 const valarray<size_t>& _M_index;
00586 };
00587
00588 template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> {
00589 typedef _GBase<_Dom> _Base;
00590 typedef typename _Base::value_type value_type;
00591
00592 _GClos (const _Dom& __e, const valarray<size_t>& __i)
00593 : _Base (__e, __i) {}
00594 };
00595
00596 template<typename _Tp>
00597 struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > {
00598 typedef _GBase<_Array<_Tp> > _Base;
00599 typedef typename _Base::value_type value_type;
00600
00601 _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
00602 : _Base (__a, __i) {}
00603 };
00604
00605
00606
00607
00608
00609 template<class _Dom> class _IBase {
00610 public:
00611 typedef typename _Dom::value_type value_type;
00612
00613 _IBase (const _Dom& __e, const valarray<size_t>& __i)
00614 : _M_expr (__e), _M_index (__i) {}
00615 value_type operator[] (size_t __i) const
00616 { return _M_expr[_M_index[__i]]; }
00617 size_t size() const { return _M_index.size(); }
00618
00619 private:
00620 const _Dom& _M_expr;
00621 const valarray<size_t>& _M_index;
00622 };
00623
00624 template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> {
00625 typedef _IBase<_Dom> _Base;
00626 typedef typename _Base::value_type value_type;
00627
00628 _IClos (const _Dom& __e, const valarray<size_t>& __i)
00629 : _Base (__e, __i) {}
00630 };
00631
00632 template<typename _Tp>
00633 struct _IClos<_ValArray,_Tp> : _IBase<valarray<_Tp> > {
00634 typedef _IBase<valarray<_Tp> > _Base;
00635 typedef _Tp value_type;
00636
00637 _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
00638 : _Base (__a, __i) {}
00639 };
00640
00641
00642
00643
00644 template<class _Clos, typename _Tp> class _Expr {
00645 public:
00646 typedef _Tp value_type;
00647
00648 _Expr (const _Clos&);
00649
00650 const _Clos& operator() () const;
00651
00652 value_type operator[] (size_t) const;
00653 valarray<value_type> operator[] (slice) const;
00654 valarray<value_type> operator[] (const gslice&) const;
00655 valarray<value_type> operator[] (const valarray<bool>&) const;
00656 valarray<value_type> operator[] (const valarray<size_t>&) const;
00657
00658 _Expr<_UnClos<_Unary_plus,std::_Expr,_Clos>, value_type>
00659 operator+ () const;
00660
00661 _Expr<_UnClos<negate,std::_Expr,_Clos>, value_type>
00662 operator- () const;
00663
00664 _Expr<_UnClos<_Bitwise_not,std::_Expr,_Clos>, value_type>
00665 operator~ () const;
00666
00667 _Expr<_UnClos<logical_not,std::_Expr,_Clos>, bool>
00668 operator! () const;
00669
00670 size_t size () const;
00671 value_type sum () const;
00672
00673 valarray<value_type> shift (int) const;
00674 valarray<value_type> cshift (int) const;
00675
00676 value_type min() const;
00677 value_type max() const;
00678
00679 valarray<value_type> apply(value_type (*) (const value_type&)) const;
00680 valarray<value_type> apply(value_type (*) (value_type)) const;
00681
00682 private:
00683 const _Clos _M_closure;
00684 };
00685
00686 template<class _Clos, typename _Tp>
00687 inline
00688 _Expr<_Clos,_Tp>::_Expr (const _Clos& __c) : _M_closure(__c) {}
00689
00690 template<class _Clos, typename _Tp>
00691 inline const _Clos&
00692 _Expr<_Clos,_Tp>::operator() () const
00693 { return _M_closure; }
00694
00695 template<class _Clos, typename _Tp>
00696 inline _Tp
00697 _Expr<_Clos,_Tp>::operator[] (size_t __i) const
00698 { return _M_closure[__i]; }
00699
00700 template<class _Clos, typename _Tp>
00701 inline valarray<_Tp>
00702 _Expr<_Clos,_Tp>::operator[] (slice __s) const
00703 { return _M_closure[__s]; }
00704
00705 template<class _Clos, typename _Tp>
00706 inline valarray<_Tp>
00707 _Expr<_Clos,_Tp>::operator[] (const gslice& __gs) const
00708 { return _M_closure[__gs]; }
00709
00710 template<class _Clos, typename _Tp>
00711 inline valarray<_Tp>
00712 _Expr<_Clos,_Tp>::operator[] (const valarray<bool>& __m) const
00713 { return _M_closure[__m]; }
00714
00715 template<class _Clos, typename _Tp>
00716 inline valarray<_Tp>
00717 _Expr<_Clos,_Tp>::operator[] (const valarray<size_t>& __i) const
00718 { return _M_closure[__i]; }
00719
00720 template<class _Clos, typename _Tp>
00721 inline size_t
00722 _Expr<_Clos,_Tp>::size () const { return _M_closure.size (); }
00723
00724 template<class _Clos, typename _Tp>
00725 inline valarray<_Tp>
00726 _Expr<_Clos, _Tp>::shift(int __n) const
00727 { return valarray<_Tp>(_M_closure).shift(__n); }
00728
00729 template<class _Clos, typename _Tp>
00730 inline valarray<_Tp>
00731 _Expr<_Clos, _Tp>::cshift(int __n) const
00732 { return valarray<_Tp>(_M_closure).cshift(__n); }
00733
00734 template<class _Clos, typename _Tp>
00735 inline valarray<_Tp>
00736 _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
00737 { return valarray<_Tp>(_M_closure).apply(__f); }
00738
00739 template<class _Clos, typename _Tp>
00740 inline valarray<_Tp>
00741 _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
00742 { return valarray<_Tp>(_M_closure).apply(__f); }
00743
00744
00745 template<class _Clos, typename _Tp>
00746 inline _Tp
00747 _Expr<_Clos,_Tp>::sum () const
00748 {
00749 size_t __n = _M_closure.size();
00750 if (__n == 0) return _Tp();
00751 else {
00752 _Tp __s = _M_closure[--__n];
00753 while (__n != 0) __s += _M_closure[--__n];
00754 return __s;
00755 }
00756 }
00757
00758 template<class _Clos, typename _Tp>
00759 inline _Tp
00760 _Expr<_Clos, _Tp>::min() const
00761 { return __valarray_min(_M_closure); }
00762
00763 template<class _Clos, typename _Tp>
00764 inline _Tp
00765 _Expr<_Clos, _Tp>::max() const
00766 { return __valarray_max(_M_closure); }
00767
00768 template<class _Dom, typename _Tp>
00769 inline _Expr<_UnClos<logical_not,_Expr,_Dom>, bool>
00770 _Expr<_Dom,_Tp>::operator! () const
00771 {
00772 typedef _UnClos<logical_not,std::_Expr,_Dom> _Closure;
00773 return _Expr<_Closure,_Tp> (_Closure(this->_M_closure));
00774 }
00775
00776 #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \
00777 template<class _Dom, typename _Tp> \
00778 inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp> \
00779 _Expr<_Dom,_Tp>::operator _Op () const \
00780 { \
00781 typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \
00782 return _Expr<_Closure,_Tp> (_Closure (this->_M_closure)); \
00783 }
00784
00785 _DEFINE_EXPR_UNARY_OPERATOR(+, _Unary_plus)
00786 _DEFINE_EXPR_UNARY_OPERATOR(-, negate)
00787 _DEFINE_EXPR_UNARY_OPERATOR(~, _Bitwise_not)
00788
00789 #undef _DEFINE_EXPR_UNARY_OPERATOR
00790
00791
00792 #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \
00793 template<class _Dom1, class _Dom2> \
00794 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \
00795 typename _Name<typename _Dom1::value_type>::result_type> \
00796 operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \
00797 const _Expr<_Dom2,typename _Dom2::value_type>& __w) \
00798 { \
00799 typedef typename _Dom1::value_type _Arg; \
00800 typedef typename _Name<_Arg>::result_type _Value; \
00801 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
00802 return _Expr<_Closure,_Value> (_Closure (__v (), __w ())); \
00803 } \
00804 \
00805 template<class _Dom> \
00806 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
00807 typename _Name<typename _Dom::value_type>::result_type> \
00808 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \
00809 const typename _Dom::value_type& __t) \
00810 { \
00811 typedef typename _Dom::value_type _Arg; \
00812 typedef typename _Name<_Arg>::result_type _Value; \
00813 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
00814 return _Expr<_Closure,_Value> (_Closure (__v (), __t)); \
00815 } \
00816 \
00817 template<class _Dom> \
00818 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
00819 typename _Name<typename _Dom::value_type>::result_type> \
00820 operator _Op (const typename _Dom::value_type& __t, \
00821 const _Expr<_Dom,typename _Dom::value_type>& __v) \
00822 { \
00823 typedef typename _Dom::value_type _Arg; \
00824 typedef typename _Name<_Arg>::result_type _Value; \
00825 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
00826 return _Expr<_Closure,_Value> (_Closure (__t, __v ())); \
00827 } \
00828 \
00829 template<class _Dom> \
00830 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
00831 typename _Name<typename _Dom::value_type>::result_type> \
00832 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \
00833 const valarray<typename _Dom::value_type>& __v) \
00834 { \
00835 typedef typename _Dom::value_type _Arg; \
00836 typedef typename _Name<_Arg>::result_type _Value; \
00837 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \
00838 return _Expr<_Closure,_Value> (_Closure (__e (), __v)); \
00839 } \
00840 \
00841 template<class _Dom> \
00842 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
00843 typename _Name<typename _Dom::value_type>::result_type> \
00844 operator _Op (const valarray<typename _Dom::value_type>& __v, \
00845 const _Expr<_Dom,typename _Dom::value_type>& __e) \
00846 { \
00847 typedef typename _Dom::value_type _Tp; \
00848 typedef typename _Name<_Tp>::result_type _Value; \
00849 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
00850 return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \
00851 }
00852
00853 _DEFINE_EXPR_BINARY_OPERATOR(+, plus)
00854 _DEFINE_EXPR_BINARY_OPERATOR(-, minus)
00855 _DEFINE_EXPR_BINARY_OPERATOR(*, multiplies)
00856 _DEFINE_EXPR_BINARY_OPERATOR(/, divides)
00857 _DEFINE_EXPR_BINARY_OPERATOR(%, modulus)
00858 _DEFINE_EXPR_BINARY_OPERATOR(^, _Bitwise_xor)
00859 _DEFINE_EXPR_BINARY_OPERATOR(&, _Bitwise_and)
00860 _DEFINE_EXPR_BINARY_OPERATOR(|, _Bitwise_or)
00861 _DEFINE_EXPR_BINARY_OPERATOR(<<, _Shift_left)
00862 _DEFINE_EXPR_BINARY_OPERATOR(>>, _Shift_right)
00863
00864 #undef _DEFINE_EXPR_BINARY_OPERATOR
00865
00866 #define _DEFINE_EXPR_RELATIONAL_OPERATOR(_Op, _Name) \
00867 template<class _Dom1, class _Dom2> \
00868 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, bool> \
00869 operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \
00870 const _Expr<_Dom2,typename _Dom2::value_type>& __w) \
00871 { \
00872 typedef typename _Dom1::value_type _Arg; \
00873 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
00874 return _Expr<_Closure,bool> (_Closure (__v (), __w ())); \
00875 } \
00876 \
00877 template<class _Dom> \
00878 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
00879 bool> \
00880 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \
00881 const typename _Dom::value_type& __t) \
00882 { \
00883 typedef typename _Dom::value_type _Arg; \
00884 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
00885 return _Expr<_Closure,bool> (_Closure (__v (), __t)); \
00886 } \
00887 \
00888 template<class _Dom> \
00889 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
00890 bool> \
00891 operator _Op (const typename _Dom::value_type& __t, \
00892 const _Expr<_Dom,typename _Dom::value_type>& __v) \
00893 { \
00894 typedef typename _Dom::value_type _Arg; \
00895 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
00896 return _Expr<_Closure,bool> (_Closure (__t, __v ())); \
00897 } \
00898 \
00899 template<class _Dom> \
00900 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
00901 bool> \
00902 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \
00903 const valarray<typename _Dom::value_type>& __v) \
00904 { \
00905 typedef typename _Dom::value_type _Tp; \
00906 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure; \
00907 return _Expr<_Closure,bool> (_Closure (__e (), __v)); \
00908 } \
00909 \
00910 template<class _Dom> \
00911 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
00912 bool> \
00913 operator _Op (const valarray<typename _Dom::value_type>& __v, \
00914 const _Expr<_Dom,typename _Dom::value_type>& __e) \
00915 { \
00916 typedef typename _Dom::value_type _Tp; \
00917 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
00918 return _Expr<_Closure,bool> (_Closure (__v, __e ())); \
00919 }
00920
00921 _DEFINE_EXPR_RELATIONAL_OPERATOR(&&, logical_and)
00922 _DEFINE_EXPR_RELATIONAL_OPERATOR(||, logical_or)
00923 _DEFINE_EXPR_RELATIONAL_OPERATOR(==, equal_to)
00924 _DEFINE_EXPR_RELATIONAL_OPERATOR(!=, not_equal_to)
00925 _DEFINE_EXPR_RELATIONAL_OPERATOR(<, less)
00926 _DEFINE_EXPR_RELATIONAL_OPERATOR(>, greater)
00927 _DEFINE_EXPR_RELATIONAL_OPERATOR(<=, less_equal)
00928 _DEFINE_EXPR_RELATIONAL_OPERATOR(>=, greater_equal)
00929
00930 #undef _DEFINE_EXPR_RELATIONAL_OPERATOR
00931
00932
00933
00934 #define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \
00935 template<class _Dom> \
00936 inline _Expr<_UnFunClos<_Expr,_Dom>,typename _Dom::value_type> \
00937 _Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \
00938 { \
00939 typedef typename _Dom::value_type _Tp; \
00940 typedef _UnFunClos<_Expr,_Dom> _Closure; \
00941 return _Expr<_Closure,_Tp>(_Closure(__e(), (_Tp(*)(_Tp))(&_Name))); \
00942 } \
00943 \
00944 template<typename _Tp> \
00945 inline _Expr<_UnFunClos<_ValArray,_Tp>,_Tp> \
00946 _Name(const valarray<_Tp>& __v) \
00947 { \
00948 typedef _UnFunClos<_ValArray,_Tp> _Closure; \
00949 return _Expr<_Closure,_Tp> (_Closure (__v, (_Tp(*)(_Tp))(&_Name))); \
00950 }
00951
00952
00953 _DEFINE_EXPR_UNARY_FUNCTION(abs)
00954 _DEFINE_EXPR_UNARY_FUNCTION(cos)
00955 _DEFINE_EXPR_UNARY_FUNCTION(acos)
00956 _DEFINE_EXPR_UNARY_FUNCTION(cosh)
00957 _DEFINE_EXPR_UNARY_FUNCTION(sin)
00958 _DEFINE_EXPR_UNARY_FUNCTION(asin)
00959 _DEFINE_EXPR_UNARY_FUNCTION(sinh)
00960 _DEFINE_EXPR_UNARY_FUNCTION(tan)
00961 _DEFINE_EXPR_UNARY_FUNCTION(tanh)
00962 _DEFINE_EXPR_UNARY_FUNCTION(atan)
00963 _DEFINE_EXPR_UNARY_FUNCTION(exp)
00964 _DEFINE_EXPR_UNARY_FUNCTION(log)
00965 _DEFINE_EXPR_UNARY_FUNCTION(log10)
00966 _DEFINE_EXPR_UNARY_FUNCTION(sqrt)
00967
00968 #undef _DEFINE_EXPR_UNARY_FUNCTION
00969
00970
00971 #define _DEFINE_EXPR_BINARY_FUNCTION(_Name) \
00972 template<class _Dom1, class _Dom2> \
00973 inline _Expr<_BinFunClos<_Expr,_Expr,_Dom1,_Dom2>,typename _Dom1::value_type>\
00974 _Name (const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \
00975 const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \
00976 { \
00977 typedef typename _Dom1::value_type _Tp; \
00978 typedef _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> _Closure; \
00979 return _Expr<_Closure,_Tp> \
00980 (_Closure (__e1 (), __e2 (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
00981 } \
00982 \
00983 template<class _Dom> \
00984 inline _Expr<_BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
00985 typename _Dom::value_type> \
00986 _Name (const _Expr<_Dom,typename _Dom::value_type>& __e, \
00987 const valarray<typename _Dom::value_type>& __v) \
00988 { \
00989 typedef typename _Dom::value_type _Tp; \
00990 typedef _BinFunClos<_Expr,_ValArray,_Dom,_Tp> _Closure; \
00991 return _Expr<_Closure,_Tp> \
00992 (_Closure (__e (), __v, (_Tp(*)(_Tp, _Tp))(&_Name))); \
00993 } \
00994 \
00995 template<class _Dom> \
00996 inline _Expr<_BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
00997 typename _Dom::value_type> \
00998 _Name (const valarray<typename _Dom::valarray>& __v, \
00999 const _Expr<_Dom,typename _Dom::value_type>& __e) \
01000 { \
01001 typedef typename _Dom::value_type _Tp; \
01002 typedef _BinFunClos<_ValArray,_Expr,_Tp,_Dom> _Closure; \
01003 return _Expr<_Closure,_Tp> \
01004 (_Closure (__v, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
01005 } \
01006 \
01007 template<class _Dom> \
01008 inline _Expr<_BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>, \
01009 typename _Dom::value_type> \
01010 _Name (const _Expr<_Dom, typename _Dom::value_type>& __e, \
01011 const typename _Dom::value_type& __t) \
01012 { \
01013 typedef typename _Dom::value_type _Tp; \
01014 typedef _BinFunClos<_Expr,_Constant,_Dom,_Tp> _Closure; \
01015 return _Expr<_Closure,_Tp> \
01016 (_Closure (__e (), __t, (_Tp(*)(_Tp, _Tp))(&_Name))); \
01017 } \
01018 \
01019 template<class _Dom> \
01020 inline _Expr<_BinFunClos<_Constant,_Expr,typename _Dom::value_type,_Dom>, \
01021 typename _Dom::value_type> \
01022 _Name (const typename _Dom::value_type& __t, \
01023 const _Expr<_Dom,typename _Dom::value_type>& __e) \
01024 { \
01025 typedef typename _Dom::value_type _Tp; \
01026 typedef _BinFunClos<_Constant,_Expr,_Tp,_Dom> _Closure; \
01027 return _Expr<_Closure,_Tp> \
01028 (_Closure (__t, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
01029 } \
01030 \
01031 template<typename _Tp> \
01032 inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp> \
01033 _Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
01034 { \
01035 typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure; \
01036 return _Expr<_Closure,_Tp> \
01037 (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name))); \
01038 } \
01039 \
01040 template<typename _Tp> \
01041 inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp> \
01042 _Name (const valarray<_Tp>& __v, const _Tp& __t) \
01043 { \
01044 typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure; \
01045 return _Expr<_Closure,_Tp> \
01046 (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name))); \
01047 } \
01048 \
01049 template<typename _Tp> \
01050 inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp> \
01051 _Name (const _Tp& __t, const valarray<_Tp>& __v) \
01052 { \
01053 typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure; \
01054 return _Expr<_Closure,_Tp> \
01055 (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name))); \
01056 }
01057
01058 _DEFINE_EXPR_BINARY_FUNCTION(atan2)
01059 _DEFINE_EXPR_BINARY_FUNCTION(pow)
01060
01061 #undef _DEFINE_EXPR_BINARY_FUNCTION
01062
01063 }
01064
01065
01066 #endif
01067
01068
01069
01070