peerplays-fc/include/fc/tuple.hpp

137 lines
5.3 KiB
C++
Raw Permalink Normal View History

2012-10-26 04:59:30 +00:00
#pragma once
#include <fc/utility.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
2012-10-26 04:59:30 +00:00
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<typename MemberType>
* void operator()( MemberType& m );
*
* template<typename MemberType>
* void operator()( const MemberType& m );
* };
* @endcode
template<typename A=void, typename B=void,typename C=void, typename D=void>
struct tuple {
tuple(){}
enum size_enum { size = 4 };
template<typename AA, typename BB, typename CC, typename DD>
tuple( AA&& aa, BB&& bb, CC&& cc, DD&& dd )
:a( fc::forward<AA>(aa) ),
b( fc::forward<BB>(bb) ),
c( fc::forward<CC>(cc) ),
d( fc::forward<DD>(dd) )
{}
template<typename V>
void visit( V&& v ) { v(a); v(b); v(c); v(d); }
template<typename V>
void visit( V&& v )const { v(a); v(b); v(c); v(d); }
A a;
B b;
C c;
D d;
};
*/
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(9, typename A, void)> struct tuple{};
template<>
struct tuple<> {
enum size_enum { size = 0 };
template<typename V>
void visit( V&& v)const{};
};
2012-12-03 19:51:31 +00:00
template<typename Functor>
auto call_fused( Functor f, const tuple<>& t ) -> decltype( f( ) ) {
2012-11-13 02:45:41 +00:00
return f();
}
inline tuple<> make_tuple(){ return tuple<>(); }
template<typename T>
struct is_tuple {
typedef fc::false_type type;
};
2012-10-26 04:59:30 +00:00
2012-12-03 19:51:31 +00:00
#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(AA,n)>( 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)
2012-11-13 02:45:41 +00:00
#define DEDUCE_MEMBERS(z,n,data) typename fc::deduce<BOOST_PP_CAT(AA,n)>::type
2012-12-03 19:51:31 +00:00
#define FORWARD_PARAMS(z,n,data) fc::forward<BOOST_PP_CAT(AA,n)>(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<BOOST_PP_ENUM_PARAMS( n, typename A)> \
struct tuple<BOOST_PP_ENUM_PARAMS(n,A)> { \
enum size_enum { size = n }; \
template<BOOST_PP_ENUM_PARAMS( n, typename AA)> \
2012-12-18 19:37:14 +00:00
explicit 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(){}\
template<typename V>\
void visit( V&& v ) { BOOST_PP_REPEAT(n,VISIT_PARAMS,a) }\
template<typename V>\
void visit( V&& v )const { BOOST_PP_REPEAT(n,VISIT_PARAMS,a) }\
BOOST_PP_REPEAT(n,MEM_PARAMS,a) \
}; \
template<BOOST_PP_ENUM_PARAMS( n, typename AA)> \
tuple<BOOST_PP_ENUM_PARAMS(n,AA)> make_tuple( BOOST_PP_ENUM( n, RREF_PARAMS, unused) ) { \
return tuple<BOOST_PP_ENUM_PARAMS(n,AA)>( BOOST_PP_ENUM( n, FORWARD_PARAMS,unused ) ); \
} \
2012-12-03 19:51:31 +00:00
template<typename Functor, BOOST_PP_ENUM_PARAMS(n,typename AA)> \
auto call_fused( Functor f, tuple<BOOST_PP_ENUM_PARAMS(n,AA)>& t ) \
-> decltype( f( BOOST_PP_ENUM( n, LIST_MEMBERS_ON, t) ) ) { \
return f( BOOST_PP_ENUM( n, LIST_MEMBERS_ON, t) ); \
} \
template<typename Functor, BOOST_PP_ENUM_PARAMS(n,typename AA)> \
auto call_fused( Functor f, const tuple<BOOST_PP_ENUM_PARAMS(n,AA)>& t ) \
-> decltype( f( BOOST_PP_ENUM( n, LIST_MEMBERS_ON, t) ) ) { \
return f( BOOST_PP_ENUM( n, LIST_MEMBERS_ON, t) ); \
} \
template<BOOST_PP_ENUM_PARAMS( n, typename AA)> \
struct is_tuple<fc::tuple<BOOST_PP_ENUM_PARAMS(n,AA)> > { \
typedef fc::true_type type; \
2012-11-13 02:45:41 +00:00
}; \
template<BOOST_PP_ENUM_PARAMS( n, typename AA)> \
struct deduce<fc::tuple<BOOST_PP_ENUM_PARAMS(n,AA)> > { \
typedef fc::tuple<BOOST_PP_ENUM( n, DEDUCE_MEMBERS,unused)> type; \
};
2013-03-01 23:56:06 +00:00
BOOST_PP_REPEAT_FROM_TO( 1, 5, TUPLE, unused )
#undef FORWARD_PARAMS
2012-11-13 02:45:41 +00:00
#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
2012-10-26 04:59:30 +00:00
}