home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 November / PCWorld_2000-11_cd.bin / Software / Topware / devc40 / _SETUP.6 / Group12 / valarray_meta.h < prev   
C/C++ Source or Header  |  2000-01-21  |  41KB  |  1,046 lines

  1. // The template and inlines for the -*- C++ -*- internal _Meta class.
  2.  
  3. // Copyright (C) 1997-1999 Cygnus Solutions
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 2, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // You should have received a copy of the GNU General Public License along
  17. // with this library; see the file COPYING.  If not, write to the Free
  18. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  19. // USA.
  20.  
  21. // As a special exception, you may use this file as part of a free software
  22. // library without restriction.  Specifically, if other files instantiate
  23. // templates or use macros or inline functions from this file, or you compile
  24. // this file and link it with other files to produce an executable, this
  25. // file does not by itself cause the resulting executable to be covered by
  26. // the GNU General Public License.  This exception does not however
  27. // invalidate any other reasons why the executable file might be covered by
  28. // the GNU General Public License.
  29.  
  30. // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
  31.  
  32. #ifndef _CPP_VALARRAY_META_H
  33. #define _CPP_VALARRAY_META_H 1
  34.  
  35. //
  36. // Implementing a loosened valarray return value is tricky.
  37. // First we need to meet 26.3.1/3: we should not add more than
  38. // two levels of template nesting. Therefore we resort to template
  39. // template to "flatten" loosened return value types.
  40. // At some point we use partial specialization to remove one level
  41. // template nesting due to _Expr<>
  42. //
  43.     
  44.  
  45. // This class is NOT defined. It doesn't need to.
  46. template<typename _Tp1, typename _Tp2> class _Constant;
  47.  
  48. //
  49. // Unary function application closure.
  50. //
  51. template<class _Dom> class _UnFunBase {
  52. public:
  53.     typedef typename _Dom::value_type value_type;
  54.     typedef value_type _Vt;
  55.     
  56.     _UnFunBase (const _Dom& __e, _Vt __f(_Vt))
  57.             : _M_expr(__e), _M_func(__f) {}
  58.     
  59.     _Vt operator[] (size_t __i) const { return _M_func(_M_expr[__i]); }
  60.     size_t size () const { return _M_expr.size(); }
  61.     
  62. private:
  63.     const _Dom& _M_expr;
  64.     _Vt (*_M_func)(_Vt);
  65. };
  66.  
  67. template<template<class, class> class _Meta, class _Dom> class _UnFunClos;
  68.  
  69. template<class _Dom>
  70. struct _UnFunClos<_Expr,_Dom> : _UnFunBase<_Dom> {
  71.     typedef _UnFunBase<_Dom> _Base;
  72.     typedef typename _Base::value_type value_type;
  73.     
  74.     _UnFunClos (const _Dom& __e, value_type __f(value_type))
  75.             : _Base (__e, __f) {}
  76. };
  77.  
  78. template<typename _Tp>
  79. struct _UnFunClos<_ValArray,_Tp> : _UnFunBase<valarray<_Tp> > {
  80.     typedef _UnFunBase<valarray<_Tp> > _Base;
  81.     typedef typename _Base::value_type value_type;
  82.     
  83.     _UnFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
  84.             : _Base (__v, __f) {}
  85. };
  86.  
  87. //
  88. // Binary function application closure.
  89. //
  90. template<template<class, class> class _Meta1,
  91.     template<class, class> class Meta2,
  92.     class _Dom1, class _Dom2> class _BinFunClos;
  93.  
  94. template<class _Dom1, class _Dom2> class _BinFunBase {
  95. public:
  96.     typedef typename _Dom1::value_type value_type;
  97.     typedef value_type _Vt;
  98.     
  99.     _BinFunBase (const _Dom1& __e1, const _Dom2& __e2,
  100.                  _Vt __f (_Vt, _Vt))
  101.             : _M_expr1 (__e1), _M_expr2 (__e2), _M_func (__f) {}
  102.     
  103.     value_type operator[] (size_t __i) const
  104.     { return _M_func (_M_expr1[__i], _M_expr2[__i]); }
  105.     size_t size () const { return _M_expr1.size (); }
  106.     
  107. private:
  108.     const _Dom1& _M_expr1;
  109.     const _Dom2& _M_expr2;
  110.     _Vt (*_M_func)(_Vt, _Vt);
  111. };
  112.  
  113. template<class _Dom> class _BinFunBase1 {
  114. public:
  115.     typedef typename _Dom::value_type value_type ;
  116.     typedef value_type _Vt;
  117.     
  118.     _BinFunBase1 (const _Vt& __c, const _Dom& __e, _Vt __f(_Vt, _Vt))
  119.             : _M_expr1 (__c), _M_expr2 (__e), _M_func (__f) {}
  120.     
  121.     value_type operator[] (size_t __i) const
  122.     { return _M_func (_M_expr1, _M_expr2[__i]); }
  123.     size_t size () const { return _M_expr2.size (); }
  124.     
  125. private:
  126.     const _Vt& _M_expr1;
  127.     const _Dom& _M_expr2;
  128.     _Vt (*_M_func)(_Vt, _Vt);
  129. };
  130.  
  131. template<class _Dom> class _BinFunBase2 {
  132. public:
  133.     typedef typename _Dom::value_type value_type;
  134.     typedef value_type _Vt;
  135.     
  136.     _BinFunBase2 (const _Dom& __e, const _Vt& __c, _Vt __f(_Vt, _Vt))
  137.             : _M_expr1 (__e), _M_expr2 (__c), _M_func (__f) {}
  138.     
  139.     value_type operator[] (size_t __i) const
  140.     { return _M_func (_M_expr1[__i], _M_expr2); }
  141.     size_t size () const { return _M_expr1.size (); }
  142.     
  143. private:
  144.     const _Dom& _M_expr1;
  145.     const _Vt& _M_expr2;
  146.     _Vt (*_M_func)(_Vt, _Vt);
  147. };
  148.  
  149. template<class _Dom1, class _Dom2>
  150. struct _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> : _BinFunBase<_Dom1,_Dom2> {
  151.     typedef _BinFunBase<_Dom1,_Dom2> _Base;
  152.     typedef typename _Base::value_type value_type;
  153.     typedef value_type _Tp;
  154.     
  155.     _BinFunClos (const _Dom1& __e1, const _Dom2& __e2,
  156.                  _Tp __f(_Tp, _Tp))
  157.             : _Base (__e1, __e2, __f) {}
  158. };
  159.  
  160. template<typename _Tp>
  161. struct _BinFunClos<_ValArray,_ValArray,_Tp,_Tp>
  162.     : _BinFunBase<valarray<_Tp>, valarray<_Tp> > {
  163.     typedef _BinFunBase<valarray<_Tp>, valarray<_Tp> > _Base;
  164.     typedef _Tp value_type;
  165.     
  166.     _BinFunClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w,
  167.                  _Tp __f(_Tp, _Tp))
  168.             : _Base (__v, __w, __f) {}
  169. };
  170.  
  171. template<class _Dom>
  172. struct _BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>
  173.     : _BinFunBase<_Dom,valarray<typename _Dom::value_type> > {
  174.     typedef typename _Dom::value_type _Tp;
  175.     typedef _BinFunBase<_Dom,valarray<_Tp> > _Base;
  176.     typedef _Tp value_type;
  177.     
  178.     _BinFunClos (const _Dom& __e, const valarray<_Tp>& __v,
  179.                  _Tp __f(_Tp, _Tp))
  180.             : _Base (__e, __v, __f) {}
  181. };
  182.  
  183. template<class _Dom>
  184. struct _BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>
  185.     : _BinFunBase<valarray<typename _Dom::value_type>,_Dom> {
  186.     typedef typename _Dom::value_type _Tp;
  187.     typedef _BinFunBase<_Dom,valarray<_Tp> > _Base;
  188.     typedef _Tp value_type;
  189.     
  190.     _BinFunClos (const valarray<_Tp>& __v, const _Dom& __e,
  191.                  _Tp __f(_Tp, _Tp))
  192.             : _Base (__v, __e, __f) {}
  193. };
  194.  
  195. template<class _Dom>
  196. struct _BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>
  197.     : _BinFunBase2<_Dom> {
  198.     typedef typename _Dom::value_type _Tp;
  199.     typedef _Tp value_type;
  200.     typedef _BinFunBase2<_Dom> _Base;
  201.     
  202.     _BinFunClos (const _Dom& __e, const _Tp& __t, _Tp __f (_Tp, _Tp))
  203.             : _Base (__e, __t, __f) {}
  204. };
  205.  
  206. template<class _Dom>
  207. struct _BinFunClos<_Constant,_Expr,_Dom,typename _Dom::value_type>
  208.     : _BinFunBase1<_Dom> {
  209.     typedef typename _Dom::value_type _Tp;
  210.     typedef _Tp value_type;
  211.     typedef _BinFunBase1<_Dom> _Base;
  212.     
  213.     _BinFunClos (const _Tp& __t, const _Dom& __e, _Tp __f (_Tp, _Tp))
  214.             : _Base (__t, __e, __f) {}
  215. };
  216.  
  217. template<typename _Tp>
  218. struct _BinFunClos<_ValArray,_Constant,_Tp,_Tp>
  219.     : _BinFunBase2<valarray<_Tp> > {
  220.     typedef _BinFunBase2<valarray<_Tp> > _Base;
  221.     typedef _Tp value_type;
  222.     
  223.     _BinFunClos (const valarray<_Tp>& __v, const _Tp& __t,
  224.                  _Tp __f(_Tp, _Tp))
  225.             : _Base (__v, __t, __f) {}
  226. };
  227.  
  228. template<typename _Tp>
  229. struct _BinFunClos<_Constant,_ValArray,_Tp,_Tp>
  230.     : _BinFunBase1<valarray<_Tp> > {
  231.     typedef _BinFunBase1<valarray<_Tp> > _Base;
  232.     typedef _Tp value_type;
  233.     
  234.     _BinFunClos (const _Tp& __t, const valarray<_Tp>& __v,
  235.                  _Tp __f (_Tp, _Tp))
  236.             : _Base (__t, __v, __f) {}
  237. };
  238.  
  239. //
  240. // Apply function taking a value/const reference closure
  241. //
  242.  
  243. template<typename _Dom, typename _Arg> class _FunBase {
  244. public:
  245.     typedef typename _Dom::value_type value_type;
  246.     
  247.     _FunBase (const _Dom& __e, value_type __f(_Arg))
  248.             : _M_expr (__e), _M_func (__f) {}
  249.     
  250.     value_type operator[] (size_t __i) const
  251.     { return _M_func (_M_expr[__i]); }
  252.     size_t size() const { return _M_expr.size ();}
  253.     
  254. private:
  255.     const _Dom& _M_expr;
  256.     value_type (*_M_func)(_Arg);
  257. };
  258.  
  259. template<class _Dom>
  260. struct _ValFunClos<_Expr,_Dom>
  261.     : _FunBase<_Dom, typename _Dom::value_type> {
  262.     typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
  263.     typedef typename _Base::value_type value_type;
  264.     typedef value_type _Tp;
  265.     
  266.     _ValFunClos (const _Dom& __e, _Tp __f (_Tp)) : _Base (__e, __f) {}
  267. };
  268.  
  269. template<typename _Tp>
  270. struct _ValFunClos<_ValArray,_Tp>
  271.     : _FunBase<valarray<_Tp>, _Tp> {
  272.     typedef _FunBase<valarray<_Tp>, _Tp> _Base;
  273.     typedef _Tp value_type;
  274.     
  275.     _ValFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
  276.             : _Base (__v, __f) {}
  277. };
  278.  
  279. template<class _Dom>
  280. struct _RefFunClos<_Expr,_Dom> :
  281.     _FunBase<_Dom, const typename _Dom::value_type&> {
  282.     typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
  283.     typedef typename _Base::value_type value_type;
  284.     typedef value_type _Tp;
  285.     
  286.     _RefFunClos (const _Dom& __e, _Tp __f (const _Tp&))
  287.             : _Base (__e, __f) {}
  288. };
  289.  
  290. template<typename _Tp>
  291. struct _RefFunClos<_ValArray,_Tp>
  292.     : _FunBase<valarray<_Tp>, const _Tp&> {
  293.     typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
  294.     typedef _Tp value_type;
  295.     
  296.     _RefFunClos (const valarray<_Tp>& __v, _Tp __f(const _Tp&))
  297.             : _Base (__v, __f) {}
  298. };
  299.  
  300. //
  301. // Unary expression closure.
  302. //
  303.  
  304. template<template<class> class _Oper, typename _Arg>
  305. class _UnBase {
  306. public:
  307.     typedef _Oper<typename _Arg::value_type> _Op;
  308.     typedef typename _Op::result_type value_type;
  309.     
  310.     _UnBase (const _Arg& __e) : _M_expr(__e) {}
  311.     value_type operator[] (size_t) const;
  312.     size_t size () const { return _M_expr.size (); }
  313.     
  314. private:
  315.     const _Arg& _M_expr;
  316. };
  317.  
  318. template<template<class> class _Oper, typename _Arg>
  319. inline typename _UnBase<_Oper, _Arg>::value_type
  320. _UnBase<_Oper, _Arg>::operator[] (size_t __i) const
  321. { return _Op() (_M_expr[__i]); }
  322.  
  323. template<template<class> class _Oper, class _Dom>
  324. struct _UnClos<_Oper, _Expr, _Dom> :  _UnBase<_Oper, _Dom> {
  325.     typedef _Dom _Arg;
  326.     typedef _UnBase<_Oper, _Dom> _Base;
  327.     typedef typename _Base::value_type value_type;
  328.     
  329.     _UnClos (const _Arg& __e) : _Base(__e) {}
  330. };
  331.  
  332. template<template<class> class _Oper, typename _Tp>
  333. struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > {
  334.     typedef valarray<_Tp> _Arg;
  335.     typedef _UnBase<_Oper, valarray<_Tp> > _Base;
  336.     typedef typename _Base::value_type value_type;
  337.     
  338.     _UnClos (const _Arg& __e) : _Base(__e) {}
  339. };
  340.  
  341.  
  342. //
  343. // Binary expression closure.
  344. //
  345.  
  346. template<template<class> class _Oper, typename _FirstArg, typename _SecondArg>
  347. class _BinBase {
  348. public:
  349.     typedef _Oper<typename _FirstArg::value_type> _Op;
  350.     typedef typename _Op::result_type value_type;
  351.     
  352.     _BinBase (const _FirstArg& __e1, const _SecondArg& __e2)
  353.             : _M_expr1 (__e1), _M_expr2 (__e2) {}
  354.     value_type operator[] (size_t) const;
  355.     size_t size () const { return _M_expr1.size (); }
  356.     
  357. private:
  358.     const _FirstArg& _M_expr1;
  359.     const _SecondArg& _M_expr2;
  360. };
  361.  
  362. template<template<class> class _Oper, typename _FirstArg, typename _SecondArg>
  363. inline typename _BinBase<_Oper,_FirstArg,_SecondArg>::value_type
  364. _BinBase<_Oper,_FirstArg,_SecondArg>::operator[] (size_t __i) const
  365. { return _Op() (_M_expr1[__i], _M_expr2[__i]); }
  366.  
  367.  
  368. template<template<class> class _Oper, class _Clos>
  369. class _BinBase2 {
  370. public:
  371.         typedef typename _Clos::value_type _Vt;
  372.     typedef _Oper<_Vt> _Op;
  373.     typedef typename _Op::result_type value_type;
  374.     
  375.     _BinBase2 (const _Clos& __e, const _Vt& __t)
  376.             : _M_expr1 (__e), _M_expr2 (__t) {}
  377.     value_type operator[] (size_t) const;
  378.     size_t size () const { return _M_expr1.size (); }
  379.     
  380. private:
  381.     const _Clos& _M_expr1;
  382.     const _Vt& _M_expr2;
  383. };
  384.  
  385. template<template<class> class _Oper, class _Clos>
  386. inline typename _BinBase2<_Oper,_Clos>::value_type
  387. _BinBase2<_Oper,_Clos>::operator[] (size_t __i) const
  388. { return _Op() (_M_expr1[__i], _M_expr2); }
  389.  
  390.  
  391. template<template<class> class _Oper, class _Clos>
  392. class _BinBase1 {
  393. public:
  394.     typedef typename _Clos::value_type _Vt;
  395.     typedef _Oper<_Vt> _Op;
  396.     typedef typename _Op::result_type value_type;
  397.     
  398.     _BinBase1 (const _Vt& __t, const _Clos& __e)
  399.             : _M_expr1 (__t), _M_expr2 (__e) {}
  400.     value_type operator[] (size_t) const;
  401.     size_t size () const { return _M_expr2.size (); }
  402.     
  403. private:
  404.     const _Vt& _M_expr1;
  405.     const _Clos& _M_expr2;
  406. };
  407.  
  408. template<template<class> class _Oper, class _Clos>
  409. inline typename
  410. _BinBase1<_Oper,_Clos>::value_type
  411. _BinBase1<_Oper,_Clos>:: operator[] (size_t __i) const
  412. { return _Op() (_M_expr1, _M_expr2[__i]); }
  413.  
  414.  
  415. template<template<class> class _Oper, class _Dom1, class _Dom2>
  416. struct  _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
  417.     : _BinBase<_Oper,_Dom1,_Dom2> {
  418.     typedef _BinBase<_Oper,_Dom1,_Dom2> _Base;
  419.     typedef typename _Base::value_type value_type;
  420.     
  421.     _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
  422. };
  423.  
  424. template<template<class> class _Oper, typename _Tp>
  425. struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp>
  426.     : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > {
  427.     typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base;
  428.     typedef _Tp value_type;
  429.     
  430.     _BinClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w)
  431.             : _Base (__v, __w) {}
  432. };
  433.  
  434. template<template<class> class _Oper, class _Dom>
  435. struct  _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type>
  436.     : _BinBase<_Oper,_Dom,valarray<typename _Dom::value_type> > {
  437.         typedef typename _Dom::value_type _Tp;
  438.     typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
  439.     typedef typename _Base::value_type value_type;
  440.     
  441.     _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
  442.             : _Base (__e1, __e2) {}
  443. };
  444.  
  445. template<template<class> class _Oper, class _Dom>
  446. struct  _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom>
  447.     : _BinBase<_Oper,valarray<typename _Dom::value_type>,_Dom> {
  448.     typedef typename _Dom::value_type _Tp;
  449.     typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base;
  450.     typedef typename _Base::value_type value_type;
  451.     
  452.     _BinClos (const valarray<_Tp>& __e1, const _Dom& __e2)
  453.             : _Base (__e1, __e2) {}
  454. };
  455.  
  456. template<template<class> class _Oper, class _Dom>
  457. struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type>
  458.     : _BinBase2<_Oper,_Dom> {
  459.     typedef typename _Dom::value_type _Tp;
  460.     typedef _BinBase2<_Oper,_Dom> _Base;
  461.     typedef typename _Base::value_type value_type;
  462.     
  463.     _BinClos (const _Dom& __e1, const _Tp& __e2) : _Base (__e1, __e2) {}
  464. };
  465.  
  466. template<template<class> class _Oper, class _Dom>
  467. struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom>
  468.     : _BinBase1<_Oper,_Dom> {
  469.     typedef typename _Dom::value_type _Tp;
  470.     typedef _BinBase1<_Oper,_Dom> _Base;
  471.     typedef typename _Base::value_type value_type;
  472.     
  473.     _BinClos (const _Tp& __e1, const _Dom& __e2) : _Base (__e1, __e2) {}
  474. };
  475.  
  476. template<template<class> class _Oper, typename _Tp>
  477. struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp>
  478.     : _BinBase2<_Oper,valarray<_Tp> > {
  479.     typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
  480.     typedef typename _Base::value_type value_type;
  481.     
  482.     _BinClos (const valarray<_Tp>& __v, const _Tp& __t)
  483.             : _Base (__v, __t) {}
  484. };
  485.  
  486. template<template<class> class _Oper, typename _Tp>
  487. struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp>
  488.     : _BinBase1<_Oper,valarray<_Tp> > {
  489.     typedef _BinBase1<_Oper,valarray<_Tp> > _Base;
  490.     typedef typename _Base::value_type value_type;
  491.     
  492.     _BinClos (const _Tp& __t, const valarray<_Tp>& __v)
  493.             : _Base (__t, __v) {}
  494. };
  495.  
  496.  
  497. //
  498. // slice_array closure.
  499. //
  500. template<typename _Dom>  class _SBase {
  501. public:
  502.     typedef typename _Dom::value_type value_type;
  503.     
  504.     _SBase (const _Dom& __e, const slice& __s)
  505.             : _M_expr (__e), _M_slice (__s) {}
  506.     value_type operator[] (size_t __i) const
  507.     { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
  508.     size_t size() const { return _M_slice.size (); }
  509.     
  510. private:
  511.     const _Dom& _M_expr;
  512.     const slice& _M_slice;
  513. };
  514.  
  515. template<typename _Tp> class _SBase<_Array<_Tp> > {
  516. public:
  517.     typedef _Tp value_type;
  518.     
  519.     _SBase (_Array<_Tp> __a, const slice& __s)
  520.             : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
  521.               _M_stride (__s.stride()) {}
  522.     value_type operator[] (size_t __i) const
  523.     { return _M_array._M_data[__i * _M_stride]; }
  524.     size_t size() const { return _M_size; }
  525.     
  526. private:
  527.     const _Array<_Tp> _M_array;
  528.     const size_t _M_size;
  529.     const size_t _M_stride;
  530. };
  531.  
  532. template<class _Dom> struct  _SClos<_Expr,_Dom> : _SBase<_Dom> {
  533.     typedef _SBase<_Dom> _Base;
  534.     typedef typename _Base::value_type value_type;
  535.     
  536.     _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
  537. };
  538.  
  539. template<typename _Tp>
  540. struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > {
  541.     typedef  _SBase<_Array<_Tp> > _Base;
  542.     typedef _Tp value_type;
  543.     
  544.     _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
  545. };
  546.  
  547. //
  548. // gslice_array closure.
  549. //
  550. template<class _Dom> class _GBase {
  551. public:
  552.     typedef typename _Dom::value_type value_type;
  553.     
  554.     _GBase (const _Dom& __e, const valarray<size_t>& __i)
  555.             : _M_expr (__e), _M_index(__i) {}
  556.     value_type operator[] (size_t __i) const
  557.     { return _M_expr[_M_index[__i]]; }
  558.     size_t size () const { return _M_index.size(); }
  559.     
  560. private:
  561.     const _Dom&     _M_expr;
  562.     const valarray<size_t>& _M_index;
  563. };
  564.  
  565. template<typename _Tp> class _GBase<_Array<_Tp> > {
  566. public:
  567.     typedef _Tp value_type;
  568.     
  569.     _GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
  570.             : _M_array (__a), _M_index(__i) {}
  571.     value_type operator[] (size_t __i) const
  572.     { return _M_array._M_data[_M_index[__i]]; }
  573.     size_t size () const { return _M_index.size(); }
  574.     
  575. private:
  576.     const _Array<_Tp>     _M_array;
  577.     const valarray<size_t>& _M_index;
  578. };
  579.  
  580. template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> {
  581.     typedef _GBase<_Dom> _Base;
  582.     typedef typename _Base::value_type value_type;
  583.  
  584.     _GClos (const _Dom& __e, const valarray<size_t>& __i)
  585.             : _Base (__e, __i) {}
  586. };
  587.  
  588. template<typename _Tp>
  589. struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > {
  590.     typedef _GBase<_Array<_Tp> > _Base;
  591.     typedef typename _Base::value_type value_type;
  592.     
  593.     _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
  594.             : _Base (__a, __i) {}
  595. };
  596.  
  597. //
  598. // indirect_array closure
  599. //
  600.  
  601. template<class _Dom> class _IBase {
  602. public:
  603.     typedef typename _Dom::value_type value_type;
  604.  
  605.     _IBase (const _Dom& __e, const valarray<size_t>& __i)
  606.             : _M_expr (__e), _M_index (__i) {}
  607.     value_type operator[] (size_t __i) const
  608.     { return _M_expr[_M_index[__i]]; }
  609.     size_t size() const { return _M_index.size(); }
  610.     
  611. private:
  612.     const _Dom&         _M_expr;
  613.     const valarray<size_t>& _M_index;
  614. };
  615.  
  616. template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> {
  617.     typedef _IBase<_Dom> _Base;
  618.     typedef typename _Base::value_type value_type;
  619.     
  620.     _IClos (const _Dom& __e, const valarray<size_t>& __i)
  621.             : _Base (__e, __i) {}
  622. };
  623.  
  624. template<typename _Tp>
  625. struct _IClos<_ValArray,_Tp>  : _IBase<valarray<_Tp> > {
  626.     typedef _IBase<valarray<_Tp> > _Base;
  627.     typedef _Tp value_type;
  628.     
  629.     _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
  630.             : _Base (__a, __i) {}
  631. };
  632.  
  633. //
  634. // class _Expr
  635. //      
  636. template<class _Clos, typename _Tp> class _Expr {
  637. public:
  638.     typedef _Tp value_type;
  639.     
  640.     _Expr (const _Clos&);
  641.     
  642.     const _Clos& operator() () const;
  643.     
  644.     value_type operator[] (size_t) const;
  645.     valarray<value_type> operator[] (slice) const;
  646.     valarray<value_type> operator[] (const gslice&) const;
  647.     valarray<value_type> operator[] (const valarray<bool>&) const;
  648.     valarray<value_type> operator[] (const valarray<size_t>&) const;
  649.     
  650.     _Expr<_UnClos<_Unary_plus,_Expr,_Clos>, value_type>
  651.     operator+ () const;
  652.     
  653.     _Expr<_UnClos<negate,_Expr,_Clos>, value_type>
  654.     operator- () const;
  655.     
  656.     _Expr<_UnClos<_Bitwise_not,_Expr,_Clos>, value_type>
  657.     operator~ () const;
  658.     
  659.     _Expr<_UnClos<logical_not,_Expr,_Clos>, bool>
  660.     operator! () const;
  661.     
  662.     size_t size () const;
  663.     value_type sum () const;
  664.     
  665.     valarray<value_type> shift (int) const;
  666.     valarray<value_type> cshift (int) const;
  667. //     _Meta<_ApplyFunctionWithValue<_Expr>, value_type>
  668. //     apply (value_type _M_func (value_type)) const;
  669. //     _Meta<_ApplyFunctionWithConstRef<_Expr>, value_type>
  670. //     apply (value_type _M_func (const value_type&)) const;
  671.         
  672. private:
  673.     const _Clos _M_closure;
  674. };
  675.     
  676. template<class _Clos, typename _Tp>
  677. inline
  678. _Expr<_Clos,_Tp>::_Expr (const _Clos& __c) : _M_closure(__c) {}
  679.  
  680. template<class _Clos, typename _Tp>
  681. inline const _Clos&
  682. _Expr<_Clos,_Tp>::operator() () const
  683. { return _M_closure; }
  684.  
  685. template<class _Clos, typename _Tp>
  686. inline _Tp
  687. _Expr<_Clos,_Tp>::operator[] (size_t __i) const
  688. { return _M_closure[__i]; }
  689.  
  690. template<class _Clos, typename _Tp>
  691. inline valarray<_Tp>
  692. _Expr<_Clos,_Tp>::operator[] (slice __s) const
  693. { return _M_closure[__s]; }
  694.  
  695. template<class _Clos, typename _Tp>
  696. inline valarray<_Tp>
  697. _Expr<_Clos,_Tp>::operator[] (const gslice& __gs) const
  698. { return _M_closure[__gs]; }
  699.  
  700. template<class _Clos, typename _Tp>
  701. inline valarray<_Tp>
  702. _Expr<_Clos,_Tp>::operator[] (const valarray<bool>& __m) const
  703. { return _M_closure[__m]; }
  704.  
  705. template<class _Clos, typename _Tp>
  706. inline valarray<_Tp>
  707. _Expr<_Clos,_Tp>::operator[] (const valarray<size_t>& __i) const
  708. { return _M_closure[__i]; }
  709.  
  710. template<class _Clos, typename _Tp>
  711. inline size_t
  712. _Expr<_Clos,_Tp>::size () const  { return _M_closure.size (); }
  713.  
  714. // XXX: replace this with a more robust summation algorithm.
  715. template<class _Clos, typename _Tp>
  716. inline _Tp
  717. _Expr<_Clos,_Tp>::sum () const
  718. {
  719.         _Tp __s(_Tp());
  720.         size_t __n (_M_closure.size ());
  721.         for (size_t __i=0; __i<__n; ++__i) __s += _M_closure[__i];
  722.         return __s;
  723. }
  724.  
  725. template<class _Dom, typename _Tp>
  726. inline _Tp
  727. min (const _Expr<_Dom,_Tp>& __e)
  728. {
  729.     size_t __s (__e.size ());
  730.     _Tp  __m (__e[0]);
  731.     for (size_t __i=1; __i<__s; ++__i)
  732.         if (__m > __e[__i]) __m = __e[__i];
  733.     return __m;
  734. }
  735.  
  736. template<class _Dom, typename _Tp>
  737. inline _Tp
  738. max (const _Expr<_Dom,_Tp>& __e)
  739. {
  740.     size_t __s (__e.size());
  741.     _Tp __m (__e[0]);
  742.     for (size_t __i=1; __i<__s; ++__i)
  743.         if (__m < __e[__i]) __m = __e[__i];
  744.     return __m;
  745. }
  746.  
  747. template<class _Dom, typename _Tp>
  748. inline _Expr<_UnClos<logical_not,_Expr,_Dom>, bool>
  749. _Expr<_Dom,_Tp>::operator! () const
  750. {
  751.     typedef _UnClos<logical_not,_Expr,_Dom> _Closure;
  752.     return _Expr<_Closure,_Tp> (_Closure(this->_M_closure));
  753. }
  754.  
  755. #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name)                         \
  756. template<class _Dom, typename _Tp>                                      \
  757. inline _Expr<_UnClos<_Name,_Expr,_Dom>,_Tp>                             \
  758. _Expr<_Dom,_Tp>::operator##_Op () const                                 \
  759. {                                                                       \
  760.     typedef _UnClos<_Name,_Expr,_Dom> _Closure;                         \
  761.     return _Expr<_Closure,_Tp> (_Closure (this->_M_closure));           \
  762. }
  763.  
  764.     _DEFINE_EXPR_UNARY_OPERATOR(+, _Unary_plus)
  765.     _DEFINE_EXPR_UNARY_OPERATOR(-, negate)
  766.     _DEFINE_EXPR_UNARY_OPERATOR(~, _Bitwise_not)
  767.  
  768. #undef _DEFINE_EXPR_UNARY_OPERATOR
  769.  
  770.  
  771. #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name)                        \
  772. template<class _Dom1, class _Dom2>                    \
  773. inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>,                   \
  774.              typename _Name<typename _Dom1::value_type>::result_type>   \
  775. operator##_Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v,      \
  776.               const _Expr<_Dom2,typename _Dom2::value_type>& __w)       \
  777. {                                                                       \
  778.     typedef typename _Dom1::value_type _Arg;                            \
  779.     typedef typename _Name<_Arg>::result_type _Value;                   \
  780.     typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure;           \
  781.     return _Expr<_Closure,_Value> (_Closure (__v (), __w ()));          \
  782. }                                                                       \
  783.                                                                         \
  784. template<class _Dom>                                                    \
  785. inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
  786.              typename _Name<typename _Dom::value_type>::result_type>    \
  787. operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __v,        \
  788.               const typename _Dom::value_type& __t)                     \
  789. {                                                                       \
  790.     typedef typename _Dom::value_type _Arg;                             \
  791.     typedef typename _Name<_Arg>::result_type _Value;                   \
  792.     typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure;         \
  793.     return _Expr<_Closure,_Value> (_Closure (__v (), __t));             \
  794. }                                                                       \
  795.                                                                         \
  796. template<class _Dom>                                                    \
  797. inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
  798.              typename _Name<typename _Dom::value_type>::result_type>    \
  799. operator##_Op (const typename _Dom::value_type& __t,                    \
  800.                const _Expr<_Dom,typename _Dom::value_type>& __v)        \
  801. {                                                                       \
  802.     typedef typename _Dom::value_type _Arg;                             \
  803.     typedef typename _Name<_Arg>::result_type _Value;                   \
  804.     typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure;         \
  805.     return _Expr<_Closure,_Value> (_Closure (__t, __v ()));             \
  806. }                                                                       \
  807.                                                                         \
  808. template<class _Dom>                                                    \
  809. inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
  810.              typename _Name<typename _Dom::value_type>::result_type>    \
  811. operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __e,        \
  812.                const valarray<typename _Dom::value_type>& __v)          \
  813. {                                                                       \
  814.     typedef typename _Dom::value_type _Arg;                             \
  815.     typedef typename _Name<_Arg>::result_type _Value;                   \
  816.     typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure;         \
  817.     return  _Expr<_Closure,_Value> (_Closure (__e (), __v));            \
  818. }                                                                       \
  819.                                                                         \
  820. template<class _Dom>                                                    \
  821. inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
  822.              typename _Name<typename _Dom::value_type>::result_type>    \
  823. operator##_Op (const valarray<typename _Dom::value_type>& __v,          \
  824.                const _Expr<_Dom,typename _Dom::value_type>& __e)        \
  825. {                                                                       \
  826.     typedef typename _Dom::value_type _Tp;                              \
  827.     typedef typename _Name<_Tp>::result_type _Value;                    \
  828.     typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure;          \
  829.     return _Expr<_Closure,_Value> (_Closure (__v, __e ()));             \
  830. }
  831.  
  832.     _DEFINE_EXPR_BINARY_OPERATOR(+, plus)
  833.     _DEFINE_EXPR_BINARY_OPERATOR(-, minus)
  834.     _DEFINE_EXPR_BINARY_OPERATOR(*, multiplies)
  835.     _DEFINE_EXPR_BINARY_OPERATOR(/, divides)
  836.     _DEFINE_EXPR_BINARY_OPERATOR(%, modulus)
  837.     _DEFINE_EXPR_BINARY_OPERATOR(^, _Bitwise_xor)
  838.     _DEFINE_EXPR_BINARY_OPERATOR(&, _Bitwise_and)
  839.     _DEFINE_EXPR_BINARY_OPERATOR(|, _Bitwise_or)
  840.     _DEFINE_EXPR_BINARY_OPERATOR(<<, _Shift_left)
  841.     _DEFINE_EXPR_BINARY_OPERATOR(>>, _Shift_right)
  842.  
  843. #undef _DEFINE_EXPR_BINARY_OPERATOR
  844.     
  845. #define _DEFINE_EXPR_RELATIONAL_OPERATOR(_Op, _Name)                    \
  846. template<class _Dom1, class _Dom2>                    \
  847. inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, bool>             \
  848. operator##_Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v,      \
  849.               const _Expr<_Dom2,typename _Dom2::value_type>& __w)       \
  850. {                                                                       \
  851.     typedef typename _Dom1::value_type _Arg;                            \
  852.     typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure;           \
  853.     return _Expr<_Closure,bool> (_Closure (__v (), __w ()));            \
  854. }                                                                       \
  855.                                                                         \
  856. template<class _Dom>                                                    \
  857. inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
  858.              bool>                                                      \
  859. operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __v,        \
  860.               const typename _Dom::value_type& __t)                     \
  861. {                                                                       \
  862.     typedef typename _Dom::value_type _Arg;                             \
  863.     typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure;         \
  864.     return _Expr<_Closure,bool> (_Closure (__v (), __t));               \
  865. }                                                                       \
  866.                                                                         \
  867. template<class _Dom>                                                    \
  868. inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
  869.              bool>                                                      \
  870. operator##_Op (const typename _Dom::value_type& __t,                    \
  871.                const _Expr<_Dom,typename _Dom::value_type>& __v)        \
  872. {                                                                       \
  873.     typedef typename _Dom::value_type _Arg;                             \
  874.     typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure;         \
  875.     return _Expr<_Closure,bool> (_Closure (__t, __v ()));               \
  876. }                                                                       \
  877.                                                                         \
  878. template<class _Dom>                                                    \
  879. inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
  880.              bool>                                                      \
  881. operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __e,        \
  882.                const valarray<typename _Dom::value_type>& __v)          \
  883. {                                                                       \
  884.     typedef typename _Dom::value_type _Tp;                              \
  885.     typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure;          \
  886.     return  _Expr<_Closure,bool> (_Closure (__e (), __v));              \
  887. }                                                                       \
  888.                                                                         \
  889. template<class _Dom>                                                    \
  890. inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
  891.              bool>                                                      \
  892. operator##_Op (const valarray<typename _Dom::value_type>& __v,          \
  893.                const _Expr<_Dom,typename _Dom::value_type>& __e)        \
  894. {                                                                       \
  895.     typedef typename _Dom::value_type _Tp;                              \
  896.     typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure;          \
  897.     return _Expr<_Closure,bool> (_Closure (__v, __e ()));               \
  898. }
  899.  
  900.     _DEFINE_EXPR_RELATIONAL_OPERATOR(&&, logical_and)
  901.     _DEFINE_EXPR_RELATIONAL_OPERATOR(||, logical_or)
  902.     _DEFINE_EXPR_RELATIONAL_OPERATOR(==, equal_to)
  903.     _DEFINE_EXPR_RELATIONAL_OPERATOR(!=, not_equal_to)
  904.     _DEFINE_EXPR_RELATIONAL_OPERATOR(<, less)
  905.     _DEFINE_EXPR_RELATIONAL_OPERATOR(>, greater)
  906.     _DEFINE_EXPR_RELATIONAL_OPERATOR(<=, less_equal)
  907.     _DEFINE_EXPR_RELATIONAL_OPERATOR(>=, greater_equal)
  908.  
  909. #undef _DEFINE_EXPR_RELATIONAL_OPERATOR
  910.  
  911.  
  912.  
  913. #define _DEFINE_EXPR_UNARY_FUNCTION(_Name)                              \
  914. template<class _Dom>                                                    \
  915. inline _Expr<_UnFunClos<_Expr,_Dom>,typename _Dom::value_type>          \
  916. _Name(const _Expr<_Dom,typename _Dom::value_type>& __e)                 \
  917. {                                                                       \
  918.     typedef typename _Dom::value_type _Tp;                              \
  919.     typedef _UnFunClos<_Expr,_Dom> _Closure;                            \
  920.     return _Expr<_Closure,_Tp> (_Closure (__e, (_Tp(*)(_Tp))(&_Name))); \
  921. }                                                                       \
  922.                                                                         \
  923. template<typename _Tp>                                                  \
  924. inline _Expr<_UnFunClos<_ValArray,_Tp>,_Tp>                             \
  925. _Name(const valarray<_Tp>& __v)                                         \
  926. {                                                                       \
  927.     typedef _UnFunClos<_ValArray,_Tp> _Closure;                         \
  928.     return _Expr<_Closure,_Tp> (_Closure (__v, (_Tp(*)(_Tp))(&_Name))); \
  929. }
  930.  
  931.  
  932.     _DEFINE_EXPR_UNARY_FUNCTION(abs)
  933.     _DEFINE_EXPR_UNARY_FUNCTION(cos)
  934.     _DEFINE_EXPR_UNARY_FUNCTION(acos)
  935.     _DEFINE_EXPR_UNARY_FUNCTION(cosh)    
  936.     _DEFINE_EXPR_UNARY_FUNCTION(sin)
  937.     _DEFINE_EXPR_UNARY_FUNCTION(asin)
  938.     _DEFINE_EXPR_UNARY_FUNCTION(sinh)    
  939.     _DEFINE_EXPR_UNARY_FUNCTION(tan)    
  940.     _DEFINE_EXPR_UNARY_FUNCTION(atan)
  941.     _DEFINE_EXPR_UNARY_FUNCTION(exp)    
  942.     _DEFINE_EXPR_UNARY_FUNCTION(log)
  943.     _DEFINE_EXPR_UNARY_FUNCTION(log10)
  944.     _DEFINE_EXPR_UNARY_FUNCTION(sqrt)
  945.  
  946. #undef _DEFINE_EXPR_UNARY_FUNCTION
  947.  
  948.  
  949. #define _DEFINE_EXPR_BINARY_FUNCTION(_Name)                             \
  950. template<class _Dom1, class _Dom2>                                      \
  951. inline _Expr<_BinFunClos<_Expr,_Expr,_Dom1,_Dom2>,typename _Dom1::value_type>\
  952. _Name (const _Expr<_Dom1,typename _Dom1::value_type>& __e1,             \
  953.        const _Expr<_Dom2,typename _Dom2::value_type>& __e2)             \
  954. {                                                                       \
  955.     typedef typename _Dom1::value_type _Tp;                             \
  956.     typedef _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> _Closure;              \
  957.     return _Expr<_Closure,_Tp>                                          \
  958.         (_Closure (__e1 (), __e2 (), (_Tp(*)(_Tp, _Tp))(&_Name)));      \
  959. }                                                                       \
  960.                                                                         \
  961. template<class _Dom>                                                    \
  962. inline _Expr<_BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
  963.              typename _Dom::value_type>                                 \
  964. _Name (const _Expr<_Dom,typename _Dom::value_type>& __e,                \
  965.        const valarray<typename _Dom::value_type>& __v)                  \
  966. {                                                                       \
  967.     typedef typename _Dom::value_type _Tp;                              \
  968.     typedef _BinFunClos<_Expr,_ValArray,_Dom,_Tp> _Closure;             \
  969.     return _Expr<_Closure,_Tp>                                          \
  970.         (_Closure (__e (), __v, (_Tp(*)(_Tp, _Tp))(&_Name)));           \
  971. }                                                                       \
  972.                                                                         \
  973. template<class _Dom>                                                    \
  974. inline _Expr<_BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
  975.              typename _Dom::value_type>                                 \
  976. _Name (const valarray<typename _Dom::valarray>& __v,                    \
  977.        const _Expr<_Dom,typename _Dom::value_type>& __e)                \
  978. {                                                                       \
  979.     typedef typename _Dom::value_type _Tp;                              \
  980.     typedef _BinFunClos<_ValArray,_Expr,_Tp,_Dom> _Closure;             \
  981.     return _Expr<_Closure,_Tp>                                          \
  982.         (_Closure (__v, __e (), (_Tp(*)(_Tp, _Tp))(&_Name)));           \
  983. }                                                                       \
  984.                                                                         \
  985. template<class _Dom>                                                    \
  986. inline _Expr<_BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>, \
  987.              typename _Dom::value_type>                                 \
  988. _Name (const _Expr<_Dom, typename _Dom::value_type>& __e,               \
  989.        const typename _Dom::value_type& __t)                            \
  990. {                                                                       \
  991.     typedef typename _Dom::value_type _Tp;                              \
  992.     typedef _BinFunClos<_Expr,_Constant,_Dom,_Tp> _Closure;             \
  993.     return _Expr<_Closure,_Tp>                                          \
  994.         (_Closure (__e (), __t, (_Tp(*)(_Tp, _Tp))(&_Name)));           \
  995. }                                                                       \
  996.                                                                         \
  997. template<class _Dom>                                                    \
  998. inline _Expr<_BinFunClos<_Constant,_Expr,typename _Dom::value_type,_Dom>, \
  999.              typename _Dom::value_type>                                 \
  1000. _Name (const typename _Dom::value_type& __t,                            \
  1001.        const _Expr<_Dom,typename _Dom::value_type>& __e)                \
  1002. {                                                                       \
  1003.     typedef typename _Dom::value_type _Tp;                              \
  1004.     typedef _BinFunClos<_Constant,_Expr,_Tp,_Dom> _Closure;             \
  1005.     return _Expr<_Closure,_Tp>                                          \
  1006.         (_Closure (__t, __e (), (_Tp(*)(_Tp, _Tp))(&_Name)));           \
  1007. }                                                                       \
  1008.                                                                         \
  1009. template<typename _Tp>                                                  \
  1010. inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp>             \
  1011. _Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w)              \
  1012. {                                                                       \
  1013.     typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure;          \
  1014.     return _Expr<_Closure,_Tp>                                          \
  1015.         (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name)));               \
  1016. }                                                                       \
  1017.                                                                         \
  1018. template<typename _Tp>                                                  \
  1019. inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp>              \
  1020. _Name (const valarray<_Tp>& __v, const _Tp& __t)                        \
  1021. {                                                                       \
  1022.     typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure;          \
  1023.     return _Expr<_Closure,_Tp>                                          \
  1024.         (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name)));               \
  1025. }                                                                       \
  1026.                                                                         \
  1027. template<typename _Tp>                                                  \
  1028. inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp>              \
  1029. _Name (const _Tp& __t, const valarray<_Tp>& __v)                        \
  1030. {                                                                       \
  1031.     typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure;          \
  1032.     return _Expr<_Closure,_Tp>                                          \
  1033.         (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name)));               \
  1034. }
  1035.  
  1036. _DEFINE_EXPR_BINARY_FUNCTION(atan2)
  1037. _DEFINE_EXPR_BINARY_FUNCTION(pow)
  1038.  
  1039. #undef _DEFINE_EXPR_BINARY_FUNCTION
  1040.  
  1041. #endif // _CPP_VALARRAY_META_H 
  1042.  
  1043. // Local Variables:
  1044. // mode:c++
  1045. // End:
  1046.