Hi Masa,

The problem is that you were not really building a proto expression, but
just calling your DifferenceOperator directly. You can create a proper
proto terminal in your domain using:
ExprWrapper<boost::proto::terminal<DifferenceOperator>::type> const opr =
{{}};

Once that is done, only the deep copy compiles, but you need a proper
grammar for evaluation to work, and a << overload for printing and starting
evaluation. The fixed code with a small start of the grammar is attached.

p.s. It's awfully quiet on this list, is it still the place to discuss
Proto?

Cheers,

Bart

On Mon, Dec 14, 2015 at 12:48 PM Masakatsu ITO(伊藤) <itoh.masaka...@jaxa.jp>
wrote:

> Hello,
>
> I'm trying to make an EDSL for finite volume method,
> which translates a formula of the method into
> executable code.
>
> Now I've confirmed that such a formula
>
>      std::cout << MyEDSL::opr( 0.1, 0.1) + 1.0 << std::endl;
>
> can be compiled and prints out the correct answer.
>
>
#include <iostream>
#include <boost/proto/proto.hpp>


namespace mpl = boost::mpl;
namespace proto = boost::proto;

namespace MyEDSL {

     // A user defined expression
     struct DifferenceOperator : proto::callable
     {
         typedef double result_type;
         template <typename Sig> struct result;

         template < typename This, typename T >
         struct result< This(T, T) > { typedef double type; };

         DifferenceOperator() {}
         DifferenceOperator( const DifferenceOperator & expr) {}

         double operator()( double dx1, double dx2) const {
             return ( 1.0 /dx1 + 1.0 /dx2 );
         }
     };

     struct ExprGrammar : proto::or_<
         proto::when<proto::function<proto::terminal< DifferenceOperator >, proto::_, proto::_>,
         DifferenceOperator(proto::_value(proto::_child1), proto::_value(proto::_child2))>
     > {};

     // A wrapper for a user defined expression
     template< typename E > struct ExprWrapper;

     // The above grammar is associated with this domain.
     struct Domain
         : proto::domain< proto::generator< ExprWrapper >, ExprGrammar >
     {};

     // A wrapper template for a user defined expression
     template< typename ExprType >
     struct ExprWrapper
         : proto::extends< ExprType, ExprWrapper< ExprType >, Domain >
     {

         ExprWrapper(const ExprType& e)
             : proto::extends<ExprType, ExprWrapper<ExprType>, Domain>(e)
         {}
         
         friend std::ostream &operator <<(std::ostream &sout, ExprWrapper<ExprType> const &expr)
        {
            return std::cout << ExprGrammar()(expr);
        }
     };
     
     // Define a trait for detecting linear algebraic terminals, to be used
     // by the BOOST_PROTO_DEFINE_OPERATORS macro below.
     template<typename> struct IsExpr  : mpl::false_ {};

     template<> struct IsExpr< DifferenceOperator > : mpl::true_  {};

     // This defines all the overloads to make expressions involving
     // Vector and Matrix objects to build Proto's expression templates.
     BOOST_PROTO_DEFINE_OPERATORS(IsExpr, Domain)
     
     ExprWrapper<boost::proto::terminal<DifferenceOperator>::type> const opr = {{}};
}


int main() {
     // This worked well.
     std::cout << MyEDSL::opr( 0.1, 0.1) << std::endl;

     // But this cannot be compiled.
     auto copyOfOperator = proto::deep_copy( MyEDSL::opr );

     return 0;
}
_______________________________________________
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto

Reply via email to