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

Revert a wrong fix in expression template for gf

This reverts the part of the commit 1906dc30a5
which introduced modifications in the expr templates of the Green's
functions. The commit had introduced some bugs and this revert
removes them (the expr templates will be taken care of fully in later
commits). This is a temporary fix for issues #18 and #25.

  reverted:   triqs/gfs/data_proxies.hpp
  reverted:   triqs/gfs/gf.hpp
  reverted:   triqs/gfs/gf_expr.hpp
This commit is contained in:
Michel Ferrero 2013-10-16 23:48:14 +02:00
parent 44bd729252
commit f4444f3b49
3 changed files with 120 additions and 78 deletions

View File

@ -42,7 +42,9 @@ namespace triqs { namespace gfs {
arrays::matrix_view_proxy<storage_view_t,0> operator()(storage_view_t & data, size_t i) const { return arrays::matrix_view_proxy<storage_view_t,0>(data,i); } arrays::matrix_view_proxy<storage_view_t,0> operator()(storage_view_t & data, size_t i) const { return arrays::matrix_view_proxy<storage_view_t,0>(data,i); }
arrays::const_matrix_view_proxy<storage_view_t,0> operator()(storage_view_t const & data, size_t i) const { return arrays::const_matrix_view_proxy<storage_view_t,0>(data,i); } arrays::const_matrix_view_proxy<storage_view_t,0> operator()(storage_view_t const & data, size_t i) const { return arrays::const_matrix_view_proxy<storage_view_t,0>(data,i); }
template<typename S, typename RHS> static void assign_no_resize (S & data, RHS && rhs) { data() = std::forward<RHS>(rhs);}
template<typename S, typename RHS> static void assign_to_scalar (S & data, RHS && rhs) { data() = std::forward<RHS>(rhs);} template<typename S, typename RHS> static void assign_to_scalar (S & data, RHS && rhs) { data() = std::forward<RHS>(rhs);}
template<typename RHS> static void assign_with_resize (storage_t & data, RHS && rhs) { data = std::forward<RHS>(rhs);}
template<typename RHS> static void rebind (storage_view_t & data, RHS && rhs) { data.rebind(rhs.data()); } template<typename RHS> static void rebind (storage_view_t & data, RHS && rhs) { data.rebind(rhs.data()); }
}; };
@ -59,7 +61,9 @@ namespace triqs { namespace gfs {
auto operator()(storage_view_t & data,size_t i) const -> decltype(data(i)) { return data(i);} auto operator()(storage_view_t & data,size_t i) const -> decltype(data(i)) { return data(i);}
auto operator()(storage_view_t const & data,size_t i) const -> decltype(data(i)) { return data(i);} auto operator()(storage_view_t const & data,size_t i) const -> decltype(data(i)) { return data(i);}
template<typename S, typename RHS> static void assign_no_resize (S & data, RHS && rhs) { data() = std::forward<RHS>(rhs);}
template<typename S, typename RHS> static void assign_to_scalar (S & data, RHS && rhs) { data() = std::forward<RHS>(rhs);} template<typename S, typename RHS> static void assign_to_scalar (S & data, RHS && rhs) { data() = std::forward<RHS>(rhs);}
template<typename RHS> static void assign_with_resize (storage_t & data, RHS && rhs) { data = std::forward<RHS>(rhs);}
template<typename RHS> static void rebind (storage_view_t & data, RHS && rhs) { data.rebind(rhs.data()); } template<typename RHS> static void rebind (storage_view_t & data, RHS && rhs) { data.rebind(rhs.data()); }
}; };
@ -78,6 +82,12 @@ namespace triqs { namespace gfs {
Tv & operator()(storage_view_t & data, size_t i) { return data[i];} Tv & operator()(storage_view_t & data, size_t i) { return data[i];}
Tv const & operator()(storage_view_t const & data, size_t i) const { return data[i];} Tv const & operator()(storage_view_t const & data, size_t i) const { return data[i];}
template<typename S, typename RHS> static void assign_no_resize (S & data, RHS && rhs) {
//auto r = make_vector(rhs);
if (data.size() !=rhs.size()) TRIQS_RUNTIME_ERROR << "Size mismatch in gf assignment";
for (size_t i =0; i<data.size(); ++i) data[i] = rhs[i];
}
template<typename S, typename RHS> static void assign_with_resize (S & data, RHS && rhs) {data = utility::factory<storage_t>(rhs);}
template<typename S, typename RHS> static void assign_to_scalar (S & data, RHS && rhs) {for (size_t i =0; i<data.size(); ++i) data[i] = rhs;} template<typename S, typename RHS> static void assign_to_scalar (S & data, RHS && rhs) {for (size_t i =0; i<data.size(); ++i) data[i] = rhs;}
template<typename RHS> static void rebind (storage_view_t & data, RHS && rhs) { data.clear(); for (auto & x : rhs.data()) data.push_back(x);} template<typename RHS> static void rebind (storage_view_t & data, RHS && rhs) { data.clear(); for (auto & x : rhs.data()) data.push_back(x);}
}; };
@ -94,6 +104,8 @@ namespace triqs { namespace gfs {
auto operator()(storage_t & data, size_t i) DECL_AND_RETURN( data(i)); auto operator()(storage_t & data, size_t i) DECL_AND_RETURN( data(i));
auto operator()(storage_t const & data, size_t i) const DECL_AND_RETURN( data(i)); auto operator()(storage_t const & data, size_t i) const DECL_AND_RETURN( data(i));
template<typename S, typename RHS> static void assign_no_resize (S & data, RHS && rhs) { data() = std::forward<RHS>(rhs);}
template<typename S, typename RHS> static void assign_with_resize (S & data, RHS && rhs) = delete;
template<typename S, typename RHS> static void assign_to_scalar (S & data, RHS && rhs) = delete; template<typename S, typename RHS> static void assign_to_scalar (S & data, RHS && rhs) = delete;
template<typename RHS> static void rebind (storage_view_t & data, RHS && rhs) = delete;// { data = std::forward<RHS>(rhs);} template<typename RHS> static void rebind (storage_view_t & data, RHS && rhs) = delete;// { data = std::forward<RHS>(rhs);}
}; };

