metaSMT git

metaSMT/support/lazy.hpp

Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines