#pragma once #include #include #include #include #include #include #include #include namespace fc { /** * Provides a fast-compiling tuple that doesn't use fancy meta-programming * techniques. It is limited to 4 parameters which is sufficient for most * methods argument lists which is the primary use case for this tuple. Methods * that require more than 4 parameters are probably better served by defining * a struct. * * The members of the tuple are easily visited with a simple visitor functor * of the form: * @code * struct visitor { * template * void operator()( MemberType& m ); * * template * void operator()( const MemberType& m ); * }; * @endcode template struct tuple { tuple(){} enum size_enum { size = 4 }; template tuple( AA&& aa, BB&& bb, CC&& cc, DD&& dd ) :a( fc::forward(aa) ), b( fc::forward(bb) ), c( fc::forward(cc) ), d( fc::forward
(dd) ) {} template void visit( V&& v ) { v(a); v(b); v(c); v(d); } template void visit( V&& v )const { v(a); v(b); v(c); v(d); } A a; B b; C c; D d; }; */ template struct tuple{}; template<> struct tuple<> { enum size_enum { size = 0 }; template void visit( V&& v)const{}; }; template auto call_fused( Functor f, const tuple<>& t ) -> decltype( f( ) ) { return f(); } inline tuple<> make_tuple(){ return tuple<>(); } template struct is_tuple { typedef fc::false_type type; }; #define RREF_PARAMS(z,n,data) BOOST_PP_CAT(AA,n)&& BOOST_PP_CAT(p,n) #define ILIST_PARAMS(z,n,data) BOOST_PP_CAT(a,n)( fc::forward( BOOST_PP_CAT(p,n) ) ) #define ILIST_PARAMS_COPY(z,n,data) BOOST_PP_CAT(a,n)( t.BOOST_PP_CAT(a,n) ) #define VISIT_PARAMS(z,n,data) v(BOOST_PP_CAT(a,n)); #define LIST_MEMBERS_ON(z,n,data) data.BOOST_PP_CAT(a,n) #define DEDUCE_MEMBERS(z,n,data) typename fc::deduce::type #define FORWARD_PARAMS(z,n,data) fc::forward(BOOST_PP_CAT(p,n)) #define MEM_PARAMS(z,n,data) BOOST_PP_CAT(A,n) BOOST_PP_CAT(a,n); #define TUPLE(z,n,unused) \ template \ struct tuple { \ enum size_enum { size = n }; \ template \ tuple( BOOST_PP_ENUM(n, RREF_PARAMS, unused ) )BOOST_PP_IF(n,:,BOOST_PP_EMPTY())BOOST_PP_ENUM( n, ILIST_PARAMS,unused){} \ tuple( const tuple& t )BOOST_PP_IF(n,:,BOOST_PP_EMPTY())BOOST_PP_ENUM( n, ILIST_PARAMS_COPY,unused){} \ tuple( tuple& t )BOOST_PP_IF(n,:,BOOST_PP_EMPTY())BOOST_PP_ENUM( n, ILIST_PARAMS_COPY,unused){} \ tuple( tuple&& t )BOOST_PP_IF(n,:,BOOST_PP_EMPTY())BOOST_PP_ENUM( n, ILIST_PARAMS_COPY,unused){} \ tuple(){}\ template\ void visit( V&& v ) { BOOST_PP_REPEAT(n,VISIT_PARAMS,a) }\ template\ void visit( V&& v )const { BOOST_PP_REPEAT(n,VISIT_PARAMS,a) }\ BOOST_PP_REPEAT(n,MEM_PARAMS,a) \ }; \ template \ tuple make_tuple( BOOST_PP_ENUM( n, RREF_PARAMS, unused) ) { \ return tuple( BOOST_PP_ENUM( n, FORWARD_PARAMS,unused ) ); \ } \ template \ auto call_fused( Functor f, tuple& t ) \ -> decltype( f( BOOST_PP_ENUM( n, LIST_MEMBERS_ON, t) ) ) { \ return f( BOOST_PP_ENUM( n, LIST_MEMBERS_ON, t) ); \ } \ template \ auto call_fused( Functor f, const tuple& t ) \ -> decltype( f( BOOST_PP_ENUM( n, LIST_MEMBERS_ON, t) ) ) { \ return f( BOOST_PP_ENUM( n, LIST_MEMBERS_ON, t) ); \ } \ template \ struct is_tuple > { \ typedef fc::true_type type; \ }; \ template \ struct deduce > { \ typedef fc::tuple type; \ }; BOOST_PP_REPEAT_FROM_TO( 1, 4, TUPLE, unused ) #undef FORWARD_PARAMS #undef DEDUCE_MEMBERS #undef RREF_PARAMS #undef LIST_MEMBERS_ON #undef ILIST_PARAMS #undef ILIST_PARAMS_COPY #undef VISIT_PARAMS #undef MEM_PARAMS #undef TUPLE }