const & ex, Pairs const & ... pairs) const
DECL_AND_RETURN (OPTYPE()(eval(std::get<0>(ex.childs),pairs...),eval(std::get<1>(ex.childs),pairs...)));
};
#define AUX(z,p,unused) eval(std::get(ex.childs),pairs...)
#define IMPL(z, NN, unused) \
template struct evaluator_node_gal, Pairs...> {\
typedef _or::is_lazy... > is_lazy;\
typedef operation2 OPTYPE;\
auto operator()(expr const & ex, Pairs const & ... pairs) const\
DECL_AND_RETURN ( OPTYPE()(BOOST_PP_ENUM(NN,AUX,nil)));\
};
BOOST_PP_REPEAT_FROM_TO(3,BOOST_PP_INC(TRIQS_CLEF_MAXNARGS), IMPL, nil);
#undef AUX
#undef IMPL
template
struct evaluator, Pairs...> : evaluator_node_gal, Pairs...>{};
// The general eval function for expressions
template
auto eval (T const & ex, Pairs const &... pairs) DECL_AND_RETURN( evaluator()(ex, pairs...));
/* ---------------------------------------------------------------------------------------------------
* make_function : transform an expression to a function
* --------------------------------------------------------------------------------------------------- */
template< typename Expr, int... Is> struct make_fun_impl {
Expr ex; // keep a copy of the expression
make_fun_impl(Expr const & ex_) : ex(ex_) {}
// gcc 4.6 crashes (!!!) on the first variant
#ifndef TRIQS_COMPILER_OBSOLETE_GCC
template
auto operator()(Args &&... args) const
DECL_AND_RETURN( evaluator...>() ( ex, pair{std::forward(args)}...));
#else
template struct __eval {
typedef evaluator...> eval_t;
auto operator()(Expr const &ex , Args &&... args) const DECL_AND_RETURN( return eval_t() ( ex, pair{std::forward(args)}...));
};
template
auto operator()(Args &&... args) const DECL_AND_RETURN(return __eval() ( ex, std::forward(args)...));
#endif
};
// values of the ph, excluding the Is ...
template struct ph_filter;
template struct ph_filter { static constexpr ull_t value = ph_filter::value & (~ (1ull< struct ph_filter { static constexpr ull_t value = x; };
template< typename Expr, int... Is> struct ph_set > { static constexpr ull_t value = ph_filter ::value, Is...>::value;};
template< typename Expr, int... Is> struct is_any_lazy > : std::integral_constant>::value !=0>{};
template< typename Expr, int... Is> struct force_copy_in_expr > : std::true_type{};
template< typename Expr, typename ... Phs>
make_fun_impl::type,Phs::index...>
make_function(Expr && ex, Phs...) { return {ex}; }
namespace result_of {
template< typename Expr, typename ... Phs> struct make_function {
typedef make_fun_impl::type,Phs::index...> type;
};
}
template< typename Expr, int... Is,typename... Pairs> struct evaluator, Pairs...> {
typedef evaluator e_t;
typedef std::integral_constant >::value != ph_set::value> is_lazy;
auto operator()(make_fun_impl const & f, Pairs const & ... pairs) const DECL_AND_RETURN( make_function( e_t()(f.ex, pairs...),placeholder()...));
};
template struct ph_list {};
template ph_list var( placeholder ...) { return {};}
template
auto operator >> (ph_list, Expr const & ex) DECL_AND_RETURN( make_function(ex, placeholder()...));
/* --------------------------------------------------------------------------------------------------
* make_function
* x_ >> expression is the same as make_function(expression,x)
* --------------------------------------------------------------------------------------------------- */
template
make_fun_impl operator >> (placeholder p, Expr&& ex) { return {ex}; }
/* ---------------------------------------------------------------------------------------------------
* Auto assign for ()
* --------------------------------------------------------------------------------------------------- */
// by default it is deleted = not implemented : every class has to define it...
template void triqs_clef_auto_assign (T,F) = delete;
// remove the ref_wrapper, terminal ...
template void triqs_clef_auto_assign (std::reference_wrapper R ,F && f) { triqs_clef_auto_assign(R.get(),std::forward(f));}
template void triqs_clef_auto_assign (expr const & t,F && f) { triqs_clef_auto_assign(std::get<0>(t.childs),std::forward(f));}
// auto assign of an expr ? (for chain calls) : just reuse the same operator
template
void triqs_clef_auto_assign (expr && ex, RHS const & rhs) { ex << rhs;}
template
void triqs_clef_auto_assign (expr const & ex, RHS const & rhs) { ex << rhs;}
// The case A(x_,y_) = RHS : we form the function (make_function) and call auto_assign (by ADL)
template
void operator<<(expr...> && ex, RHS && rhs) {
triqs_clef_auto_assign(std::get<0>(ex.childs), make_function(std::forward(rhs), placeholder()...));
}
template
void operator<<(expr...> const & ex, RHS && rhs) {
triqs_clef_auto_assign(std::get<0>(ex.childs), make_function(std::forward(rhs), placeholder()...));
}
template
void operator<<(expr...> & ex, RHS && rhs) {
triqs_clef_auto_assign(std::get<0>(ex.childs), make_function(std::forward(rhs), placeholder()...));
}
// any other case e.g. f(x_+y_) = RHS etc .... which makes no sense : compiler will stop
template
void operator<<(expr && ex, RHS && rhs) = delete;
template
void operator<<(expr const & ex, RHS && rhs) = delete;
/* ---------------------------------------------------------------------------------------------------
* Auto assign for []
* --------------------------------------------------------------------------------------------------- */
// by default it is deleted = not implemented : every class has to define it...
template void triqs_clef_auto_assign_subscript (T,F) = delete;
// remove the ref_wrapper, terminal ...
template void triqs_clef_auto_assign_subscript (std::reference_wrapper R ,F && f)
{ triqs_clef_auto_assign_subscript(R.get(),std::forward(f));}
template void triqs_clef_auto_assign_subscript (expr const & t,F && f)
{ triqs_clef_auto_assign_subscript(std::get<0>(t.childs),std::forward(f));}
// auto assign of an expr ? (for chain calls) : just reuse the same operator
template
void triqs_clef_auto_assign_subscript (expr && ex, RHS const & rhs) { ex << rhs;}
template
void triqs_clef_auto_assign_subscript (expr const & ex, RHS const & rhs) { ex << rhs;}
// Same thing for the [ ]
template
void operator<<(expr...> const & ex, RHS && rhs) {
triqs_clef_auto_assign_subscript(std::get<0>(ex.childs), make_function(std::forward(rhs), placeholder()...));
}
template