metaSMT git
|
00001 #pragma once 00002 00003 #include "protofy.hpp" 00004 00005 #include <boost/proto/core.hpp> 00006 #include <boost/proto/debug.hpp> 00007 #include <boost/proto/transform.hpp> 00008 #include <boost/proto/functional/fusion/at.hpp> 00009 #include <boost/fusion/container/generation/make_vector.hpp> 00010 00011 namespace metaSMT { 00012 00013 namespace detail { 00014 // implementation details 00015 00016 template <typename N> 00017 struct argument 00018 { 00019 typedef N type; 00020 enum { value = N::value }; 00021 }; 00022 00023 //template<typename O, typename N> 00024 //O& operator<< (O & out, argument<N> const & ) { 00025 // return out << "arg" << (N::value+1); 00026 //} 00027 00028 struct replace_args 00029 : proto::or_< 00030 proto::when<proto::terminal< argument<proto::_> > 00031 , boost::proto::functional::at( proto::_state, proto::_value ) 00032 > 00033 , proto::nary_expr<proto::_, proto::vararg<replace_args> > 00034 > {}; 00035 00036 00037 template <typename Context, typename Expr> 00038 struct lazy_call { 00039 00040 lazy_call(Context& ctx, Expr const & e) 00041 : ctx_( ctx ) 00042 , e_( proto::deep_copy(e) ) 00043 { } 00044 00045 template<typename Arg1> 00046 typename Context::result_type operator() ( Arg1 const & arg1) 00047 { 00048 return evaluate(ctx_, replace_args()(e_, 00049 boost::fusion::make_vector( protofy(arg1) ) 00050 )); 00051 } 00052 00053 template<typename Arg1, typename Arg2> 00054 typename Context::result_type operator() ( Arg1 const & arg1 00055 , Arg2 const & arg2 ) 00056 { 00057 return evaluate(ctx_, replace_args()(e_, 00058 boost::fusion::make_vector( protofy(arg1), protofy(arg2) ) 00059 )); 00060 } 00061 00062 template<typename Arg1, typename Arg2, typename Arg3> 00063 typename Context::result_type operator() ( Arg1 const & arg1 00064 , Arg2 const & arg2, Arg3 const & arg3 ) 00065 { 00066 return evaluate(ctx_, replace_args()(e_, 00067 boost::fusion::make_vector(protofy(arg1), protofy(arg2), protofy(arg3)) 00068 )); 00069 } 00070 00071 typename proto::result_of::deep_copy<Expr>::type e_; 00072 Context & ctx_; 00073 }; 00074 00075 } /* detail */ 00076 00106 template< typename Context, typename Expr> 00107 detail::lazy_call< Context, Expr > 00108 lazy(Context & ctx, Expr const & e) 00109 { 00110 return detail::lazy_call< Context, Expr> (ctx, e); 00111 } 00112 00116 static const detail::argument< boost::mpl::int_<0> > arg1 = {}; 00120 static const detail::argument< boost::mpl::int_<1> > arg2 = {}; 00124 static const detail::argument< boost::mpl::int_<2> > arg3 = {}; 00125 00127 } /* metaSMT */ 00128 00129