#pragma once #include "index_list.hpp" #include "friendly_fusion.hpp" #include #include #include template struct IndicesOf { typedef typename build_indices::type::value>::type type; }; template class F, int... Indices, typename... Args> typename F::return_type apply_functor_to_member_impl(indices, int index, Args... args) { typedef std::function::return_type(Args...)> f_type; static f_type array[] = { F::template call ... }; return array[index](std::forward(args)...); } template class F, int... Indices, typename Arg1, typename... Args> typename F::return_type apply_functor_to_member_impl(indices, int index, Arg1& arg1, Args... args) { typedef std::function::return_type(Arg1&, Args...)> f_type; static f_type array[] = { F::template call ... }; return array[index](arg1, std::forward(args)...); } template class F, typename... Args> typename F::return_type apply_functor_to_member(int index, Args... args) { return apply_functor_to_member_impl(typename IndicesOf::type{}, index, std::forward(args)...); } template class F, typename Arg1, typename... Args> typename F::return_type apply_functor_to_member(int index, Arg1& arg1, Args... args) { return apply_functor_to_member_impl(typename IndicesOf::type{}, index, arg1, std::forward(args)...); } template struct is_const_functor { typedef bool return_type; template static return_type call() { typedef typename friendly_fusion::utils::UnrefTypeOfAtIndex::type unref_type; return std::is_const::value; } }; template bool is_const(int index) { return apply_functor_to_member(index); } template struct get_nth_functor { typedef boost::any return_type; template static return_type call(T& seq) { return boost::any(friendly_fusion::deref(friendly_fusion::advance_c(friendly_fusion::begin(seq)))); } }; template boost::any get_nth(T x, int index) { return apply_functor_to_member(index, x); } template typename std::enable_if::type assign(T&, V) { //this function will never be called, but has to be defined. //We need to generate a assign statement for all members at compile time even when they are const. return; } template typename std::enable_if::type assign(T& lh, V rh) { lh = rh; } template struct set_nth_functor { typedef void return_type; template static return_type call(T& t, boost::any const& value) { typedef typename friendly_fusion::utils::DecayedTypeOfAtIndex::type value_type; typedef typename friendly_fusion::utils::UnrefTypeOfAtIndex::type unref_type; assign::value>(friendly_fusion::deref(friendly_fusion::advance_c(friendly_fusion::begin(t))), boost::any_cast(value)); } }; template void set_nth(T& x, int index, boost::any const& value) { apply_functor_to_member(index, x, value); } template std::string get_nth_name(int index); template struct get_nth_name_functor { typedef std::string return_type; template static return_type call() { return std::string(friendly_fusion::extension::struct_member_name::call()); } }; template struct get_nth_name_functor> { typedef std::string return_type; template static return_type call() { constexpr int size_of_T = friendly_fusion::result_of::size::type::value; if(I < size_of_T){ return get_nth_name(I); } else { return get_nth_name(I - size_of_T); } } }; template std::string get_nth_name(int index) { return apply_functor_to_member(index); }