/******************************************************************************* * * 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 //#include "../../utility/function_arg_ret_type.hpp" 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::arity> map (F f) { return {std::move(f),true}; } template map_impl map (F f) { return {std::move(f),true}; } template map_impl map2 (F f) { return {std::move(f),true}; } // ----------- implementation ------------------------------------- template struct map_impl_result; template struct map_impl_result { typedef typename std::result_of::type::value_type)>::type value_type; typedef typename std::remove_reference::type::domain_type domain_type; F f; typename std::add_const::type a; // A is a T or a T& : add const to them. domain_type domain() const { return a.domain(); } template value_type operator() (Args && ... args) const { return f(a(std::forward(args)...)); } friend std::ostream & operator<<(std::ostream & out, map_impl_result const & x){ return out<<"mapping result";} // rest is only for vector template TYPE_ENABLE_IFC(size_t,vec) size() const { return a.size();} template TYPE_ENABLE_IFC(value_type,vec) operator[] (Args && args) const { return f(a[std::forward(args)]);} }; // possible to generalize to N order using tuple techniques ... template struct map_impl_result { typedef typename std::result_of::type::value_type, typename remove_cv_ref::type::value_type)>::type value_type; typedef typename remove_cv_ref::type::domain_type domain_type; F f; typename std::add_const::type a; typename std::add_const::type b; domain_type domain() const { return a.domain(); } template value_type operator() (Args && ... args) const { return f(a(std::forward(args)...),b(std::forward(args)...)); } friend std::ostream & operator<<(std::ostream & out, map_impl_result const & x){ return out<<"mapping result";} // rest is only for vector template TYPE_ENABLE_IFC(size_t,vec) size() const { return a.size();} template TYPE_ENABLE_IFC(value_type,vec) operator[] (Args && args) const { return f(a[std::forward(args)],b[std::forward(args)]);} }; /* already defined in traist template struct _and; template struct _and : std::integral_constant::value>{}; template struct _and : T{}; */ template struct ImmutableCuboidArray> : std::true_type{}; template struct ImmutableArray > : _and::type>::type...>{}; template struct ImmutableMatrix> : _and::type>::type...>{}; template struct ImmutableVector> : _and::type>::type...>{}; //template struct ImmutableArray > : ImmutableArray {}; //template struct ImmutableMatrix> : ImmutableMatrix{}; //template struct ImmutableVector> : ImmutableVector{}; // 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 f_, bool):f(std::move(f_)) {} map_impl(map_impl const &) = default; map_impl(map_impl &&) = default; map_impl & operator = (map_impl const &) = default; map_impl & operator = (map_impl &&) = default; template map_impl_result::type...>::value,A...> operator()(A&&... a) const { return {f,std::forward(a)...}; } friend std::ostream & operator<<(std::ostream & out, map_impl const & x){ return out<<"map("<<"F"<<")";} }; }}//namespace triqs::arrays #endif