GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
is_rpc_call.hpp
1 /*
2  * Copyright (c) 2009 Carnegie Mellon University.
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an "AS
13  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14  * express or implied. See the License for the specific language
15  * governing permissions and limitations under the License.
16  *
17  * For more about this software visit:
18  *
19  * http://www.graphlab.ml.cmu.edu
20  *
21  */
22 
23 
24 #ifndef IS_RPC_CALL_HPP
25 #define IS_RPC_CALL_HPP
26 #include <boost/type_traits/remove_pointer.hpp>
27 #include <boost/type_traits/remove_const.hpp>
28 #include <boost/type_traits/function_traits.hpp>
29 #include <boost/type_traits/is_same.hpp>
30 #include <boost/mpl/if.hpp>
31 #include <boost/mpl/and.hpp>
32 #include <boost/mpl/bool.hpp>
33 #include <boost/mpl/less.hpp>
34 #include <boost/mpl/comparison.hpp>
35 #include <boost/mpl/int.hpp>
36 
37 #include <graphlab/rpc/dc_types.hpp>
38 #include <graphlab/rpc/function_arg_types_def.hpp>
39 
40 
41 namespace graphlab {
42 class distributed_control;
43 namespace dc_impl {
44 
45 namespace is_rpc_call_detail {
46 /**
47 \ingroup rpc
48 \internal
49 Whether the function has less than or equal to 2 arguments
50 */
51 template <typename F>
52 struct less_than_2_args {
53  typedef typename boost::mpl::bool_<__GLRPC_FARITY < 2 >::type type;
54 };
55 
56 
57 /**
58 \ingroup rpc
59 \internal
60 Now, arg1_type and arg_2 type may not exist in function_traits if the
61 number of arguments is < 2. I will need to wrap it to make it safe
62 */
63 template <typename F, size_t nargs>
64 struct get_args{
65  typedef __GLRPC_NIF0 arg1_type;
66  typedef __GLRPC_NIF1 arg2_type;
67 };
68 
69 // if 0 args. then make both void
70 template <typename F>
71 struct get_args<F, 0>{
72  typedef void arg1_type;
73  typedef void arg2_type;
74 };
75 
76 // if 1 arg then make just make arg2 void
77 template <typename F>
78 struct get_args<F, 1>{
79  typedef __GLRPC_NIF0 arg1_type;
80  typedef void arg2_type;
81 };
82 
83 
84 
85 template <typename F>
86 struct check_first_arg {
87  typedef typename boost::is_same<typename get_args<F,__GLRPC_FARITY>::arg1_type, distributed_control>::type type;
88 };
89 
90 template <typename F>
91 struct check_second_arg {
92  typedef typename boost::is_integral<typename get_args<F,__GLRPC_FARITY>::arg2_type>::type type;
93 };
94 
95 
96 }
97 
98 /**
99  * \ingroup rpc
100  * \internal
101  * ::type is true if F is an RPC call interface.
102  * \tparam F the function to test
103  */
104 template <typename F>
105 struct is_rpc_call {
106  typedef typename boost::mpl::if_< typename is_rpc_call_detail::less_than_2_args<F>::type,
107  boost::false_type,
108  typename boost::mpl::and_<
109  typename is_rpc_call_detail::check_first_arg<F>::type,
110  typename is_rpc_call_detail::check_second_arg<F>::type>::type >::type type;
111 
112 
113 };
114 
115 // Varargs are all none RPC calls
116 #define BLOCK_VAR_ARGS(Z,N,_) \
117 template <typename RetType BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, typename T)> \
118 struct is_rpc_call<RetType (BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_COMMA_IF(N) ...)> { \
119  typedef boost::false_type type; \
120 }; \
121 \
122 template <typename RetType BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, typename T)> \
123 struct is_rpc_call<RetType (*)(BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_COMMA_IF(N) ...)> { \
124  typedef boost::false_type type; \
125 };
126 BOOST_PP_REPEAT(6, BLOCK_VAR_ARGS, _)
127 #undef BLOCK_VAR_ARGS
128 
129 #define GEN_GET_USER_ARG(Z,N,_) \
130 template <typename F, typename BoolType> \
131 struct BOOST_PP_CAT(get_cleaned_rpc_or_basic_arg, N) { \
132  typedef BOOST_PP_CAT(__GLRPC_NIF, N) arg_type; \
133 }; \
134 template <typename F> \
135 struct BOOST_PP_CAT(get_cleaned_rpc_or_basic_arg, N) <F, boost::mpl::bool_<true> > { \
136  typedef BOOST_PP_CAT(__GLRPC_F, N) arg_type; \
137 }; \
138 template <typename F> \
139 struct BOOST_PP_CAT(get_cleaned_user_arg, N) { \
140  typedef typename BOOST_PP_CAT(get_cleaned_rpc_or_basic_arg, N)<F,typename is_rpc_call<F>::type>::arg_type arg_type; \
141 };
142 
143 BOOST_PP_REPEAT(6, GEN_GET_USER_ARG, _)
144 #undef GEN_GET_USER_ARG
145 
146 } // namespace dc_impl
147 } // namespace graphlab
148 
149 #include <graphlab/rpc/function_arg_types_undef.hpp>
150 
151 #endif
152