View File

@ -33,6 +33,7 @@ namespace triqs { namespace gfs {
using utility::factory; using utility::factory;
using arrays::make_shape; using arrays::make_shape;
// GENERALISE matrxi TO DEFAULT
template<typename Variable, typename Opt=void> struct gf_mesh; template<typename Variable, typename Opt=void> struct gf_mesh;
template<typename Variable, typename Target=matrix_valued, typename Opt=void> class gf; // the regular type template<typename Variable, typename Target=matrix_valued, typename Opt=void> class gf; // the regular type
template<typename Variable, typename Target=matrix_valued, typename Opt=void> class gf_view; // the view type template<typename Variable, typename Target=matrix_valued, typename Opt=void> class gf_view; // the view type
@ -40,7 +41,7 @@ namespace triqs { namespace gfs {
// various implementation traits // various implementation traits
namespace gfs_implementation { // never use using of this... namespace gfs_implementation { // never use using of this...
// evaluator regroup functions to evaluate the function. // evaluator regroup functions to evaluate the function. Cf descriptors
template<typename Variable, typename Target, typename Opt> struct evaluator{ static constexpr int arity = 0;}; template<typename Variable, typename Target, typename Opt> struct evaluator{ static constexpr int arity = 0;};
// closest_point mechanism // closest_point mechanism
@ -59,7 +60,7 @@ namespace triqs { namespace gfs {
// this is used to specialize this part of the code to array of dim 3 (matrix gf), dim 1 (scalar gf) and vector (e.g. block gf, ...) // this is used to specialize this part of the code to array of dim 3 (matrix gf), dim 1 (scalar gf) and vector (e.g. block gf, ...)
template<typename Variable, typename Target, typename Opt, typename Enable = void> struct data_proxy; template<typename Variable, typename Target, typename Opt, typename Enable = void> struct data_proxy;
// This trait contains functions to read/write in hdf5 files. Can be specialized for some case (Cf block) // This trait contains functions to read/write in hdf5 files. Can be specialized for some descriptor (Cf block)
template <typename Variable, typename Target, typename Opt> struct h5_name; // value is a const char * template <typename Variable, typename Target, typename Opt> struct h5_name; // value is a const char *
template<typename Variable, typename Opt> struct h5_name<Variable,scalar_valued,Opt> { static std::string invoke(){ return h5_name<Variable,matrix_valued,Opt>::invoke() + "_s";}}; template<typename Variable, typename Opt> struct h5_name<Variable,scalar_valued,Opt> { static std::string invoke(){ return h5_name<Variable,matrix_valued,Opt>::invoke() + "_s";}};
@ -82,6 +83,9 @@ namespace triqs { namespace gfs {
template <typename Variable, typename Target=matrix_valued, typename Opt=void, typename ... U> template <typename Variable, typename Target=matrix_valued, typename Opt=void, typename ... U>
gf_view<Variable,Target,Opt> make_gf_view(U && ... x) { return gfs_implementation::factories<Variable,Target,Opt>::make_gf_view(std::forward<U>(x)...);} gf_view<Variable,Target,Opt> make_gf_view(U && ... x) { return gfs_implementation::factories<Variable,Target,Opt>::make_gf_view(std::forward<U>(x)...);}
template<typename Variable, typename Target, typename Opt> struct gf_desc{};
template<typename Descriptor> struct gf_tag{};
// The trait that "marks" the Green function // The trait that "marks" the Green function
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT(ImmutableGreenFunction); TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT(ImmutableGreenFunction);
@ -89,13 +93,16 @@ namespace triqs { namespace gfs {
/// A common implementation class for gf and gf_view. They will only redefine contructor and = ... /// A common implementation class for gf and gf_view. They will only redefine contructor and = ...
template<typename Variable, typename Target, typename Opt, bool IsView> class gf_impl : template<typename Variable, typename Target, typename Opt, bool IsView> class gf_impl :
TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction){ TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction), gf_tag<gf_desc<Variable,Target,Opt>> {
public : public :
// Pattern : ValueView
typedef gf_view<Variable,Target,Opt> view_type; typedef gf_view<Variable,Target,Opt> view_type;
typedef gf<Variable,Target,Opt> regular_type; typedef gf<Variable,Target,Opt> regular_type;
typedef gf_desc<Variable,Target,Opt> descriptor_t;
typedef Variable variable_t; typedef Variable variable_t;
typedef Target target_t;
typedef Opt option_t; typedef Opt option_t;
typedef gf_mesh<Variable,Opt> mesh_t; typedef gf_mesh<Variable,Opt> mesh_t;
@ -178,6 +185,13 @@ namespace triqs { namespace gfs {
>::type // end of add_Const >::type // end of add_Const
operator() (Arg0&& arg0, Args&&... args) const { return _evaluator(this,std::forward<Arg0>( arg0), std::forward<Args>(args)...); } operator() (Arg0&& arg0, Args&&... args) const { return _evaluator(this,std::forward<Arg0>( arg0), std::forward<Args>(args)...); }
// Interaction with the CLEF library : calling the gf with any clef expression as argument build a new clef expression
//template<typename Arg0, typename ...Args>
// auto operator()(Arg0 arg0, Args... args) const DECL_AND_RETURN( clef::make_expr_call(view_type(*this),arg0, args...));
//template<typename Arg0, typename ...Args>
// auto operator()(Arg0 arg0, Args... args) DECL_AND_RETURN( clef::make_expr_call(view_type(*this),arg0, args...));
template<typename Arg0, typename ...Args> template<typename Arg0, typename ...Args>
typename clef::_result_of::make_expr_call<view_type,Arg0, Args...>::type typename clef::_result_of::make_expr_call<view_type,Arg0, Args...>::type
operator()(Arg0 arg0, Args... args) const { operator()(Arg0 arg0, Args... args) const {
@ -213,14 +227,34 @@ namespace triqs { namespace gfs {
template<typename ... U> template<typename ... U>
cr_type operator[] (closest_pt_wrap<U...> const & p) const { return _data_proxy(_data, _mesh.index_to_linear( gfs_implementation::get_closest_point<Variable,Target,Opt>::invoke(this,p)));} cr_type operator[] (closest_pt_wrap<U...> const & p) const { return _data_proxy(_data, _mesh.index_to_linear( gfs_implementation::get_closest_point<Variable,Target,Opt>::invoke(this,p)));}
// Interaction with the CLEF library : calling the gf with any clef expression as argument build a new clef expression
/* template<typename Arg>
typename boost::lazy_enable_if< // enable the template if
clef::is_any_lazy<Arg>, // One of Args is a lazy expression
clef::_result_of::make_expr_subscript<view_type,Arg>
>::type // end of lazy_enable_if
operator[](Arg && arg) const { return clef::make_expr_subscript(view_type(*this),std::forward<Arg>(arg));}
*/
/*template<typename Arg>
//auto operator[](Arg && arg) const DECL_AND_RETURN(clef::make_expr_subscript((*this)(),std::forward<Arg>(arg)));
auto operator[](Arg && arg) const DECL_AND_RETURN(clef::make_expr_subscript(view_type(*this),std::forward<Arg>(arg)));
template<typename Arg>
//auto operator[](Arg && arg) DECL_AND_RETURN(clef::make_expr_subscript((*this)(),std::forward<Arg>(arg)));
auto operator[](Arg && arg) DECL_AND_RETURN(clef::make_expr_subscript(view_type(*this),std::forward<Arg>(arg)));
*/
template<typename Arg> template<typename Arg>
typename clef::_result_of::make_expr_subscript<view_type,Arg>::type typename clef::_result_of::make_expr_subscript<view_type,Arg>::type
operator[](Arg && arg) const { return clef::make_expr_subscript(view_type(*this),std::forward<Arg>(arg));} operator[](Arg && arg) const { return clef::make_expr_subscript(view_type(*this),std::forward<Arg>(arg));}
/// A direct access to the grid point /// A direct access to the grid point
template<typename... Args> template<typename... Args>
r_type on_mesh (Args&&... args) { return _data_proxy(_data,_mesh.index_to_linear(mesh_index_t(std::forward<Args>(args)...)));} r_type on_mesh (Args&&... args) { return _data_proxy(_data,_mesh.index_to_linear(mesh_index_t(std::forward<Args>(args)...)));}
/// A direct access to the grid point (const version)
template<typename... Args> template<typename... Args>
cr_type on_mesh (Args&&... args) const { return _data_proxy(_data,_mesh.index_to_linear(mesh_index_t(std::forward<Args>(args)...)));} cr_type on_mesh (Args&&... args) const { return _data_proxy(_data,_mesh.index_to_linear(mesh_index_t(std::forward<Args>(args)...)));}
@ -245,7 +279,7 @@ namespace triqs { namespace gfs {
friend void h5_write (h5::group fg, std::string subgroup_name, gf_impl const & g) { friend void h5_write (h5::group fg, std::string subgroup_name, gf_impl const & g) {
auto gr = fg.create_group(subgroup_name); auto gr = fg.create_group(subgroup_name);
gr.write_triqs_hdf5_data_scheme(g); gr.write_triqs_hdf5_data_scheme(g);
gfs_implementation::h5_ops<Variable,Target,Opt>::write(gr, "data", g._data, g); gfs_implementation::h5_ops<Variable,Target,Opt>::write(gr, "data", g._data, g);//can be specialized for some descriptors (E.g. blocks)
h5_write(gr,"singularity",g._singularity); h5_write(gr,"singularity",g._singularity);
h5_write(gr,"mesh",g._mesh); h5_write(gr,"mesh",g._mesh);
h5_write(gr,"symmetry",g._symmetry); h5_write(gr,"symmetry",g._symmetry);
@ -259,7 +293,7 @@ namespace triqs { namespace gfs {
auto tag_expected= get_triqs_hdf5_data_scheme(g); auto tag_expected= get_triqs_hdf5_data_scheme(g);
if (tag_file != tag_expected) if (tag_file != tag_expected)
TRIQS_RUNTIME_ERROR<< "h5_read : mismatch of the tag TRIQS_HDF5_data_scheme tag in the h5 group : found "<<tag_file << " while I expected "<< tag_expected; TRIQS_RUNTIME_ERROR<< "h5_read : mismatch of the tag TRIQS_HDF5_data_scheme tag in the h5 group : found "<<tag_file << " while I expected "<< tag_expected;
gfs_implementation::h5_ops<Variable,Target,Opt>::read(gr, "data", g._data, g); gfs_implementation::h5_ops<Variable,Target,Opt>::read(gr, "data", g._data, g);//can be specialized for some descriptors (E.g. blocks)
h5_read(gr,"singularity",g._singularity); h5_read(gr,"singularity",g._singularity);
h5_read(gr,"mesh",g._mesh); h5_read(gr,"mesh",g._mesh);
h5_read(gr,"symmetry",g._symmetry); h5_read(gr,"symmetry",g._symmetry);
@ -305,11 +339,11 @@ namespace triqs { namespace gfs {
gf & operator = (gf const & rhs) { *this = gf(rhs); return *this;} // use move = gf & operator = (gf const & rhs) { *this = gf(rhs); return *this;} // use move =
gf & operator = (gf & rhs) { *this = gf(rhs); return *this;} // use move = gf & operator = (gf & rhs) { *this = gf(rhs); return *this;} // use move =
gf & operator = (gf && rhs) noexcept { swap(*this,rhs); return *this;} gf & operator = (gf && rhs) noexcept { swap(*this, rhs); return *this;}
template<typename RHS> void operator = (RHS && rhs) { template<typename RHS> void operator = (RHS && rhs) {
this->_mesh = std::forward<RHS>(rhs).mesh(); this->_mesh = rhs.mesh();
for (auto const & w: this->mesh()) (*this)[w] = rhs[w]; B::data_proxy_t::assign_with_resize(this->data(), std::forward<RHS>(rhs).data()); // looks strange for &&
this->_singularity = rhs.singularity(); this->_singularity = rhs.singularity();
// to be implemented : there is none in the gf_expr in particular.... // to be implemented : there is none in the gf_expr in particular....
//this->_symmetry = rhs.symmetry(); //this->_symmetry = rhs.symmetry();
@ -372,7 +406,7 @@ namespace triqs { namespace gfs {
template<typename Variable, typename Target, typename Opt, typename RHS> template<typename Variable, typename Target, typename Opt, typename RHS>
DISABLE_IF(arrays::is_scalar<RHS>) triqs_gf_view_assign_delegation( gf_view<Variable,Target,Opt> g, RHS const & rhs) { DISABLE_IF(arrays::is_scalar<RHS>) triqs_gf_view_assign_delegation( gf_view<Variable,Target,Opt> g, RHS const & rhs) {
if (!(g.mesh() == rhs.mesh())) TRIQS_RUNTIME_ERROR<<"Gf Assignment in View : incompatible mesh"; if (!(g.mesh() == rhs.mesh())) TRIQS_RUNTIME_ERROR<<"Gf Assignment in View : incompatible mesh";
for (auto const & w: g.mesh()) g[w] = rhs[w]; gf_view<Variable,Target,Opt>::data_proxy_t::assign_no_resize(g.data(),rhs.data());
g.singularity() = rhs.singularity(); g.singularity() = rhs.singularity();
} }

View File

@ -22,61 +22,47 @@
#define TRIQS_GF_EXPR_H #define TRIQS_GF_EXPR_H
#include <triqs/utility/expression_template_tools.hpp> #include <triqs/utility/expression_template_tools.hpp>
namespace triqs { namespace gfs { namespace triqs { namespace gfs {
using utility::is_in_ZRC; using utility::is_in_ZRC;
using utility::remove_rvalue_ref;
namespace gfs_expr_tools { namespace gfs_expr_tools {
// a wrapper for scalars
template<typename S> struct scalar_wrap { template<typename S> struct scalar_wrap {
typedef void variable_t; typedef S value_type;
typedef void target_t; S s; scalar_wrap(S const &s_):s(s_){}
typedef void option_t;
S s;
template<typename T> scalar_wrap(T && x):s(std::forward<T>(x)){}
S singularity() const { return s;} S singularity() const { return s;}
template<typename KeyType> S operator[](KeyType && key) const { return s;} S data() const { return s;}
template<typename ... Args> inline S operator()(Args && ... args) const { return s;} template<typename KeyType> value_type operator[](KeyType && key) const { return s;}
template<typename ... Args> inline value_type operator()(Args && ... args) const { return s;}
friend std::ostream &operator <<(std::ostream &sout, scalar_wrap const &expr){return sout << expr.s; } friend std::ostream &operator <<(std::ostream &sout, scalar_wrap const &expr){return sout << expr.s; }
}; };
// Combine the two meshes of LHS and RHS : need to specialize where there is a scalar // Combine the two meshes of LHS and RHS : need to specialize where there is a scalar
struct combine_mesh { struct combine_mesh {
template<typename L, typename R> template<typename L, typename R>
auto operator() (L && l, R && r) const -> decltype(std::forward<L>(l).mesh()) { inline auto operator() (L const & l, R const & r) const -> decltype(l.mesh()) {
if (!(l.mesh() == r.mesh())) TRIQS_RUNTIME_ERROR << "Mesh mismatch : ";//<< l.mesh()<<" vs" <<r.mesh(); if (!(l.mesh() == r.mesh())) TRIQS_RUNTIME_ERROR << "Mesh mismatch : ";//<< l.mesh()<<" vs" <<r.mesh();
return std::forward<L>(l).mesh(); return l.mesh();
} }
template<typename S, typename R> auto operator() (scalar_wrap<S> const &, R && r) const DECL_AND_RETURN(std::forward<R>(r).mesh()); template<typename S, typename R> auto operator() (scalar_wrap<S> const & w, R const & r) const -> decltype(r.mesh()) { return r.mesh();}
template<typename S, typename L> auto operator() (L && l, scalar_wrap<S> const &) const DECL_AND_RETURN(std::forward<L>(l).mesh()); template<typename S, typename L> auto operator() (L const & l, scalar_wrap<S> const & w) const -> decltype(l.mesh()) { return l.mesh();}
}; };
template<typename T> struct node_t : std::conditional<utility::is_in_ZRC<T>::value, scalar_wrap<T>, typename remove_rvalue_ref<T>::type> {}; template<typename T> struct keeper_type : std::conditional<utility::is_in_ZRC<T>::value, scalar_wrap<T>, typename view_type_if_exists_else_type<T>::type> {};
template <typename A, typename B> struct _or_ {typedef void type;};
template <typename A> struct _or_<A,A> {typedef A type;};
template <typename A> struct _or_<void,A> {typedef A type;};
template <typename A> struct _or_<A,void> {typedef A type;};
template <> struct _or_<void,void> {typedef void type;};
}// gfs_expr_tools }// gfs_expr_tools
template<typename Tag, typename L, typename R> struct gf_expr : TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction){ template<typename Descriptor, typename Tag, typename L, typename R> struct gf_expr : TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction),gf_tag<Descriptor> {
typedef typename std::remove_reference<L>::type L_t; typedef typename gfs_expr_tools::keeper_type<L>::type L_t;
typedef typename std::remove_reference<R>::type R_t; typedef typename gfs_expr_tools::keeper_type<R>::type R_t;
typedef typename gfs_expr_tools::_or_<typename L_t::variable_t,typename R_t::variable_t>::type variable_t; typedef Descriptor descriptor_t;
typedef typename gfs_expr_tools::_or_<typename L_t::target_t,typename R_t::target_t>::type target_t; //typedef typename std::result_of<utility::operation<Tag>(typename L_t::value_type,typename R_t::value_type)>::type value_t;
typedef typename gfs_expr_tools::_or_<typename L_t::option_t,typename R_t::option_t>::type option_t; typedef typename std::remove_reference<typename std::result_of<gfs_expr_tools::combine_mesh(L_t,R_t)>::type>::type mesh_t;
static_assert(!std::is_same<variable_t,void>::value, "Can not combine two gf expressions with different variables"); //typedef typename Descriptor::singularity_t::view_type singularity_view_t;
static_assert(!std::is_same<target_t,void>::value, "Can not combine two gf expressions with different target"); //typedef value_t value_type;
L_t l; R_t r;
L l; R r; template<typename LL, typename RR> gf_expr(LL && l_, RR && r_) : l(std::forward<LL>(l_)), r(std::forward<RR>(r_)) {}
template<typename LL, typename RR> gf_expr(LL && l_, RR && r_):l(std::forward<LL>(l_)), r(std::forward<RR>(r_)) {} mesh_t mesh() const { return gfs_expr_tools::combine_mesh()(l,r); }
auto data() const ->decltype( utility::operation<Tag>()(l.data(), r.data())) { return utility::operation<Tag>()(l.data(), r.data());}
auto mesh() const DECL_AND_RETURN(gfs_expr_tools::combine_mesh()(l,r));
auto singularity() const DECL_AND_RETURN (utility::operation<Tag>()(l.singularity() , r.singularity())); auto singularity() const DECL_AND_RETURN (utility::operation<Tag>()(l.singularity() , r.singularity()));
//const singularity_view_t singularity() const { return utility::operation<Tag>()(l.singularity() , r.singularity());}
//symmetry_t const & symmetry() const { return _symmetry;}
template<typename KeyType> auto operator[](KeyType && key) const DECL_AND_RETURN(utility::operation<Tag>()(l[std::forward<KeyType>(key)] , r[std::forward<KeyType>(key)])); template<typename KeyType> auto operator[](KeyType && key) const DECL_AND_RETURN(utility::operation<Tag>()(l[std::forward<KeyType>(key)] , r[std::forward<KeyType>(key)]));
template<typename ... Args> auto operator()(Args && ... args) const DECL_AND_RETURN(utility::operation<Tag>()(l(std::forward<Args>(args)...) , r(std::forward<Args>(args)...))); template<typename ... Args> auto operator()(Args && ... args) const DECL_AND_RETURN(utility::operation<Tag>()(l(std::forward<Args>(args)...) , r(std::forward<Args>(args)...)));
friend std::ostream &operator <<(std::ostream &sout, gf_expr const &expr){return sout << "("<<expr.l << " "<<utility::operation<Tag>::name << " "<<expr.r<<")" ; } friend std::ostream &operator <<(std::ostream &sout, gf_expr const &expr){return sout << "("<<expr.l << " "<<utility::operation<Tag>::name << " "<<expr.r<<")" ; }
@ -84,30 +70,44 @@ namespace triqs { namespace gfs {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//a special case : the unary operator ! //a special case : the unary operator !
template<typename L> struct gf_unary_m_expr : TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction){ template<typename Descriptor, typename L> struct gf_unary_m_expr : TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction),gf_tag<Descriptor>{
typedef typename std::remove_reference<L>::type L_t; typedef typename gfs_expr_tools::keeper_type<L>::type L_t;
typedef typename L_t::variable_t variable_t; typedef Descriptor descriptor_t;
typedef typename L_t::target_t target_t; //typedef typename L_t::value_type value_type;
typedef typename L_t::option_t option_t; typedef typename L_t::mesh_t mesh_t;
//typedef typename Descriptor::singularity_t::view_type singularity_view_t;
L l; L_t l;
template<typename LL> gf_unary_m_expr(LL && l_) : l(std::forward<LL>(l_)) {} template<typename LL> gf_unary_m_expr(LL && l_) : l(std::forward<LL>(l_)) {}
mesh_t mesh() const { return l.mesh(); }
auto mesh() const DECL_AND_RETURN(l.mesh()); auto data() const ->decltype( - l.data()) { return - l.data();}
auto singularity() const DECL_AND_RETURN(l.singularity()); auto singularity() const DECL_AND_RETURN(l.singularity());
//const singularity_view_t singularity() const { return l.singularity();}
//symmetry_t const & symmetry() const { return _symmetry;}
template<typename KeyType> auto operator[](KeyType&& key) const DECL_AND_RETURN( -l[key]); template<typename KeyType> auto operator[](KeyType&& key) const DECL_AND_RETURN( -l[key]);
template<typename ... Args> auto operator()(Args && ... args) const DECL_AND_RETURN( -l(std::forward<Args>(args)...)); template<typename ... Args> auto operator()(Args && ... args) const DECL_AND_RETURN( -l(std::forward<Args>(args)...));
friend std::ostream &operator <<(std::ostream &sout, gf_unary_m_expr const &expr){return sout << '-'<<expr.l; } friend std::ostream &operator <<(std::ostream &sout, gf_unary_m_expr const &expr){return sout << '-'<<expr.l; }
}; };
// -------------------------------------------------------------------
// get the descriptor ...
template<typename A1, typename A2, typename Enable=void> struct get_desc;
template<typename A1, typename A2>
struct get_desc <A1,A2, typename std::enable_if<((!ImmutableGreenFunction<A1>::value) && (ImmutableGreenFunction<A2>::value))>::type > {
typedef typename A2::descriptor_t type;
};
template<typename A1, typename A2>
struct get_desc <A1,A2,typename std::enable_if<(!ImmutableGreenFunction<A2>::value) && (ImmutableGreenFunction<A1>::value)>::type > {
typedef typename A1::descriptor_t type;
};
template<typename A1, typename A2>
struct get_desc <A1,A2, typename std::enable_if< (ImmutableGreenFunction<A1>::value) && (ImmutableGreenFunction<A2>::value) && std::is_same<typename A1::descriptor_t,typename A2::descriptor_t>::value >::type > { typedef typename A2::descriptor_t type; };
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Now we can define all the C++ operators ... // Now we can define all the C++ operators ...
#define DEFINE_OPERATOR(TAG, OP, TRAIT1, TRAIT2) \ #define DEFINE_OPERATOR(TAG, OP, TRAIT1, TRAIT2) \
template<typename A1, typename A2>\ template<typename A1, typename A2>\
typename std::enable_if<TRAIT1<A1>::value && TRAIT2 <A2>::value, \ typename std::enable_if<TRAIT1<A1>::value && TRAIT2 <A2>::value, gf_expr<typename get_desc<A1,A2>::type, utility::tags::TAG, A1,A2>>::type\
gf_expr<utility::tags::TAG, typename gfs_expr_tools::node_t<A1>::type, typename gfs_expr_tools::node_t<A2>::type>>::type\ operator OP (A1 const & a1, A2 const & a2) { return gf_expr<typename get_desc<A1,A2>::type,utility::tags::TAG, A1,A2>(a1,a2);}
operator OP (A1 && a1, A2 && a2) { return {std::forward<A1>(a1),std::forward<A2>(a2)};}
DEFINE_OPERATOR(plus, +, ImmutableGreenFunction,ImmutableGreenFunction); DEFINE_OPERATOR(plus, +, ImmutableGreenFunction,ImmutableGreenFunction);
DEFINE_OPERATOR(minus, -, ImmutableGreenFunction,ImmutableGreenFunction); DEFINE_OPERATOR(minus, -, ImmutableGreenFunction,ImmutableGreenFunction);
@ -120,12 +120,8 @@ namespace triqs { namespace gfs {
#undef DEFINE_OPERATOR #undef DEFINE_OPERATOR
// the unary is special // the unary is special
template<typename A1> template<typename A1> typename std::enable_if<ImmutableGreenFunction<A1>::value, gf_unary_m_expr<typename A1::descriptor_t, A1>>::type
typename std::enable_if< operator - (A1 const & a1) { return gf_unary_m_expr<typename A1::descriptor_t, A1>(a1);}
ImmutableGreenFunction<A1>::value,
gf_unary_m_expr<typename gfs_expr_tools::node_t<A1>::type >
>::type
operator - (A1 && a1) { return {std::forward<A1>(a1)};}
}}//namespace triqs::gf }}//namespace triqs::gf
#endif #endif