blob: 11642e6b93ebac2c741448f7e88ef919c2c056be [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001// Boost.Function library
2
3// Copyright Douglas Gregor 2001-2006
4// Copyright Emil Dotchevski 2007
5// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8
9// For more information, see http://www.boost.org
10
11// Note: this header is a header template and must NOT have multiple-inclusion
12// protection.
13#include <ndnboost/function/detail/prologue.hpp>
14#include <ndnboost/detail/no_exceptions_support.hpp>
15
Jeff Thompson3d613fd2013-10-15 15:39:04 -070016#if defined(NDNBOOST_MSVC)
Jeff Thompsona28eed82013-08-22 16:21:10 -070017# pragma warning( push )
18# pragma warning( disable : 4127 ) // "conditional expression is constant"
19#endif
20
Jeff Thompson3d613fd2013-10-15 15:39:04 -070021#define NDNBOOST_FUNCTION_TEMPLATE_PARMS NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_FUNCTION_NUM_ARGS, typename T)
Jeff Thompsona28eed82013-08-22 16:21:10 -070022
Jeff Thompson3d613fd2013-10-15 15:39:04 -070023#define NDNBOOST_FUNCTION_TEMPLATE_ARGS NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_FUNCTION_NUM_ARGS, T)
Jeff Thompsona28eed82013-08-22 16:21:10 -070024
Jeff Thompson3d613fd2013-10-15 15:39:04 -070025#define NDNBOOST_FUNCTION_PARM(J,I,D) NDNBOOST_PP_CAT(T,I) NDNBOOST_PP_CAT(a,I)
Jeff Thompsona28eed82013-08-22 16:21:10 -070026
Jeff Thompson3d613fd2013-10-15 15:39:04 -070027#define NDNBOOST_FUNCTION_PARMS NDNBOOST_PP_ENUM(NDNBOOST_FUNCTION_NUM_ARGS,NDNBOOST_FUNCTION_PARM,NDNBOOST_PP_EMPTY)
Jeff Thompsona28eed82013-08-22 16:21:10 -070028
Jeff Thompson3d613fd2013-10-15 15:39:04 -070029#define NDNBOOST_FUNCTION_ARGS NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_FUNCTION_NUM_ARGS, a)
Jeff Thompsona28eed82013-08-22 16:21:10 -070030
Jeff Thompson3d613fd2013-10-15 15:39:04 -070031#define NDNBOOST_FUNCTION_ARG_TYPE(J,I,D) \
32 typedef NDNBOOST_PP_CAT(T,I) NDNBOOST_PP_CAT(NDNBOOST_PP_CAT(arg, NDNBOOST_PP_INC(I)),_type);
Jeff Thompsona28eed82013-08-22 16:21:10 -070033
Jeff Thompson3d613fd2013-10-15 15:39:04 -070034#define NDNBOOST_FUNCTION_ARG_TYPES NDNBOOST_PP_REPEAT(NDNBOOST_FUNCTION_NUM_ARGS,NDNBOOST_FUNCTION_ARG_TYPE,NDNBOOST_PP_EMPTY)
Jeff Thompsona28eed82013-08-22 16:21:10 -070035
36// Comma if nonzero number of arguments
Jeff Thompson3d613fd2013-10-15 15:39:04 -070037#if NDNBOOST_FUNCTION_NUM_ARGS == 0
38# define NDNBOOST_FUNCTION_COMMA
Jeff Thompsona28eed82013-08-22 16:21:10 -070039#else
Jeff Thompson3d613fd2013-10-15 15:39:04 -070040# define NDNBOOST_FUNCTION_COMMA ,
41#endif // NDNBOOST_FUNCTION_NUM_ARGS > 0
Jeff Thompsona28eed82013-08-22 16:21:10 -070042
43// Class names used in this version of the code
Jeff Thompson3d613fd2013-10-15 15:39:04 -070044#define NDNBOOST_FUNCTION_FUNCTION NDNBOOST_JOIN(function,NDNBOOST_FUNCTION_NUM_ARGS)
45#define NDNBOOST_FUNCTION_FUNCTION_INVOKER \
46 NDNBOOST_JOIN(function_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
47#define NDNBOOST_FUNCTION_VOID_FUNCTION_INVOKER \
48 NDNBOOST_JOIN(void_function_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
49#define NDNBOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
50 NDNBOOST_JOIN(function_obj_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
51#define NDNBOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
52 NDNBOOST_JOIN(void_function_obj_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
53#define NDNBOOST_FUNCTION_FUNCTION_REF_INVOKER \
54 NDNBOOST_JOIN(function_ref_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
55#define NDNBOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
56 NDNBOOST_JOIN(void_function_ref_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
57#define NDNBOOST_FUNCTION_MEMBER_INVOKER \
58 NDNBOOST_JOIN(function_mem_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
59#define NDNBOOST_FUNCTION_VOID_MEMBER_INVOKER \
60 NDNBOOST_JOIN(function_void_mem_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
61#define NDNBOOST_FUNCTION_GET_FUNCTION_INVOKER \
62 NDNBOOST_JOIN(get_function_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
63#define NDNBOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
64 NDNBOOST_JOIN(get_function_obj_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
65#define NDNBOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
66 NDNBOOST_JOIN(get_function_ref_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
67#define NDNBOOST_FUNCTION_GET_MEMBER_INVOKER \
68 NDNBOOST_JOIN(get_member_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
69#define NDNBOOST_FUNCTION_GET_INVOKER \
70 NDNBOOST_JOIN(get_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
71#define NDNBOOST_FUNCTION_VTABLE NDNBOOST_JOIN(basic_vtable,NDNBOOST_FUNCTION_NUM_ARGS)
Jeff Thompsona28eed82013-08-22 16:21:10 -070072
Jeff Thompson3d613fd2013-10-15 15:39:04 -070073#ifndef NDNBOOST_NO_VOID_RETURNS
74# define NDNBOOST_FUNCTION_VOID_RETURN_TYPE void
75# define NDNBOOST_FUNCTION_RETURN(X) X
Jeff Thompsona28eed82013-08-22 16:21:10 -070076#else
Jeff Thompson3d613fd2013-10-15 15:39:04 -070077# define NDNBOOST_FUNCTION_VOID_RETURN_TYPE ndnboost::detail::function::unusable
78# define NDNBOOST_FUNCTION_RETURN(X) X; return NDNBOOST_FUNCTION_VOID_RETURN_TYPE ()
Jeff Thompsona28eed82013-08-22 16:21:10 -070079#endif
80
81namespace ndnboost {
82 namespace detail {
83 namespace function {
84 template<
85 typename FunctionPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -070086 typename R NDNBOOST_FUNCTION_COMMA
87 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -070088 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -070089 struct NDNBOOST_FUNCTION_FUNCTION_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -070090 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -070091 static R invoke(function_buffer& function_ptr NDNBOOST_FUNCTION_COMMA
92 NDNBOOST_FUNCTION_PARMS)
Jeff Thompsona28eed82013-08-22 16:21:10 -070093 {
94 FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
Jeff Thompson3d613fd2013-10-15 15:39:04 -070095 return f(NDNBOOST_FUNCTION_ARGS);
Jeff Thompsona28eed82013-08-22 16:21:10 -070096 }
97 };
98
99 template<
100 typename FunctionPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700101 typename R NDNBOOST_FUNCTION_COMMA
102 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700103 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700104 struct NDNBOOST_FUNCTION_VOID_FUNCTION_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -0700105 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700106 static NDNBOOST_FUNCTION_VOID_RETURN_TYPE
107 invoke(function_buffer& function_ptr NDNBOOST_FUNCTION_COMMA
108 NDNBOOST_FUNCTION_PARMS)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700109
110 {
111 FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700112 NDNBOOST_FUNCTION_RETURN(f(NDNBOOST_FUNCTION_ARGS));
Jeff Thompsona28eed82013-08-22 16:21:10 -0700113 }
114 };
115
116 template<
117 typename FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700118 typename R NDNBOOST_FUNCTION_COMMA
119 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700120 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700121 struct NDNBOOST_FUNCTION_FUNCTION_OBJ_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -0700122 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700123 static R invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
124 NDNBOOST_FUNCTION_PARMS)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700125
126 {
127 FunctionObj* f;
128 if (function_allows_small_object_optimization<FunctionObj>::value)
129 f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
130 else
131 f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700132 return (*f)(NDNBOOST_FUNCTION_ARGS);
Jeff Thompsona28eed82013-08-22 16:21:10 -0700133 }
134 };
135
136 template<
137 typename FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700138 typename R NDNBOOST_FUNCTION_COMMA
139 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700140 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700141 struct NDNBOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -0700142 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700143 static NDNBOOST_FUNCTION_VOID_RETURN_TYPE
144 invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
145 NDNBOOST_FUNCTION_PARMS)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700146
147 {
148 FunctionObj* f;
149 if (function_allows_small_object_optimization<FunctionObj>::value)
150 f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
151 else
152 f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700153 NDNBOOST_FUNCTION_RETURN((*f)(NDNBOOST_FUNCTION_ARGS));
Jeff Thompsona28eed82013-08-22 16:21:10 -0700154 }
155 };
156
157 template<
158 typename FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700159 typename R NDNBOOST_FUNCTION_COMMA
160 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700161 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700162 struct NDNBOOST_FUNCTION_FUNCTION_REF_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -0700163 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700164 static R invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
165 NDNBOOST_FUNCTION_PARMS)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700166
167 {
168 FunctionObj* f =
169 reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700170 return (*f)(NDNBOOST_FUNCTION_ARGS);
Jeff Thompsona28eed82013-08-22 16:21:10 -0700171 }
172 };
173
174 template<
175 typename FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700176 typename R NDNBOOST_FUNCTION_COMMA
177 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700178 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700179 struct NDNBOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -0700180 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700181 static NDNBOOST_FUNCTION_VOID_RETURN_TYPE
182 invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
183 NDNBOOST_FUNCTION_PARMS)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700184
185 {
186 FunctionObj* f =
187 reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700188 NDNBOOST_FUNCTION_RETURN((*f)(NDNBOOST_FUNCTION_ARGS));
Jeff Thompsona28eed82013-08-22 16:21:10 -0700189 }
190 };
191
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700192#if NDNBOOST_FUNCTION_NUM_ARGS > 0
Jeff Thompsona28eed82013-08-22 16:21:10 -0700193 /* Handle invocation of member pointers. */
194 template<
195 typename MemberPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700196 typename R NDNBOOST_FUNCTION_COMMA
197 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700198 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700199 struct NDNBOOST_FUNCTION_MEMBER_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -0700200 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700201 static R invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
202 NDNBOOST_FUNCTION_PARMS)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700203
204 {
205 MemberPtr* f =
206 reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700207 return ndnboost::mem_fn(*f)(NDNBOOST_FUNCTION_ARGS);
Jeff Thompsona28eed82013-08-22 16:21:10 -0700208 }
209 };
210
211 template<
212 typename MemberPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700213 typename R NDNBOOST_FUNCTION_COMMA
214 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700215 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700216 struct NDNBOOST_FUNCTION_VOID_MEMBER_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -0700217 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700218 static NDNBOOST_FUNCTION_VOID_RETURN_TYPE
219 invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
220 NDNBOOST_FUNCTION_PARMS)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700221
222 {
223 MemberPtr* f =
224 reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700225 NDNBOOST_FUNCTION_RETURN(ndnboost::mem_fn(*f)(NDNBOOST_FUNCTION_ARGS));
Jeff Thompsona28eed82013-08-22 16:21:10 -0700226 }
227 };
228#endif
229
230 template<
231 typename FunctionPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700232 typename R NDNBOOST_FUNCTION_COMMA
233 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700234 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700235 struct NDNBOOST_FUNCTION_GET_FUNCTION_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -0700236 {
237 typedef typename mpl::if_c<(is_void<R>::value),
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700238 NDNBOOST_FUNCTION_VOID_FUNCTION_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700239 FunctionPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700240 R NDNBOOST_FUNCTION_COMMA
241 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700242 >,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700243 NDNBOOST_FUNCTION_FUNCTION_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700244 FunctionPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700245 R NDNBOOST_FUNCTION_COMMA
246 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700247 >
248 >::type type;
249 };
250
251 template<
252 typename FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700253 typename R NDNBOOST_FUNCTION_COMMA
254 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700255 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700256 struct NDNBOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -0700257 {
258 typedef typename mpl::if_c<(is_void<R>::value),
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700259 NDNBOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700260 FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700261 R NDNBOOST_FUNCTION_COMMA
262 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700263 >,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700264 NDNBOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700265 FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700266 R NDNBOOST_FUNCTION_COMMA
267 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700268 >
269 >::type type;
270 };
271
272 template<
273 typename FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700274 typename R NDNBOOST_FUNCTION_COMMA
275 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700276 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700277 struct NDNBOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -0700278 {
279 typedef typename mpl::if_c<(is_void<R>::value),
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700280 NDNBOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700281 FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700282 R NDNBOOST_FUNCTION_COMMA
283 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700284 >,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700285 NDNBOOST_FUNCTION_FUNCTION_REF_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700286 FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700287 R NDNBOOST_FUNCTION_COMMA
288 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700289 >
290 >::type type;
291 };
292
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700293#if NDNBOOST_FUNCTION_NUM_ARGS > 0
Jeff Thompsona28eed82013-08-22 16:21:10 -0700294 /* Retrieve the appropriate invoker for a member pointer. */
295 template<
296 typename MemberPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700297 typename R NDNBOOST_FUNCTION_COMMA
298 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700299 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700300 struct NDNBOOST_FUNCTION_GET_MEMBER_INVOKER
Jeff Thompsona28eed82013-08-22 16:21:10 -0700301 {
302 typedef typename mpl::if_c<(is_void<R>::value),
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700303 NDNBOOST_FUNCTION_VOID_MEMBER_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700304 MemberPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700305 R NDNBOOST_FUNCTION_COMMA
306 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700307 >,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700308 NDNBOOST_FUNCTION_MEMBER_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700309 MemberPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700310 R NDNBOOST_FUNCTION_COMMA
311 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700312 >
313 >::type type;
314 };
315#endif
316
317 /* Given the tag returned by get_function_tag, retrieve the
318 actual invoker that will be used for the given function
319 object.
320
321 Each specialization contains an "apply" nested class template
322 that accepts the function object, return type, function
323 argument types, and allocator. The resulting "apply" class
324 contains two typedefs, "invoker_type" and "manager_type",
325 which correspond to the invoker and manager types. */
326 template<typename Tag>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700327 struct NDNBOOST_FUNCTION_GET_INVOKER { };
Jeff Thompsona28eed82013-08-22 16:21:10 -0700328
329 /* Retrieve the invoker for a function pointer. */
330 template<>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700331 struct NDNBOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
Jeff Thompsona28eed82013-08-22 16:21:10 -0700332 {
333 template<typename FunctionPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700334 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
Jeff Thompsona28eed82013-08-22 16:21:10 -0700335 struct apply
336 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700337 typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700338 FunctionPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700339 R NDNBOOST_FUNCTION_COMMA
340 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700341 >::type
342 invoker_type;
343
344 typedef functor_manager<FunctionPtr> manager_type;
345 };
346
347 template<typename FunctionPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700348 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS,
Jeff Thompsona28eed82013-08-22 16:21:10 -0700349 typename Allocator>
350 struct apply_a
351 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700352 typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700353 FunctionPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700354 R NDNBOOST_FUNCTION_COMMA
355 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700356 >::type
357 invoker_type;
358
359 typedef functor_manager<FunctionPtr> manager_type;
360 };
361 };
362
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700363#if NDNBOOST_FUNCTION_NUM_ARGS > 0
Jeff Thompsona28eed82013-08-22 16:21:10 -0700364 /* Retrieve the invoker for a member pointer. */
365 template<>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700366 struct NDNBOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
Jeff Thompsona28eed82013-08-22 16:21:10 -0700367 {
368 template<typename MemberPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700369 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
Jeff Thompsona28eed82013-08-22 16:21:10 -0700370 struct apply
371 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700372 typedef typename NDNBOOST_FUNCTION_GET_MEMBER_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700373 MemberPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700374 R NDNBOOST_FUNCTION_COMMA
375 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700376 >::type
377 invoker_type;
378
379 typedef functor_manager<MemberPtr> manager_type;
380 };
381
382 template<typename MemberPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700383 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS,
Jeff Thompsona28eed82013-08-22 16:21:10 -0700384 typename Allocator>
385 struct apply_a
386 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700387 typedef typename NDNBOOST_FUNCTION_GET_MEMBER_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700388 MemberPtr,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700389 R NDNBOOST_FUNCTION_COMMA
390 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700391 >::type
392 invoker_type;
393
394 typedef functor_manager<MemberPtr> manager_type;
395 };
396 };
397#endif
398
399 /* Retrieve the invoker for a function object. */
400 template<>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700401 struct NDNBOOST_FUNCTION_GET_INVOKER<function_obj_tag>
Jeff Thompsona28eed82013-08-22 16:21:10 -0700402 {
403 template<typename FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700404 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
Jeff Thompsona28eed82013-08-22 16:21:10 -0700405 struct apply
406 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700407 typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700408 FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700409 R NDNBOOST_FUNCTION_COMMA
410 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700411 >::type
412 invoker_type;
413
414 typedef functor_manager<FunctionObj> manager_type;
415 };
416
417 template<typename FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700418 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS,
Jeff Thompsona28eed82013-08-22 16:21:10 -0700419 typename Allocator>
420 struct apply_a
421 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700422 typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700423 FunctionObj,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700424 R NDNBOOST_FUNCTION_COMMA
425 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700426 >::type
427 invoker_type;
428
429 typedef functor_manager_a<FunctionObj, Allocator> manager_type;
430 };
431 };
432
433 /* Retrieve the invoker for a reference to a function object. */
434 template<>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700435 struct NDNBOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
Jeff Thompsona28eed82013-08-22 16:21:10 -0700436 {
437 template<typename RefWrapper,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700438 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
Jeff Thompsona28eed82013-08-22 16:21:10 -0700439 struct apply
440 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700441 typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700442 typename RefWrapper::type,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700443 R NDNBOOST_FUNCTION_COMMA
444 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700445 >::type
446 invoker_type;
447
448 typedef reference_manager<typename RefWrapper::type> manager_type;
449 };
450
451 template<typename RefWrapper,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700452 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS,
Jeff Thompsona28eed82013-08-22 16:21:10 -0700453 typename Allocator>
454 struct apply_a
455 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700456 typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
Jeff Thompsona28eed82013-08-22 16:21:10 -0700457 typename RefWrapper::type,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700458 R NDNBOOST_FUNCTION_COMMA
459 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700460 >::type
461 invoker_type;
462
463 typedef reference_manager<typename RefWrapper::type> manager_type;
464 };
465 };
466
467
468 /**
469 * vtable for a specific ndnboost::function instance. This
470 * structure must be an aggregate so that we can use static
471 * initialization in ndnboost::function's assign_to and assign_to_a
472 * members. It therefore cannot have any constructors,
473 * destructors, base classes, etc.
474 */
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700475 template<typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
476 struct NDNBOOST_FUNCTION_VTABLE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700477 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700478#ifndef NDNBOOST_NO_VOID_RETURNS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700479 typedef R result_type;
480#else
481 typedef typename function_return_type<R>::type result_type;
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700482#endif // NDNBOOST_NO_VOID_RETURNS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700483
484 typedef result_type (*invoker_type)(function_buffer&
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700485 NDNBOOST_FUNCTION_COMMA
486 NDNBOOST_FUNCTION_TEMPLATE_ARGS);
Jeff Thompsona28eed82013-08-22 16:21:10 -0700487
488 template<typename F>
489 bool assign_to(F f, function_buffer& functor) const
490 {
491 typedef typename get_function_tag<F>::type tag;
492 return assign_to(f, functor, tag());
493 }
494 template<typename F,typename Allocator>
495 bool assign_to_a(F f, function_buffer& functor, Allocator a) const
496 {
497 typedef typename get_function_tag<F>::type tag;
498 return assign_to_a(f, functor, a, tag());
499 }
500
501 void clear(function_buffer& functor) const
502 {
503 if (base.manager)
504 base.manager(functor, functor, destroy_functor_tag);
505 }
506
507 private:
508 // Function pointers
509 template<typename FunctionPtr>
510 bool
511 assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const
512 {
513 this->clear(functor);
514 if (f) {
515 // should be a reinterpret cast, but some compilers insist
516 // on giving cv-qualifiers to free functions
517 functor.func_ptr = reinterpret_cast<void (*)()>(f);
518 return true;
519 } else {
520 return false;
521 }
522 }
523 template<typename FunctionPtr,typename Allocator>
524 bool
525 assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const
526 {
527 return assign_to(f,functor,function_ptr_tag());
528 }
529
530 // Member pointers
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700531#if NDNBOOST_FUNCTION_NUM_ARGS > 0
Jeff Thompsona28eed82013-08-22 16:21:10 -0700532 template<typename MemberPtr>
533 bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const
534 {
535 // DPG TBD: Add explicit support for member function
536 // objects, so we invoke through mem_fn() but we retain the
537 // right target_type() values.
538 if (f) {
539 this->assign_to(ndnboost::mem_fn(f), functor);
540 return true;
541 } else {
542 return false;
543 }
544 }
545 template<typename MemberPtr,typename Allocator>
546 bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const
547 {
548 // DPG TBD: Add explicit support for member function
549 // objects, so we invoke through mem_fn() but we retain the
550 // right target_type() values.
551 if (f) {
552 this->assign_to_a(ndnboost::mem_fn(f), functor, a);
553 return true;
554 } else {
555 return false;
556 }
557 }
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700558#endif // NDNBOOST_FUNCTION_NUM_ARGS > 0
Jeff Thompsona28eed82013-08-22 16:21:10 -0700559
560 // Function objects
561 // Assign to a function object using the small object optimization
562 template<typename FunctionObj>
563 void
564 assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const
565 {
566 new (reinterpret_cast<void*>(&functor.data)) FunctionObj(f);
567 }
568 template<typename FunctionObj,typename Allocator>
569 void
570 assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_) const
571 {
572 assign_functor(f,functor,mpl::true_());
573 }
574
575 // Assign to a function object allocated on the heap.
576 template<typename FunctionObj>
577 void
578 assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) const
579 {
580 functor.obj_ptr = new FunctionObj(f);
581 }
582 template<typename FunctionObj,typename Allocator>
583 void
584 assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) const
585 {
586 typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
587 typedef typename Allocator::template rebind<functor_wrapper_type>::other
588 wrapper_allocator_type;
589 typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
590 wrapper_allocator_type wrapper_allocator(a);
591 wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
592 wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
593 functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
594 functor.obj_ptr = new_f;
595 }
596
597 template<typename FunctionObj>
598 bool
599 assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const
600 {
601 if (!ndnboost::detail::function::has_empty_target(ndnboost::addressof(f))) {
602 assign_functor(f, functor,
603 mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
604 return true;
605 } else {
606 return false;
607 }
608 }
609 template<typename FunctionObj,typename Allocator>
610 bool
611 assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const
612 {
613 if (!ndnboost::detail::function::has_empty_target(ndnboost::addressof(f))) {
614 assign_functor_a(f, functor, a,
615 mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
616 return true;
617 } else {
618 return false;
619 }
620 }
621
622 // Reference to a function object
623 template<typename FunctionObj>
624 bool
625 assign_to(const reference_wrapper<FunctionObj>& f,
626 function_buffer& functor, function_obj_ref_tag) const
627 {
628 functor.obj_ref.obj_ptr = (void *)(f.get_pointer());
629 functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
630 functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
631 return true;
632 }
633 template<typename FunctionObj,typename Allocator>
634 bool
635 assign_to_a(const reference_wrapper<FunctionObj>& f,
636 function_buffer& functor, Allocator, function_obj_ref_tag) const
637 {
638 return assign_to(f,functor,function_obj_ref_tag());
639 }
640
641 public:
642 vtable_base base;
643 invoker_type invoker;
644 };
645 } // end namespace function
646 } // end namespace detail
647
648 template<
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700649 typename R NDNBOOST_FUNCTION_COMMA
650 NDNBOOST_FUNCTION_TEMPLATE_PARMS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700651 >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700652 class NDNBOOST_FUNCTION_FUNCTION : public function_base
Jeff Thompsona28eed82013-08-22 16:21:10 -0700653
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700654#if NDNBOOST_FUNCTION_NUM_ARGS == 1
Jeff Thompsona28eed82013-08-22 16:21:10 -0700655
656 , public std::unary_function<T0,R>
657
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700658#elif NDNBOOST_FUNCTION_NUM_ARGS == 2
Jeff Thompsona28eed82013-08-22 16:21:10 -0700659
660 , public std::binary_function<T0,T1,R>
661
662#endif
663
664 {
665 public:
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700666#ifndef NDNBOOST_NO_VOID_RETURNS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700667 typedef R result_type;
668#else
669 typedef typename ndnboost::detail::function::function_return_type<R>::type
670 result_type;
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700671#endif // NDNBOOST_NO_VOID_RETURNS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700672
673 private:
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700674 typedef ndnboost::detail::function::NDNBOOST_FUNCTION_VTABLE<
675 R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_ARGS>
Jeff Thompsona28eed82013-08-22 16:21:10 -0700676 vtable_type;
677
678 vtable_type* get_vtable() const {
679 return reinterpret_cast<vtable_type*>(
680 reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01));
681 }
682
683 struct clear_type {};
684
685 public:
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700686 NDNBOOST_STATIC_CONSTANT(int, args = NDNBOOST_FUNCTION_NUM_ARGS);
Jeff Thompsona28eed82013-08-22 16:21:10 -0700687
688 // add signature for ndnboost::lambda
689 template<typename Args>
690 struct sig
691 {
692 typedef result_type type;
693 };
694
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700695#if NDNBOOST_FUNCTION_NUM_ARGS == 1
Jeff Thompsona28eed82013-08-22 16:21:10 -0700696 typedef T0 argument_type;
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700697#elif NDNBOOST_FUNCTION_NUM_ARGS == 2
Jeff Thompsona28eed82013-08-22 16:21:10 -0700698 typedef T0 first_argument_type;
699 typedef T1 second_argument_type;
700#endif
701
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700702 NDNBOOST_STATIC_CONSTANT(int, arity = NDNBOOST_FUNCTION_NUM_ARGS);
703 NDNBOOST_FUNCTION_ARG_TYPES
Jeff Thompsona28eed82013-08-22 16:21:10 -0700704
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700705 typedef NDNBOOST_FUNCTION_FUNCTION self_type;
Jeff Thompsona28eed82013-08-22 16:21:10 -0700706
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700707 NDNBOOST_FUNCTION_FUNCTION() : function_base() { }
Jeff Thompsona28eed82013-08-22 16:21:10 -0700708
709 // MSVC chokes if the following two constructors are collapsed into
710 // one with a default parameter.
711 template<typename Functor>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700712 NDNBOOST_FUNCTION_FUNCTION(Functor NDNBOOST_FUNCTION_TARGET_FIX(const &) f
713#ifndef NDNBOOST_NO_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700714 ,typename enable_if_c<
715 (ndnboost::type_traits::ice_not<
716 (is_integral<Functor>::value)>::value),
717 int>::type = 0
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700718#endif // NDNBOOST_NO_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700719 ) :
720 function_base()
721 {
722 this->assign_to(f);
723 }
724 template<typename Functor,typename Allocator>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700725 NDNBOOST_FUNCTION_FUNCTION(Functor NDNBOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
726#ifndef NDNBOOST_NO_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700727 ,typename enable_if_c<
728 (ndnboost::type_traits::ice_not<
729 (is_integral<Functor>::value)>::value),
730 int>::type = 0
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700731#endif // NDNBOOST_NO_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700732 ) :
733 function_base()
734 {
735 this->assign_to_a(f,a);
736 }
737
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700738#ifndef NDNBOOST_NO_SFINAE
739 NDNBOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
Jeff Thompsona28eed82013-08-22 16:21:10 -0700740#else
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700741 NDNBOOST_FUNCTION_FUNCTION(int zero) : function_base()
Jeff Thompsona28eed82013-08-22 16:21:10 -0700742 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700743 NDNBOOST_ASSERT(zero == 0);
Jeff Thompsona28eed82013-08-22 16:21:10 -0700744 }
745#endif
746
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700747 NDNBOOST_FUNCTION_FUNCTION(const NDNBOOST_FUNCTION_FUNCTION& f) : function_base()
Jeff Thompsona28eed82013-08-22 16:21:10 -0700748 {
749 this->assign_to_own(f);
750 }
751
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700752#ifndef NDNBOOST_NO_CXX11_RVALUE_REFERENCES
753 NDNBOOST_FUNCTION_FUNCTION(NDNBOOST_FUNCTION_FUNCTION&& f) : function_base()
Jeff Thompsona28eed82013-08-22 16:21:10 -0700754 {
755 this->move_assign(f);
756 }
757#endif
758
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700759 ~NDNBOOST_FUNCTION_FUNCTION() { clear(); }
Jeff Thompsona28eed82013-08-22 16:21:10 -0700760
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700761 result_type operator()(NDNBOOST_FUNCTION_PARMS) const
Jeff Thompsona28eed82013-08-22 16:21:10 -0700762 {
763 if (this->empty())
764 ndnboost::throw_exception(bad_function_call());
765
766 return get_vtable()->invoker
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700767 (this->functor NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_ARGS);
Jeff Thompsona28eed82013-08-22 16:21:10 -0700768 }
769
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700770 // The distinction between when to use NDNBOOST_FUNCTION_FUNCTION and
Jeff Thompsona28eed82013-08-22 16:21:10 -0700771 // when to use self_type is obnoxious. MSVC cannot handle self_type as
772 // the return type of these assignment operators, but Borland C++ cannot
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700773 // handle NDNBOOST_FUNCTION_FUNCTION as the type of the temporary to
Jeff Thompsona28eed82013-08-22 16:21:10 -0700774 // construct.
775 template<typename Functor>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700776#ifndef NDNBOOST_NO_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700777 typename enable_if_c<
778 (ndnboost::type_traits::ice_not<
779 (is_integral<Functor>::value)>::value),
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700780 NDNBOOST_FUNCTION_FUNCTION&>::type
Jeff Thompsona28eed82013-08-22 16:21:10 -0700781#else
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700782 NDNBOOST_FUNCTION_FUNCTION&
Jeff Thompsona28eed82013-08-22 16:21:10 -0700783#endif
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700784 operator=(Functor NDNBOOST_FUNCTION_TARGET_FIX(const &) f)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700785 {
786 this->clear();
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700787 NDNBOOST_TRY {
Jeff Thompsona28eed82013-08-22 16:21:10 -0700788 this->assign_to(f);
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700789 } NDNBOOST_CATCH (...) {
Jeff Thompsona28eed82013-08-22 16:21:10 -0700790 vtable = 0;
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700791 NDNBOOST_RETHROW;
Jeff Thompsona28eed82013-08-22 16:21:10 -0700792 }
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700793 NDNBOOST_CATCH_END
Jeff Thompsona28eed82013-08-22 16:21:10 -0700794 return *this;
795 }
796 template<typename Functor,typename Allocator>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700797 void assign(Functor NDNBOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700798 {
799 this->clear();
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700800 NDNBOOST_TRY{
Jeff Thompsona28eed82013-08-22 16:21:10 -0700801 this->assign_to_a(f,a);
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700802 } NDNBOOST_CATCH (...) {
Jeff Thompsona28eed82013-08-22 16:21:10 -0700803 vtable = 0;
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700804 NDNBOOST_RETHROW;
Jeff Thompsona28eed82013-08-22 16:21:10 -0700805 }
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700806 NDNBOOST_CATCH_END
Jeff Thompsona28eed82013-08-22 16:21:10 -0700807 }
808
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700809#ifndef NDNBOOST_NO_SFINAE
810 NDNBOOST_FUNCTION_FUNCTION& operator=(clear_type*)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700811 {
812 this->clear();
813 return *this;
814 }
815#else
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700816 NDNBOOST_FUNCTION_FUNCTION& operator=(int zero)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700817 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700818 NDNBOOST_ASSERT(zero == 0);
Jeff Thompsona28eed82013-08-22 16:21:10 -0700819 this->clear();
820 return *this;
821 }
822#endif
823
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700824 // Assignment from another NDNBOOST_FUNCTION_FUNCTION
825 NDNBOOST_FUNCTION_FUNCTION& operator=(const NDNBOOST_FUNCTION_FUNCTION& f)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700826 {
827 if (&f == this)
828 return *this;
829
830 this->clear();
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700831 NDNBOOST_TRY {
Jeff Thompsona28eed82013-08-22 16:21:10 -0700832 this->assign_to_own(f);
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700833 } NDNBOOST_CATCH (...) {
Jeff Thompsona28eed82013-08-22 16:21:10 -0700834 vtable = 0;
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700835 NDNBOOST_RETHROW;
Jeff Thompsona28eed82013-08-22 16:21:10 -0700836 }
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700837 NDNBOOST_CATCH_END
Jeff Thompsona28eed82013-08-22 16:21:10 -0700838 return *this;
839 }
840
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700841#ifndef NDNBOOST_NO_CXX11_RVALUE_REFERENCES
842 // Move assignment from another NDNBOOST_FUNCTION_FUNCTION
843 NDNBOOST_FUNCTION_FUNCTION& operator=(NDNBOOST_FUNCTION_FUNCTION&& f)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700844 {
845
846 if (&f == this)
847 return *this;
848
849 this->clear();
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700850 NDNBOOST_TRY {
Jeff Thompsona28eed82013-08-22 16:21:10 -0700851 this->move_assign(f);
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700852 } NDNBOOST_CATCH (...) {
Jeff Thompsona28eed82013-08-22 16:21:10 -0700853 vtable = 0;
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700854 NDNBOOST_RETHROW;
Jeff Thompsona28eed82013-08-22 16:21:10 -0700855 }
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700856 NDNBOOST_CATCH_END
Jeff Thompsona28eed82013-08-22 16:21:10 -0700857 return *this;
858 }
859#endif
860
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700861 void swap(NDNBOOST_FUNCTION_FUNCTION& other)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700862 {
863 if (&other == this)
864 return;
865
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700866 NDNBOOST_FUNCTION_FUNCTION tmp;
Jeff Thompsona28eed82013-08-22 16:21:10 -0700867 tmp.move_assign(*this);
868 this->move_assign(other);
869 other.move_assign(tmp);
870 }
871
872 // Clear out a target, if there is one
873 void clear()
874 {
875 if (vtable) {
876 if (!this->has_trivial_copy_and_destroy())
877 get_vtable()->clear(this->functor);
878 vtable = 0;
879 }
880 }
881
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700882#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined NDNBOOST_NO_COMPILER_CONFIG)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700883 // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
884 operator bool () const { return !this->empty(); }
885#else
886 private:
887 struct dummy {
888 void nonnull() {}
889 };
890
891 typedef void (dummy::*safe_bool)();
892
893 public:
894 operator safe_bool () const
895 { return (this->empty())? 0 : &dummy::nonnull; }
896
897 bool operator!() const
898 { return this->empty(); }
899#endif
900
901 private:
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700902 void assign_to_own(const NDNBOOST_FUNCTION_FUNCTION& f)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700903 {
904 if (!f.empty()) {
905 this->vtable = f.vtable;
906 if (this->has_trivial_copy_and_destroy())
907 this->functor = f.functor;
908 else
909 get_vtable()->base.manager(f.functor, this->functor,
910 ndnboost::detail::function::clone_functor_tag);
911 }
912 }
913
914 template<typename Functor>
915 void assign_to(Functor f)
916 {
917 using detail::function::vtable_base;
918
919 typedef typename detail::function::get_function_tag<Functor>::type tag;
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700920 typedef detail::function::NDNBOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
Jeff Thompsona28eed82013-08-22 16:21:10 -0700921 typedef typename get_invoker::
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700922 template apply<Functor, R NDNBOOST_FUNCTION_COMMA
923 NDNBOOST_FUNCTION_TEMPLATE_ARGS>
Jeff Thompsona28eed82013-08-22 16:21:10 -0700924 handler_type;
925
926 typedef typename handler_type::invoker_type invoker_type;
927 typedef typename handler_type::manager_type manager_type;
928
929 // Note: it is extremely important that this initialization use
930 // static initialization. Otherwise, we will have a race
931 // condition here in multi-threaded code. See
932 // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
933 static const vtable_type stored_vtable =
934 { { &manager_type::manage }, &invoker_type::invoke };
935
936 if (stored_vtable.assign_to(f, functor)) {
937 std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
938 if (ndnboost::has_trivial_copy_constructor<Functor>::value &&
939 ndnboost::has_trivial_destructor<Functor>::value &&
940 detail::function::function_allows_small_object_optimization<Functor>::value)
941 value |= static_cast<size_t>(0x01);
942 vtable = reinterpret_cast<detail::function::vtable_base *>(value);
943 } else
944 vtable = 0;
945 }
946
947 template<typename Functor,typename Allocator>
948 void assign_to_a(Functor f,Allocator a)
949 {
950 using detail::function::vtable_base;
951
952 typedef typename detail::function::get_function_tag<Functor>::type tag;
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700953 typedef detail::function::NDNBOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
Jeff Thompsona28eed82013-08-22 16:21:10 -0700954 typedef typename get_invoker::
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700955 template apply_a<Functor, R NDNBOOST_FUNCTION_COMMA
956 NDNBOOST_FUNCTION_TEMPLATE_ARGS,
Jeff Thompsona28eed82013-08-22 16:21:10 -0700957 Allocator>
958 handler_type;
959
960 typedef typename handler_type::invoker_type invoker_type;
961 typedef typename handler_type::manager_type manager_type;
962
963 // Note: it is extremely important that this initialization use
964 // static initialization. Otherwise, we will have a race
965 // condition here in multi-threaded code. See
966 // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
967 static const vtable_type stored_vtable =
968 { { &manager_type::manage }, &invoker_type::invoke };
969
970 if (stored_vtable.assign_to_a(f, functor, a)) {
971 std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
972 if (ndnboost::has_trivial_copy_constructor<Functor>::value &&
973 ndnboost::has_trivial_destructor<Functor>::value &&
974 detail::function::function_allows_small_object_optimization<Functor>::value)
975 value |= static_cast<std::size_t>(0x01);
976 vtable = reinterpret_cast<detail::function::vtable_base *>(value);
977 } else
978 vtable = 0;
979 }
980
981 // Moves the value from the specified argument to *this. If the argument
982 // has its function object allocated on the heap, move_assign will pass
983 // its buffer to *this, and set the argument's buffer pointer to NULL.
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700984 void move_assign(NDNBOOST_FUNCTION_FUNCTION& f)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700985 {
986 if (&f == this)
987 return;
988
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700989 NDNBOOST_TRY {
Jeff Thompsona28eed82013-08-22 16:21:10 -0700990 if (!f.empty()) {
991 this->vtable = f.vtable;
992 if (this->has_trivial_copy_and_destroy())
993 this->functor = f.functor;
994 else
995 get_vtable()->base.manager(f.functor, this->functor,
996 ndnboost::detail::function::move_functor_tag);
997 f.vtable = 0;
998 } else {
999 clear();
1000 }
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001001 } NDNBOOST_CATCH (...) {
Jeff Thompsona28eed82013-08-22 16:21:10 -07001002 vtable = 0;
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001003 NDNBOOST_RETHROW;
Jeff Thompsona28eed82013-08-22 16:21:10 -07001004 }
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001005 NDNBOOST_CATCH_END
Jeff Thompsona28eed82013-08-22 16:21:10 -07001006 }
1007 };
1008
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001009 template<typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
1010 inline void swap(NDNBOOST_FUNCTION_FUNCTION<
1011 R NDNBOOST_FUNCTION_COMMA
1012 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -07001013 >& f1,
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001014 NDNBOOST_FUNCTION_FUNCTION<
1015 R NDNBOOST_FUNCTION_COMMA
1016 NDNBOOST_FUNCTION_TEMPLATE_ARGS
Jeff Thompsona28eed82013-08-22 16:21:10 -07001017 >& f2)
1018 {
1019 f1.swap(f2);
1020 }
1021
1022// Poison comparisons between ndnboost::function objects of the same type.
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001023template<typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
1024 void operator==(const NDNBOOST_FUNCTION_FUNCTION<
1025 R NDNBOOST_FUNCTION_COMMA
1026 NDNBOOST_FUNCTION_TEMPLATE_ARGS>&,
1027 const NDNBOOST_FUNCTION_FUNCTION<
1028 R NDNBOOST_FUNCTION_COMMA
1029 NDNBOOST_FUNCTION_TEMPLATE_ARGS>&);
1030template<typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
1031 void operator!=(const NDNBOOST_FUNCTION_FUNCTION<
1032 R NDNBOOST_FUNCTION_COMMA
1033 NDNBOOST_FUNCTION_TEMPLATE_ARGS>&,
1034 const NDNBOOST_FUNCTION_FUNCTION<
1035 R NDNBOOST_FUNCTION_COMMA
1036 NDNBOOST_FUNCTION_TEMPLATE_ARGS>& );
Jeff Thompsona28eed82013-08-22 16:21:10 -07001037
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001038#if !defined(NDNBOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
Jeff Thompsona28eed82013-08-22 16:21:10 -07001039
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001040#if NDNBOOST_FUNCTION_NUM_ARGS == 0
1041#define NDNBOOST_FUNCTION_PARTIAL_SPEC R (void)
Jeff Thompsona28eed82013-08-22 16:21:10 -07001042#else
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001043#define NDNBOOST_FUNCTION_PARTIAL_SPEC R (NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_FUNCTION_NUM_ARGS,T))
Jeff Thompsona28eed82013-08-22 16:21:10 -07001044#endif
1045
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001046template<typename R NDNBOOST_FUNCTION_COMMA
1047 NDNBOOST_FUNCTION_TEMPLATE_PARMS>
1048class function<NDNBOOST_FUNCTION_PARTIAL_SPEC>
1049 : public NDNBOOST_FUNCTION_FUNCTION<R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_ARGS>
Jeff Thompsona28eed82013-08-22 16:21:10 -07001050{
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001051 typedef NDNBOOST_FUNCTION_FUNCTION<R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_ARGS> base_type;
Jeff Thompsona28eed82013-08-22 16:21:10 -07001052 typedef function self_type;
1053
1054 struct clear_type {};
1055
1056public:
1057
1058 function() : base_type() {}
1059
1060 template<typename Functor>
1061 function(Functor f
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001062#ifndef NDNBOOST_NO_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -07001063 ,typename enable_if_c<
1064 (ndnboost::type_traits::ice_not<
1065 (is_integral<Functor>::value)>::value),
1066 int>::type = 0
1067#endif
1068 ) :
1069 base_type(f)
1070 {
1071 }
1072 template<typename Functor,typename Allocator>
1073 function(Functor f, Allocator a
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001074#ifndef NDNBOOST_NO_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -07001075 ,typename enable_if_c<
1076 (ndnboost::type_traits::ice_not<
1077 (is_integral<Functor>::value)>::value),
1078 int>::type = 0
1079#endif
1080 ) :
1081 base_type(f,a)
1082 {
1083 }
1084
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001085#ifndef NDNBOOST_NO_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -07001086 function(clear_type*) : base_type() {}
1087#endif
1088
1089 function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
1090
1091 function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
1092
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001093#ifndef NDNBOOST_NO_CXX11_RVALUE_REFERENCES
Jeff Thompsona28eed82013-08-22 16:21:10 -07001094 // Move constructors
1095 function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
1096 function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
1097#endif
1098
1099 self_type& operator=(const self_type& f)
1100 {
1101 self_type(f).swap(*this);
1102 return *this;
1103 }
1104
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001105#ifndef NDNBOOST_NO_CXX11_RVALUE_REFERENCES
Jeff Thompsona28eed82013-08-22 16:21:10 -07001106 self_type& operator=(self_type&& f)
1107 {
1108 self_type(static_cast<self_type&&>(f)).swap(*this);
1109 return *this;
1110 }
1111#endif
1112
1113 template<typename Functor>
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001114#ifndef NDNBOOST_NO_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -07001115 typename enable_if_c<
1116 (ndnboost::type_traits::ice_not<
1117 (is_integral<Functor>::value)>::value),
1118 self_type&>::type
1119#else
1120 self_type&
1121#endif
1122 operator=(Functor f)
1123 {
1124 self_type(f).swap(*this);
1125 return *this;
1126 }
1127
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001128#ifndef NDNBOOST_NO_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -07001129 self_type& operator=(clear_type*)
1130 {
1131 this->clear();
1132 return *this;
1133 }
1134#endif
1135
1136 self_type& operator=(const base_type& f)
1137 {
1138 self_type(f).swap(*this);
1139 return *this;
1140 }
1141
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001142#ifndef NDNBOOST_NO_CXX11_RVALUE_REFERENCES
Jeff Thompsona28eed82013-08-22 16:21:10 -07001143 self_type& operator=(base_type&& f)
1144 {
1145 self_type(static_cast<base_type&&>(f)).swap(*this);
1146 return *this;
1147 }
1148#endif
1149};
1150
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001151#undef NDNBOOST_FUNCTION_PARTIAL_SPEC
Jeff Thompsona28eed82013-08-22 16:21:10 -07001152#endif // have partial specialization
1153
1154} // end namespace ndnboost
1155
1156// Cleanup after ourselves...
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001157#undef NDNBOOST_FUNCTION_VTABLE
1158#undef NDNBOOST_FUNCTION_COMMA
1159#undef NDNBOOST_FUNCTION_FUNCTION
1160#undef NDNBOOST_FUNCTION_FUNCTION_INVOKER
1161#undef NDNBOOST_FUNCTION_VOID_FUNCTION_INVOKER
1162#undef NDNBOOST_FUNCTION_FUNCTION_OBJ_INVOKER
1163#undef NDNBOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
1164#undef NDNBOOST_FUNCTION_FUNCTION_REF_INVOKER
1165#undef NDNBOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
1166#undef NDNBOOST_FUNCTION_MEMBER_INVOKER
1167#undef NDNBOOST_FUNCTION_VOID_MEMBER_INVOKER
1168#undef NDNBOOST_FUNCTION_GET_FUNCTION_INVOKER
1169#undef NDNBOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
1170#undef NDNBOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
1171#undef NDNBOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
1172#undef NDNBOOST_FUNCTION_GET_INVOKER
1173#undef NDNBOOST_FUNCTION_TEMPLATE_PARMS
1174#undef NDNBOOST_FUNCTION_TEMPLATE_ARGS
1175#undef NDNBOOST_FUNCTION_PARMS
1176#undef NDNBOOST_FUNCTION_PARM
1177#undef NDNBOOST_FUNCTION_ARGS
1178#undef NDNBOOST_FUNCTION_ARG_TYPE
1179#undef NDNBOOST_FUNCTION_ARG_TYPES
1180#undef NDNBOOST_FUNCTION_VOID_RETURN_TYPE
1181#undef NDNBOOST_FUNCTION_RETURN
Jeff Thompsona28eed82013-08-22 16:21:10 -07001182
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001183#if defined(NDNBOOST_MSVC)
Jeff Thompsona28eed82013-08-22 16:21:10 -07001184# pragma warning( pop )
1185#endif