#pragma once #include "index_list.hpp" #include "friendly_fusion.hpp" #include #include template struct TypeAt { typedef friendly_fusion::result_of::begin begin; typedef friendly_fusion::result_of::advance_c adv_it; typedef friendly_fusion::result_of::deref deref; typedef typename std::decay::type value_type; }; #if defined( __GNUC__ ) && !defined( __clang__ ) template std::function make_at_c_lambda(T seq) { return [](T seq){ return boost::any(friendly_fusion::deref(friendly_fusion::advance_c(friendly_fusion::begin(seq)))); }; } #endif //defined( __GNUC__ ) && !defined( __clang__ ) template boost::any get_nth_impl(T seq, int index, indices) { typedef std::function element_type; static element_type table[] = { #if defined( __GNUC__ ) && !defined( __clang__ ) //Workaround for gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226 make_at_c_lambda(seq) ... #else [](T seq){return boost::any(friendly_fusion::deref(friendly_fusion::advance_c(friendly_fusion::begin(seq))));} ... #endif //defined( __GNUC__ ) && !defined( __clang__ ) }; return table[index](seq); } template struct get_nth_functor { boost::any operator()(T seq, int index) { typedef typename friendly_fusion::result_of::size::type seq_size; typedef typename build_indices::type indices_type; return get_nth_impl(seq, index, indices_type{}); } }; template boost::any get_nth(T x, int index) { return get_nth_functor()(x, index); } #if defined( __GNUC__ ) && !defined( __clang__ ) template std::function make_struct_member_name_lambda() { return []{ return std::string(friendly_fusion::extension::struct_member_name::call()); }; } #endif //defined( __GNUC__ ) && !defined( __clang__ ) template struct get_nth_name_impl { get_nth_name_impl() = default; template std::string operator()(int index, indices) { typedef std::function element_type; static element_type table[] = { #if defined( __GNUC__ ) && !defined( __clang__ ) //Workaround for gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226 make_struct_member_name_lambda() ... #else []{return std::string(friendly_fusion::extension::struct_member_name::call());} ... #endif //defined( __GNUC__ ) && !defined( __clang__ ) }; return table[index](); } }; template struct get_nth_name_functor { std::string operator()(int index) { typedef typename friendly_fusion::result_of::size::type seq_size; typedef typename build_indices::type indices_type; return get_nth_name_impl()(index, indices_type{}); } }; template struct get_nth_name_functor> { std::string operator()(int index) { constexpr size_t size_of_T = friendly_fusion::result_of::size::type::value; if(index < size_of_T){ return get_nth_name_functor()(index); } else { return get_nth_name_functor()(index - size_of_T); } } }; template std::string get_nth_name(int index) { return get_nth_name_functor()(index); }