Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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