Boost logo

Proto :

Subject: [proto] How to customize an expression in an EDSL , so as to make a deep copy of it?
From: 伊藤 (itoh.masakatsu_at_[hidden])
Date: 2015-12-14 06:47:54


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.

But when I try to make a deep copy of the operator part
( MyEDSL::opr ) of that formula,

     auto copyOfOperator = proto::deep_copy( MyEDSL::opr );

g++ 4.8.4 issued lots of compilation error messages.

Those error messages and all of my source code are
attached below.

Probably I missed something important to customize the expression
in my EDSL, but still cannot find out what it is. So could anybody
please look into my source and give me some advice or hint ?

Or could anybody please tell me about any detailed programming
guide for Boost.Proto? I've read through Users Guide and
"Expressive C++" article series #1 - #8, but still cannot complete
my first EDSL .

Many thanks and best regards,
Masa

Masakatsu ITO

-------------------- beginning of my source code ------------------------

#include <iostream>
#include <boost/proto/proto.hpp>

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

namespace MyEDSL {

     struct DifferenceOperator;

     struct ExprGrammar : proto::or_<
         proto::terminal< DifferenceOperator >
> {};

     // 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 >
     {

         explicit ExprWrapper(const ExprType& e)
             : proto::extends<ExprType, ExprWrapper<ExprType>, Domain>(e)
         {}
     };

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

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

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

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

     static struct DifferenceOperator opr = {};

     // 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)
}

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

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

     return 0;
}

-------------------- end of my source code ------------------------

-------------------- beginning of compilation error messages ----------

$ g++ -std=c++11 protoDeepCopyUserDefinedExpr.cpp
In file included from /home/mito/usrLocal/include/boost/proto/core.hpp:27:0,
                  from /home/mito/usrLocal/include/boost/proto/proto.hpp:12,
                  from protoDeepCopyUserDefinedExpr.cpp:9:
/home/mito/usrLocal/include/boost/proto/deep_copy.hpp: In instantiation of 'struct boost::proto::result_of::deep_copy<MyEDSL::DifferenceOperator>':
/home/mito/usrLocal/include/boost/proto/deep_copy.hpp:128:5: required by substitution of 'template<class Expr> typename boost::proto::result_of::deep_copy<Expr>::type boost::proto::deep_copy(const Expr&) [with Expr = MyEDSL::DifferenceOperator]'
protoDeepCopyUserDefinedExpr.cpp:82:54: required from here
/home/mito/usrLocal/include/boost/proto/deep_copy.hpp:67:13: error: 'proto_arity_c' is not a member of 'boost::proto::detail::uncvref<MyEDSL::DifferenceOperator>::type {aka MyEDSL::DifferenceOperator}'
              type;
              ^
protoDeepCopyUserDefinedExpr.cpp: In function 'int main()':
protoDeepCopyUserDefinedExpr.cpp:82:54: error: no matching function for call to 'deep_copy(MyEDSL::DifferenceOperator&)'
   auto copyOfOperator = proto::deep_copy( MyEDSL::opr );
                                                       ^
protoDeepCopyUserDefinedExpr.cpp:82:54: note: candidate is:
In file included from /home/mito/usrLocal/include/boost/proto/core.hpp:27:0,
                  from /home/mito/usrLocal/include/boost/proto/proto.hpp:12,
                  from protoDeepCopyUserDefinedExpr.cpp:9:
/home/mito/usrLocal/include/boost/proto/deep_copy.hpp:128:5: note: template<class Expr> typename boost::proto::result_of::deep_copy<Expr>::type boost::proto::deep_copy(const Expr&)
      deep_copy(Expr const &e)
      ^
/home/mito/usrLocal/include/boost/proto/deep_copy.hpp:128:5: note: substitution of deduced template arguments resulted in errors seen above

-------------------- end of compilation error messages ----------


Proto list run by eric at boostpro.com