peerplays-fc/include/fc/api.hpp

102 lines
3.6 KiB
C++
Raw Normal View History

#pragma once
2013-08-08 13:49:37 +00:00
#include <fc/thread/future.hpp>
#include <functional>
2012-12-03 19:51:31 +00:00
#include <boost/config.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
namespace fc {
namespace detail {
struct identity_member {
template<typename R, typename C, typename P, typename... Args>
static std::function<R(Args...)> functor( P&& p, R (C::*mem_func)(Args...) ) {
return std::function<R(Args...)>([=](Args... args){ return (p->*mem_func)(args...); });
}
template<typename R, typename C, typename P, typename... Args>
static std::function<R(Args...)> functor( P&& p, R (C::*mem_func)(Args...)const ) {
return std::function<R(Args...)>([=](Args... args){ return (p->*mem_func)(args...); });
}
};
template< typename Interface, typename Transform = detail::identity_member >
struct vtable{};
template<typename ThisPtr>
struct vtable_visitor {
template<typename U>
vtable_visitor( U&& u ):_this( fc::forward<U>(u) ){}
template<typename Function, typename MemberPtr>
void operator()( const char* name, Function& memb, MemberPtr m )const {
memb = identity_member::functor( _this, m );
}
ThisPtr _this;
};
} // namespace detail
template<typename Interface, typename Transform = detail::identity_member >
2015-03-09 22:50:20 +00:00
class api {
public:
typedef detail::vtable<Interface,Transform> vtable_type;
2015-03-09 22:50:20 +00:00
api(){}
template<typename InterfaceType>
2015-03-09 22:50:20 +00:00
api( InterfaceType* p )
:_vtable( new vtable_type() ) {
_vtable->template visit_other<InterfaceType>( detail::vtable_visitor<InterfaceType*>(p) );
}
template<typename InterfaceType>
2015-03-09 22:50:20 +00:00
api( const fc::shared_ptr<InterfaceType>& p )
:_vtable( new vtable_type() ),_self(p){
_vtable->template visit_other<InterfaceType>( detail::vtable_visitor<InterfaceType*>(p.get()) );
}
//vtable_type& operator*() { return *_vtable; }
vtable_type& operator*()const { return *_vtable; }
//vtable_type* operator->() { return _vtable.get(); }
vtable_type* operator->()const { return _vtable.get(); }
protected:
fc::shared_ptr< vtable_type > _vtable;
fc::shared_ptr< fc::retainable > _self;
};
}
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/stringize.hpp>
2015-03-09 22:50:20 +00:00
#define FC_API_VTABLE_DEFINE_MEMBER( r, data, elem ) \
decltype(Transform::functor( (data*)nullptr, &data::elem)) elem;
2015-03-09 22:50:20 +00:00
#define FC_API_VTABLE_DEFINE_VISIT_OTHER( r, data, elem ) \
v( BOOST_PP_STRINGIZE(elem), elem, &T::elem );
2015-03-09 22:50:20 +00:00
#define FC_API_VTABLE_DEFINE_VISIT( r, data, elem ) \
v( BOOST_PP_STRINGIZE(elem), elem );
2015-03-09 22:50:20 +00:00
#define FC_API( CLASS, METHODS ) \
namespace fc { namespace detail { \
template<typename Transform> \
2012-11-09 06:36:23 +00:00
struct vtable<CLASS,Transform> : public fc::retainable { \
vtable(){} \
2015-03-09 22:50:20 +00:00
BOOST_PP_SEQ_FOR_EACH( FC_API_VTABLE_DEFINE_MEMBER, CLASS, METHODS ) \
template<typename T, typename Visitor> \
void visit_other( Visitor&& v ){ \
2015-03-09 22:50:20 +00:00
BOOST_PP_SEQ_FOR_EACH( FC_API_VTABLE_DEFINE_VISIT_OTHER, CLASS, METHODS ) \
} \
template<typename Visitor> \
void visit( Visitor&& v ){ \
2015-03-09 22:50:20 +00:00
BOOST_PP_SEQ_FOR_EACH( FC_API_VTABLE_DEFINE_VISIT, CLASS, METHODS ) \
} \
}; \
2015-03-09 22:50:20 +00:00
} }
//#undef FC_API_VTABLE_DEFINE_MEMBER
//#undef FC_API_VTABLE_DEFINE_VISIT