MACE
1.0.0
|
00001 #ifndef BOOST_PP_IS_ITERATING 00002 #ifndef BOOST_CLIENT_INTERFACE_HPP 00003 #define BOOST_CLIENT_INTERFACE_HPP 00004 #include <boost/bind.hpp> 00005 #include <boost/preprocessor/repetition.hpp> 00006 #include <boost/preprocessor/seq/for_each.hpp> 00007 00008 #include <boost/fusion/container/vector.hpp> 00009 #include <boost/fusion/container/generation/make_vector.hpp> 00010 #include <boost/fusion/functional/generation/make_fused_function_object.hpp> 00011 #include <boost/fusion/functional/generation/make_unfused.hpp> 00012 #include <mace/stub/void.hpp> 00013 #include <mace/stub/vtable.hpp> 00014 00015 #include <mace/rpc/json/client_base.hpp> 00016 00017 namespace mace { namespace rpc { namespace json { 00022 template<typename MemberPtr> 00023 struct client_member; 00024 00025 class client_base; 00026 00027 namespace detail { 00028 namespace client_interface { 00029 template<typename VTableType> 00030 class set_visitor { 00031 public: 00032 set_visitor( VTableType& vt, mace::rpc::json::client_base* ci ) 00033 :m_ci(ci),vtbl(vt){} 00034 00035 template<typename M, M m> 00036 void operator()( const char* name )const { 00037 (vtbl.*m).set( name, m_ci ); 00038 } 00039 private: 00040 mace::rpc::json::client_base* m_ci; 00041 VTableType& vtbl; 00042 }; 00043 00044 struct client_member_base { 00045 client_member_base():m_ci(0){} 00046 void set( const std::string& mid, mace::rpc::json::client_base* ci ) { 00047 m_method_id = mid; 00048 m_ci = ci; 00049 } 00050 protected: 00051 std::string m_method_id; 00052 mace::rpc::json::client_base* m_ci; 00053 }; 00054 } 00055 } 00056 00069 struct client_interface { 00075 template<typename MemberPointer> 00076 struct calculate_type { 00077 typedef client_member<MemberPointer> type; 00078 }; 00079 00080 template<typename ClientType> 00081 static void set( ClientType& cl ) { 00082 mace::stub::visit( cl, detail::client_interface::set_visitor<typename ClientType::vtable_type>( *cl, &cl ) ); 00083 } 00084 }; 00085 00086 00087 #define PARAM_NAME(z,n,type) BOOST_PP_CAT(a,n) 00088 #define PARAM_TYPE_NAME(z,n,type) BOOST_PP_CAT(typename A,n) 00089 #define PARAM_TYPE(z,n,type) BOOST_PP_CAT(A,n) 00090 #define PARAM_ARG(z,n,type) PARAM_TYPE(z,n,type) PARAM_NAME(z,n,type) 00091 00092 # ifndef BOOST_CLIENT_IMPL_SIZE 00093 # define BOOST_CLIENT_IMPL_SIZE 8 00094 # endif 00095 00096 # include <boost/preprocessor/iteration/iterate.hpp> 00097 # define BOOST_PP_ITERATION_LIMITS (0, BOOST_CLIENT_IMPL_SIZE -1 ) 00098 # define BOOST_PP_FILENAME_1 <mace/rpc/json/client_interface.hpp> 00099 # include BOOST_PP_ITERATE() 00100 00101 #undef PARAM_NAME 00102 #undef PARAM_TYPE 00103 #undef PARAM_ARG 00104 00105 } } } // namespace mace::rpc::json 00106 #endif // BOOST_CLIENT_INTERFACE_HPP 00107 00108 #else // BOOST_PP_IS_ITERATING 00109 00110 #define n BOOST_PP_ITERATION() 00111 #define PARAM_NAMES BOOST_PP_ENUM(n,PARAM_NAME,A) // name_N 00112 #define PARAM_ARGS BOOST_PP_ENUM(n,PARAM_ARG,A) // TYPE_N name_N 00113 #define PARAM_TYPE_NAMES BOOST_PP_ENUM(n,PARAM_TYPE_NAME,A) // typename TYPE_N 00114 #define PARAM_TYPES BOOST_PP_ENUM(n,PARAM_TYPE,A) // TYPE_N 00115 00116 template<typename R, typename Class BOOST_PP_COMMA_IF(n) PARAM_TYPE_NAMES> 00117 struct client_member<R(Class::*)(PARAM_TYPES)const> : public detail::client_interface::client_member_base 00118 { 00119 typedef typename mace::stub::adapt_void<R>::result_type result_type; 00120 typedef mace::cmt::future<result_type> future_type; 00121 typedef client_member self_type; 00122 typedef boost::fusion::vector<PARAM_TYPES> fused_params; 00123 typedef boost::function_traits<result_type(PARAM_TYPES)> traits; 00124 static const bool is_const = true; 00125 00126 typedef typename boost::remove_pointer<result_type(*)(PARAM_TYPES)>::type signature; 00127 00128 inline future_type operator()( PARAM_ARGS )const { 00129 return (*this)( boost::fusion::make_vector(PARAM_NAMES) ); 00130 } 00131 inline future_type operator() ( const fused_params& fp )const { 00132 BOOST_ASSERT(m_ci); 00133 return m_ci->call_fused<result_type,fused_params>( m_method_id, fp ); 00134 } 00135 inline void notice( const fused_params& fp )const { 00136 BOOST_ASSERT(m_ci); 00137 return m_ci->notice_fused( m_method_id, fp ); 00138 } 00139 }; 00140 00141 template<typename R, typename Class BOOST_PP_COMMA_IF(n) PARAM_TYPE_NAMES> 00142 struct client_member<R(Class::*)(PARAM_TYPES)> : public detail::client_interface::client_member_base 00143 { 00144 typedef typename mace::stub::adapt_void<R>::result_type result_type; 00145 typedef mace::cmt::future<result_type> future_type; 00146 typedef client_member self_type; 00147 typedef boost::fusion::vector<PARAM_TYPES> fused_params; 00148 typedef boost::function_traits<result_type(PARAM_TYPES)> traits; 00149 typedef boost::function<result_type(const fused_params&)> delegate_type; 00150 static const bool is_const = false; 00151 00152 // boost::result_of 00153 typedef typename boost::remove_pointer<result_type(*)(PARAM_TYPES)>::type signature; 00154 00155 inline future_type operator()( PARAM_ARGS ) { 00156 return (*this)( boost::fusion::make_vector(PARAM_NAMES) ); 00157 } 00158 inline future_type operator() ( const fused_params& fp ) { 00159 BOOST_ASSERT(m_ci); 00160 return m_ci->call_fused<result_type,fused_params>( m_method_id, fp ); 00161 } 00162 inline void notice( const fused_params& fp )const { 00163 BOOST_ASSERT(m_ci); 00164 return m_ci->notice_fused( m_method_id, fp ); 00165 } 00166 00167 }; 00168 00169 00170 #undef n 00171 #undef PARAM_NAMES 00172 #undef PARAM_ARGS 00173 #undef PARAM_TYPE_NAMES 00174 #undef PARAM_TYPES 00175 00176 #endif // BOOST_PP_IS_ITERATING