/******************************************************************************* * * TRIQS: a Toolbox for Research in Interacting Quantum Systems * * Copyright (C) 2011 by O. Parcollet * * TRIQS is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * TRIQS. If not, see . * ******************************************************************************/ #ifndef TRIQS_ARRAYS_EXPRESSION_MAP_H #define TRIQS_ARRAYS_EXPRESSION_MAP_H #include "../impl/common.hpp" #include namespace triqs { namespace arrays { template class map_impl; /** * Given a function f : arg_type -> result_type, map(f) is the function promoted to arrays * map(f) : array --> array */ template map_impl map (F const & f) { return map_impl(f,true); } template map_impl map2 (F const & f) { return map_impl(f,true); } // ----------- implementation ------------------------------------- // NB The bool is to make constructor not ambiguous // clang on os X with lib++ has a pb otherwise (not clear what the pb is) template class map_impl { F f; public : // map_impl(F const & f_):f(f_) {} map_impl(F const & f_, bool):f(f_) {} map_impl(F && f_, bool):f(f_) {} map_impl(map_impl const &) = default; //map_impl(map_impl &&) = default; template class m_result; template class m_result >::type> : TRIQS_CONCEPT_TAG_NAME(ImmutableArray) { public: typedef typename std::result_of::type value_type; typedef typename A::domain_type domain_type; A const & a; F f; m_result(F const & f_, A const & a_):a(a_),f(f_) {} domain_type domain() const { return a.domain(); } template value_type operator() (Args const & ... args) const { return f(a(args...)); } friend std::ostream & operator<<(std::ostream & out, m_result const & x){ return out<<"lazy matrix resulting of a mapping";} }; template class m_result >::type> : TRIQS_CONCEPT_TAG_NAME(ImmutableMatrix) { public: typedef typename std::result_of::type value_type; typedef typename A::domain_type domain_type; A const & a; F f; m_result(F const & f_, A const & a_):a(a_),f(f_) {} domain_type domain() const { return a.domain(); } template value_type operator() (Args const & ... args) const { return f(a(args...)); } friend std::ostream & operator<<(std::ostream & out, m_result const & x){ return out<<"lazy matrix resulting of a mapping";} }; template class m_result >::type> : TRIQS_CONCEPT_TAG_NAME(ImmutableVector) { public: typedef typename std::result_of::type value_type; typedef typename A::domain_type domain_type; A const & a; F f; m_result(F const & f_, A const & a_):a(a_),f(f_) {} domain_type domain() const { return a.domain(); } size_t size() const { return a.size();} template value_type operator() (Args const & ... args) const { return f(a(args...)); } value_type operator() ( size_t i) const { return f(a(i)); } friend std::ostream & operator<<(std::ostream & out, m_result const & x){ return out<<"lazy matrix resulting of a mapping";} }; template struct result; template struct result { typedef m_result type;}; template< class A > m_result operator()(A const & a) const { //static_assert( (ImmutableCuboidArray::value), "map : A does not model ImmutableCuboidArray"); return m_result(f,a); } friend std::ostream & operator<<(std::ostream & out, map_impl const & x){ return out<<"map("<<"F"<<")";} }; // ----------- // TO DO : make this with preprocessor .... template class map_impl { F f; public : map_impl(F const & f_, bool):f(f_) {} map_impl(F && f_, bool):f(f_) {} map_impl(map_impl const &) = default; //map_impl(map_impl &&) = default; template class m_result : TRIQS_CONCEPT_TAG_NAME(ImmutableCuboidArray) { static_assert( (std::is_same::value), "type mismatch"); public: typedef typename std::result_of::type value_type; typedef typename A::domain_type domain_type; A const & a; B const & b; F f; m_result(F const & f_, A const & a_, B const & b_):a(a_),b(b_),f(f_) { if (a.domain() != b.domain()) TRIQS_RUNTIME_ERROR<<"map2 : domain mismatch"; } domain_type domain() const { return a.domain(); } template value_type operator() (Args const & ... args) const { return f(a(args...),b(args...)); } friend std::ostream & operator<<(std::ostream & out, m_result const & x){ return out<<"lazy matrix resulting of a mapping";} }; template struct result; template struct result { typedef m_result type;}; template< class A, class B > m_result operator()(A const & a, B const & b) { static_assert( (ImmutableCuboidArray::value), "map1 : A does not model ImmutableCuboidArray"); static_assert( (ImmutableCuboidArray::value), "map1 : B does not model ImmutableCuboidArray"); return m_result(f,a,b); } friend std::ostream & operator<<(std::ostream & out, map_impl const & x){ return out<<"map("<<"F"<<")";} }; }}//namespace triqs::arrays #endif