3
0
mirror of https://github.com/triqs/dft_tools synced 2024-12-26 06:14:14 +01:00

clef : add apply_on_each_leaf

- apply_on_each_leaf: apply a function object to every leaf of the tree
- add some macros...
This commit is contained in:
Olivier Parcollet 2014-02-10 20:19:36 +01:00
parent 786bd7095e
commit e182762bf2
2 changed files with 32 additions and 4 deletions

View File

@ -23,6 +23,8 @@
#include <triqs/utility/first_include.hpp> #include <triqs/utility/first_include.hpp>
#include <triqs/utility/macros.hpp> #include <triqs/utility/macros.hpp>
#include <triqs/utility/compiler_details.hpp> #include <triqs/utility/compiler_details.hpp>
#include <triqs/utility/tuple_tools.hpp>
#include <triqs/utility/c14.hpp>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
#include <functional> #include <functional>
@ -318,10 +320,29 @@ namespace triqs { namespace clef {
struct evaluator<expr<Tag, Childs...>, Pairs...> : evaluator_node_gal<sizeof...(Childs), expr<Tag, Childs...>, Pairs...>{}; struct evaluator<expr<Tag, Childs...>, Pairs...> : evaluator_node_gal<sizeof...(Childs), expr<Tag, Childs...>, Pairs...>{};
#endif #endif
// The general eval function for expressions // The general eval function for expressions
template<typename T, typename... Pairs> template <typename T, typename... Pairs>
auto eval (T const & ex, Pairs const &... pairs) DECL_AND_RETURN( evaluator<T, Pairs...>()(ex, pairs...)); auto eval(T const& ex, Pairs const&... pairs) DECL_AND_RETURN(evaluator<T, Pairs...>()(ex, pairs...));
/* ---------------------------------------------------------------------------------------------------
* Apply a function object to all the leaves of the expression tree
* --------------------------------------------------------------------------------------------------- */
template <typename F> struct apply_on_each_leaf_impl {
F f;
template <typename T> std::c14::enable_if_t<is_clef_expression<T>::value> operator()(T const& ex) {
tuple::for_each(ex.childs, *this);
}
template <typename T> std::c14::enable_if_t<!is_clef_expression<T>::value> operator()(T const& x) { f(x); }
template <typename T> std::c14::enable_if_t<!is_clef_expression<T>::value> operator()(std::reference_wrapper<T> const& x) {
f(x.get());
}
};
template <typename F, typename Expr> void apply_on_each_leaf(F&& f, Expr const& ex) {
auto impl = apply_on_each_leaf_impl<F>{std::forward<F>(f)};
impl(ex);
}
/* --------------------------------------------------------------------------------------------------- /* ---------------------------------------------------------------------------------------------------
* make_function : transform an expression to a function * make_function : transform an expression to a function
@ -536,6 +557,12 @@ namespace triqs { namespace clef {
template <typename... A> auto name(A&&... a) DECL_AND_RETURN(make_expr_call(name##_lazy_impl(), std::forward<A>(a)...)); \ template <typename... A> auto name(A&&... a) DECL_AND_RETURN(make_expr_call(name##_lazy_impl(), std::forward<A>(a)...)); \
template <typename... A> auto name##_lazy_impl::operator()(A&&... a) const DECL_AND_RETURN(name(std::forward<A>(a)...)); template <typename... A> auto name##_lazy_impl::operator()(A&&... a) const DECL_AND_RETURN(name(std::forward<A>(a)...));
#define TRIQS_CLEF_EXTEND_FNT_LAZY(FUN, TRAIT) \
template <typename A> \
std::c14::enable_if_t<TRAIT<A>::value, clef::expr_node_t<clef::tags::function, clef::FUN##_lazy_impl, A>> FUN(A&& a) { \
return {clef::tags::function{}, clef::FUN##_lazy_impl{}, std::forward<A>(a)}; \
}
#define TRIQS_CLEF_IMPLEMENT_LAZY_METHOD(TY, name) \ #define TRIQS_CLEF_IMPLEMENT_LAZY_METHOD(TY, name) \
struct __clef_lazy_method_impl_##name { \ struct __clef_lazy_method_impl_##name { \
TY* _x; \ TY* _x; \

View File

@ -23,6 +23,7 @@
#include <functional> #include <functional>
#include <tuple> #include <tuple>
#include "./macros.hpp" #include "./macros.hpp"
#include "./tuple_tools.hpp"
// a few that will be C++14, use in advance.... // a few that will be C++14, use in advance....