1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/function/function_template.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,837 @@
1.4 +// Boost.Function library
1.5 +
1.6 +// Copyright Douglas Gregor 2001-2006. Use, modification and
1.7 +// distribution is subject to the Boost Software License, Version
1.8 +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
1.9 +// http://www.boost.org/LICENSE_1_0.txt)
1.10 +
1.11 +// For more information, see http://www.boost.org
1.12 +
1.13 +// Note: this header is a header template and must NOT have multiple-inclusion
1.14 +// protection.
1.15 +#include <boost/function/detail/prologue.hpp>
1.16 +
1.17 +#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
1.18 +
1.19 +#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
1.20 +
1.21 +#define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
1.22 +
1.23 +#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
1.24 +
1.25 +#define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
1.26 +
1.27 +#define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
1.28 + typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type);
1.29 +
1.30 +#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
1.31 +
1.32 +// Type of the default allocator
1.33 +#ifndef BOOST_NO_STD_ALLOCATOR
1.34 +# define BOOST_FUNCTION_DEFAULT_ALLOCATOR std::allocator<function_base>
1.35 +#else
1.36 +# define BOOST_FUNCTION_DEFAULT_ALLOCATOR int
1.37 +#endif // BOOST_NO_STD_ALLOCATOR
1.38 +
1.39 +// Comma if nonzero number of arguments
1.40 +#if BOOST_FUNCTION_NUM_ARGS == 0
1.41 +# define BOOST_FUNCTION_COMMA
1.42 +#else
1.43 +# define BOOST_FUNCTION_COMMA ,
1.44 +#endif // BOOST_FUNCTION_NUM_ARGS > 0
1.45 +
1.46 +// Class names used in this version of the code
1.47 +#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
1.48 +#define BOOST_FUNCTION_FUNCTION_INVOKER \
1.49 + BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
1.50 +#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
1.51 + BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
1.52 +#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
1.53 + BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
1.54 +#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
1.55 + BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
1.56 +#define BOOST_FUNCTION_FUNCTION_REF_INVOKER \
1.57 + BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
1.58 +#define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
1.59 + BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
1.60 +#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
1.61 + BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
1.62 +#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
1.63 + BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
1.64 +#define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
1.65 + BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
1.66 +#define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
1.67 +
1.68 +#ifndef BOOST_NO_VOID_RETURNS
1.69 +# define BOOST_FUNCTION_VOID_RETURN_TYPE void
1.70 +# define BOOST_FUNCTION_RETURN(X) X
1.71 +#else
1.72 +# define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
1.73 +# define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
1.74 +#endif
1.75 +
1.76 +#ifdef BOOST_MSVC
1.77 +# pragma warning(push)
1.78 +# pragma warning(disable: 4127) // conditional expression is constant.
1.79 +#endif
1.80 +
1.81 +#ifdef BOOST_MSVC
1.82 +# pragma warning(push)
1.83 +# pragma warning(disable: 4127) // conditional expression is constant.
1.84 +#endif
1.85 +
1.86 +namespace boost {
1.87 + namespace detail {
1.88 + namespace function {
1.89 + template<
1.90 + typename FunctionPtr,
1.91 + typename R BOOST_FUNCTION_COMMA
1.92 + BOOST_FUNCTION_TEMPLATE_PARMS
1.93 + >
1.94 + struct BOOST_FUNCTION_FUNCTION_INVOKER
1.95 + {
1.96 + static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
1.97 + BOOST_FUNCTION_PARMS)
1.98 + {
1.99 + FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
1.100 + return f(BOOST_FUNCTION_ARGS);
1.101 + }
1.102 + };
1.103 +
1.104 + template<
1.105 + typename FunctionPtr,
1.106 + typename R BOOST_FUNCTION_COMMA
1.107 + BOOST_FUNCTION_TEMPLATE_PARMS
1.108 + >
1.109 + struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
1.110 + {
1.111 + static BOOST_FUNCTION_VOID_RETURN_TYPE
1.112 + invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
1.113 + BOOST_FUNCTION_PARMS)
1.114 +
1.115 + {
1.116 + FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
1.117 + BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
1.118 + }
1.119 + };
1.120 +
1.121 + template<
1.122 + typename FunctionObj,
1.123 + typename R BOOST_FUNCTION_COMMA
1.124 + BOOST_FUNCTION_TEMPLATE_PARMS
1.125 + >
1.126 + struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
1.127 + {
1.128 + static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
1.129 + BOOST_FUNCTION_PARMS)
1.130 +
1.131 + {
1.132 + FunctionObj* f;
1.133 + if (function_allows_small_object_optimization<FunctionObj>::value)
1.134 + f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
1.135 + else
1.136 + f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
1.137 + return (*f)(BOOST_FUNCTION_ARGS);
1.138 + }
1.139 + };
1.140 +
1.141 + template<
1.142 + typename FunctionObj,
1.143 + typename R BOOST_FUNCTION_COMMA
1.144 + BOOST_FUNCTION_TEMPLATE_PARMS
1.145 + >
1.146 + struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
1.147 + {
1.148 + static BOOST_FUNCTION_VOID_RETURN_TYPE
1.149 + invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
1.150 + BOOST_FUNCTION_PARMS)
1.151 +
1.152 + {
1.153 + FunctionObj* f;
1.154 + if (function_allows_small_object_optimization<FunctionObj>::value)
1.155 + f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
1.156 + else
1.157 + f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
1.158 + BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
1.159 + }
1.160 + };
1.161 +
1.162 + template<
1.163 + typename FunctionObj,
1.164 + typename R BOOST_FUNCTION_COMMA
1.165 + BOOST_FUNCTION_TEMPLATE_PARMS
1.166 + >
1.167 + struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
1.168 + {
1.169 + static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
1.170 + BOOST_FUNCTION_PARMS)
1.171 +
1.172 + {
1.173 + FunctionObj* f =
1.174 + reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
1.175 + return (*f)(BOOST_FUNCTION_ARGS);
1.176 + }
1.177 + };
1.178 +
1.179 + template<
1.180 + typename FunctionObj,
1.181 + typename R BOOST_FUNCTION_COMMA
1.182 + BOOST_FUNCTION_TEMPLATE_PARMS
1.183 + >
1.184 + struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
1.185 + {
1.186 + static BOOST_FUNCTION_VOID_RETURN_TYPE
1.187 + invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
1.188 + BOOST_FUNCTION_PARMS)
1.189 +
1.190 + {
1.191 + FunctionObj* f =
1.192 + reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
1.193 + BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
1.194 + }
1.195 + };
1.196 +
1.197 + template<
1.198 + typename FunctionPtr,
1.199 + typename R BOOST_FUNCTION_COMMA
1.200 + BOOST_FUNCTION_TEMPLATE_PARMS
1.201 + >
1.202 + struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
1.203 + {
1.204 + typedef typename mpl::if_c<(is_void<R>::value),
1.205 + BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
1.206 + FunctionPtr,
1.207 + R BOOST_FUNCTION_COMMA
1.208 + BOOST_FUNCTION_TEMPLATE_ARGS
1.209 + >,
1.210 + BOOST_FUNCTION_FUNCTION_INVOKER<
1.211 + FunctionPtr,
1.212 + R BOOST_FUNCTION_COMMA
1.213 + BOOST_FUNCTION_TEMPLATE_ARGS
1.214 + >
1.215 + >::type type;
1.216 + };
1.217 +
1.218 + template<
1.219 + typename FunctionObj,
1.220 + typename R BOOST_FUNCTION_COMMA
1.221 + BOOST_FUNCTION_TEMPLATE_PARMS
1.222 + >
1.223 + struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
1.224 + {
1.225 + typedef typename mpl::if_c<(is_void<R>::value),
1.226 + BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
1.227 + FunctionObj,
1.228 + R BOOST_FUNCTION_COMMA
1.229 + BOOST_FUNCTION_TEMPLATE_ARGS
1.230 + >,
1.231 + BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
1.232 + FunctionObj,
1.233 + R BOOST_FUNCTION_COMMA
1.234 + BOOST_FUNCTION_TEMPLATE_ARGS
1.235 + >
1.236 + >::type type;
1.237 + };
1.238 +
1.239 + template<
1.240 + typename FunctionObj,
1.241 + typename R BOOST_FUNCTION_COMMA
1.242 + BOOST_FUNCTION_TEMPLATE_PARMS
1.243 + >
1.244 + struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
1.245 + {
1.246 + typedef typename mpl::if_c<(is_void<R>::value),
1.247 + BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
1.248 + FunctionObj,
1.249 + R BOOST_FUNCTION_COMMA
1.250 + BOOST_FUNCTION_TEMPLATE_ARGS
1.251 + >,
1.252 + BOOST_FUNCTION_FUNCTION_REF_INVOKER<
1.253 + FunctionObj,
1.254 + R BOOST_FUNCTION_COMMA
1.255 + BOOST_FUNCTION_TEMPLATE_ARGS
1.256 + >
1.257 + >::type type;
1.258 + };
1.259 +
1.260 + /**
1.261 + * vtable for a specific boost::function instance.
1.262 + */
1.263 + template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
1.264 + typename Allocator>
1.265 + struct BOOST_FUNCTION_VTABLE : vtable_base
1.266 + {
1.267 +#ifndef BOOST_NO_VOID_RETURNS
1.268 + typedef R result_type;
1.269 +#else
1.270 + typedef typename function_return_type<R>::type result_type;
1.271 +#endif // BOOST_NO_VOID_RETURNS
1.272 +
1.273 + typedef result_type (*invoker_type)(function_buffer&
1.274 + BOOST_FUNCTION_COMMA
1.275 + BOOST_FUNCTION_TEMPLATE_ARGS);
1.276 +
1.277 + template<typename F>
1.278 + BOOST_FUNCTION_VTABLE(F f) : vtable_base(), invoker(0)
1.279 + {
1.280 + init(f);
1.281 + }
1.282 +
1.283 + template<typename F>
1.284 + bool assign_to(F f, function_buffer& functor)
1.285 + {
1.286 + typedef typename get_function_tag<F>::type tag;
1.287 + return assign_to(f, functor, tag());
1.288 + }
1.289 +
1.290 + void clear(function_buffer& functor)
1.291 + {
1.292 + if (manager)
1.293 + manager(functor, functor, destroy_functor_tag);
1.294 + }
1.295 +
1.296 + private:
1.297 + template<typename F>
1.298 + void init(F f)
1.299 + {
1.300 + typedef typename get_function_tag<F>::type tag;
1.301 + init(f, tag());
1.302 + }
1.303 +
1.304 + // Function pointers
1.305 + template<typename FunctionPtr>
1.306 + void init(FunctionPtr /*f*/, function_ptr_tag)
1.307 + {
1.308 + typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
1.309 + FunctionPtr,
1.310 + R BOOST_FUNCTION_COMMA
1.311 + BOOST_FUNCTION_TEMPLATE_ARGS
1.312 + >::type
1.313 + actual_invoker_type;
1.314 +
1.315 + invoker = &actual_invoker_type::invoke;
1.316 + manager = &functor_manager<FunctionPtr, Allocator>::manage;
1.317 + }
1.318 +
1.319 + template<typename FunctionPtr>
1.320 + bool
1.321 + assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag)
1.322 + {
1.323 + this->clear(functor);
1.324 + if (f) {
1.325 + // should be a reinterpret cast, but some compilers insist
1.326 + // on giving cv-qualifiers to free functions
1.327 + functor.func_ptr = (void (*)())(f);
1.328 + return true;
1.329 + } else {
1.330 + return false;
1.331 + }
1.332 + }
1.333 +
1.334 + // Member pointers
1.335 +#if BOOST_FUNCTION_NUM_ARGS > 0
1.336 + template<typename MemberPtr>
1.337 + void init(MemberPtr f, member_ptr_tag)
1.338 + {
1.339 + // DPG TBD: Add explicit support for member function
1.340 + // objects, so we invoke through mem_fn() but we retain the
1.341 + // right target_type() values.
1.342 + this->init(mem_fn(f));
1.343 + }
1.344 +
1.345 + template<typename MemberPtr>
1.346 + bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag)
1.347 + {
1.348 + // DPG TBD: Add explicit support for member function
1.349 + // objects, so we invoke through mem_fn() but we retain the
1.350 + // right target_type() values.
1.351 + if (f) {
1.352 + this->assign_to(mem_fn(f), functor);
1.353 + return true;
1.354 + } else {
1.355 + return false;
1.356 + }
1.357 + }
1.358 +#endif // BOOST_FUNCTION_NUM_ARGS > 0
1.359 +
1.360 + // Function objects
1.361 + template<typename FunctionObj>
1.362 + void init(FunctionObj /*f*/, function_obj_tag)
1.363 + {
1.364 + typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
1.365 + FunctionObj,
1.366 + R BOOST_FUNCTION_COMMA
1.367 + BOOST_FUNCTION_TEMPLATE_ARGS
1.368 + >::type
1.369 + actual_invoker_type;
1.370 +
1.371 + invoker = &actual_invoker_type::invoke;
1.372 + manager = &functor_manager<FunctionObj, Allocator>::manage;
1.373 + }
1.374 +
1.375 + // Assign to a function object using the small object optimization
1.376 + template<typename FunctionObj>
1.377 + void
1.378 + assign_functor(FunctionObj f, function_buffer& functor, mpl::true_)
1.379 + {
1.380 + new ((void*)&functor.data) FunctionObj(f);
1.381 + }
1.382 +
1.383 + // Assign to a function object allocated on the heap.
1.384 + template<typename FunctionObj>
1.385 + void
1.386 + assign_functor(FunctionObj f, function_buffer& functor, mpl::false_)
1.387 + {
1.388 +#ifndef BOOST_NO_STD_ALLOCATOR
1.389 + typedef typename Allocator::template rebind<FunctionObj>::other
1.390 + allocator_type;
1.391 + typedef typename allocator_type::pointer pointer_type;
1.392 +
1.393 + allocator_type allocator;
1.394 + pointer_type copy = allocator.allocate(1);
1.395 + allocator.construct(copy, f);
1.396 +
1.397 + // Get back to the original pointer type
1.398 + functor.obj_ptr = static_cast<FunctionObj*>(copy);
1.399 +# else
1.400 + functor.obj_ptr = new FunctionObj(f);
1.401 +# endif // BOOST_NO_STD_ALLOCATOR
1.402 + }
1.403 +
1.404 + template<typename FunctionObj>
1.405 + bool
1.406 + assign_to(FunctionObj f, function_buffer& functor, function_obj_tag)
1.407 + {
1.408 + if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
1.409 + assign_functor(f, functor,
1.410 + mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
1.411 + return true;
1.412 + } else {
1.413 + return false;
1.414 + }
1.415 + }
1.416 +
1.417 + // Reference to a function object
1.418 + template<typename FunctionObj>
1.419 + void
1.420 + init(const reference_wrapper<FunctionObj>& /*f*/, function_obj_ref_tag)
1.421 + {
1.422 + typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
1.423 + FunctionObj,
1.424 + R BOOST_FUNCTION_COMMA
1.425 + BOOST_FUNCTION_TEMPLATE_ARGS
1.426 + >::type
1.427 + actual_invoker_type;
1.428 +
1.429 + invoker = &actual_invoker_type::invoke;
1.430 + manager = &reference_manager<FunctionObj>::get;
1.431 + }
1.432 +
1.433 + template<typename FunctionObj>
1.434 + bool
1.435 + assign_to(const reference_wrapper<FunctionObj>& f,
1.436 + function_buffer& functor, function_obj_ref_tag)
1.437 + {
1.438 + if (!boost::detail::function::has_empty_target(f.get_pointer())) {
1.439 + // DPG TBD: We might need to detect constness of
1.440 + // FunctionObj to assign into obj_ptr or const_obj_ptr to
1.441 + // be truly legit, but no platform in existence makes
1.442 + // const void* different from void*.
1.443 + functor.const_obj_ptr = f.get_pointer();
1.444 + return true;
1.445 + } else {
1.446 + return false;
1.447 + }
1.448 + }
1.449 +
1.450 + public:
1.451 + invoker_type invoker;
1.452 + };
1.453 + } // end namespace function
1.454 + } // end namespace detail
1.455 +
1.456 + template<
1.457 + typename R BOOST_FUNCTION_COMMA
1.458 + BOOST_FUNCTION_TEMPLATE_PARMS,
1.459 + typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
1.460 + >
1.461 + class BOOST_FUNCTION_FUNCTION : public function_base
1.462 + {
1.463 + public:
1.464 +#ifndef BOOST_NO_VOID_RETURNS
1.465 + typedef R result_type;
1.466 +#else
1.467 + typedef typename boost::detail::function::function_return_type<R>::type
1.468 + result_type;
1.469 +#endif // BOOST_NO_VOID_RETURNS
1.470 +
1.471 + private:
1.472 + typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
1.473 + R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS, Allocator>
1.474 + vtable_type;
1.475 +
1.476 + struct clear_type {};
1.477 +
1.478 + public:
1.479 + BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
1.480 +
1.481 + // add signature for boost::lambda
1.482 + template<typename Args>
1.483 + struct sig
1.484 + {
1.485 + typedef result_type type;
1.486 + };
1.487 +
1.488 +#if BOOST_FUNCTION_NUM_ARGS == 1
1.489 + typedef T0 argument_type;
1.490 +#elif BOOST_FUNCTION_NUM_ARGS == 2
1.491 + typedef T0 first_argument_type;
1.492 + typedef T1 second_argument_type;
1.493 +#endif
1.494 +
1.495 + BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
1.496 + BOOST_FUNCTION_ARG_TYPES
1.497 +
1.498 + typedef Allocator allocator_type;
1.499 + typedef BOOST_FUNCTION_FUNCTION self_type;
1.500 +
1.501 + BOOST_FUNCTION_FUNCTION() : function_base() { }
1.502 +
1.503 + // MSVC chokes if the following two constructors are collapsed into
1.504 + // one with a default parameter.
1.505 + template<typename Functor>
1.506 + BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
1.507 +#ifndef BOOST_NO_SFINAE
1.508 + ,typename enable_if_c<
1.509 + (boost::type_traits::ice_not<
1.510 + (is_integral<Functor>::value)>::value),
1.511 + int>::type = 0
1.512 +#endif // BOOST_NO_SFINAE
1.513 + ) :
1.514 + function_base()
1.515 + {
1.516 + this->assign_to(f);
1.517 + }
1.518 +
1.519 +#ifndef BOOST_NO_SFINAE
1.520 + BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
1.521 +#else
1.522 + BOOST_FUNCTION_FUNCTION(int zero) : function_base()
1.523 + {
1.524 + BOOST_ASSERT(zero == 0);
1.525 + }
1.526 +#endif
1.527 +
1.528 + BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
1.529 + {
1.530 + this->assign_to_own(f);
1.531 + }
1.532 +
1.533 + ~BOOST_FUNCTION_FUNCTION() { clear(); }
1.534 +
1.535 +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
1.536 + // MSVC 6.0 and prior require all definitions to be inline, but
1.537 + // these definitions can become very costly.
1.538 + result_type operator()(BOOST_FUNCTION_PARMS) const
1.539 + {
1.540 + if (this->empty())
1.541 + boost::throw_exception(bad_function_call());
1.542 +
1.543 + return static_cast<vtable_type*>(vtable)->invoker
1.544 + (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
1.545 + }
1.546 +#else
1.547 + result_type operator()(BOOST_FUNCTION_PARMS) const;
1.548 +#endif
1.549 +
1.550 + // The distinction between when to use BOOST_FUNCTION_FUNCTION and
1.551 + // when to use self_type is obnoxious. MSVC cannot handle self_type as
1.552 + // the return type of these assignment operators, but Borland C++ cannot
1.553 + // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
1.554 + // construct.
1.555 + template<typename Functor>
1.556 +#ifndef BOOST_NO_SFINAE
1.557 + typename enable_if_c<
1.558 + (boost::type_traits::ice_not<
1.559 + (is_integral<Functor>::value)>::value),
1.560 + BOOST_FUNCTION_FUNCTION&>::type
1.561 +#else
1.562 + BOOST_FUNCTION_FUNCTION&
1.563 +#endif
1.564 + operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
1.565 + {
1.566 + this->clear();
1.567 + try {
1.568 + this->assign_to(f);
1.569 + } catch (...) {
1.570 + vtable = 0;
1.571 + throw;
1.572 + }
1.573 + return *this;
1.574 + }
1.575 +
1.576 +#ifndef BOOST_NO_SFINAE
1.577 + BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
1.578 + {
1.579 + this->clear();
1.580 + return *this;
1.581 + }
1.582 +#else
1.583 + BOOST_FUNCTION_FUNCTION& operator=(int zero)
1.584 + {
1.585 + BOOST_ASSERT(zero == 0);
1.586 + this->clear();
1.587 + return *this;
1.588 + }
1.589 +#endif
1.590 +
1.591 + // Assignment from another BOOST_FUNCTION_FUNCTION
1.592 + BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
1.593 + {
1.594 + if (&f == this)
1.595 + return *this;
1.596 +
1.597 + this->clear();
1.598 + try {
1.599 + this->assign_to_own(f);
1.600 + } catch (...) {
1.601 + vtable = 0;
1.602 + throw;
1.603 + }
1.604 + return *this;
1.605 + }
1.606 +
1.607 + void swap(BOOST_FUNCTION_FUNCTION& other)
1.608 + {
1.609 + if (&other == this)
1.610 + return;
1.611 +
1.612 + BOOST_FUNCTION_FUNCTION tmp = *this;
1.613 + *this = other;
1.614 + other = tmp;
1.615 + }
1.616 +
1.617 + // Clear out a target, if there is one
1.618 + void clear()
1.619 + {
1.620 + if (vtable) {
1.621 + static_cast<vtable_type*>(vtable)->clear(this->functor);
1.622 + vtable = 0;
1.623 + }
1.624 + }
1.625 +
1.626 +#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
1.627 + // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
1.628 + operator bool () const { return !this->empty(); }
1.629 +#else
1.630 + private:
1.631 + struct dummy {
1.632 + void nonnull() {};
1.633 + };
1.634 +
1.635 + typedef void (dummy::*safe_bool)();
1.636 +
1.637 + public:
1.638 + operator safe_bool () const
1.639 + { return (this->empty())? 0 : &dummy::nonnull; }
1.640 +
1.641 + bool operator!() const
1.642 + { return this->empty(); }
1.643 +#endif
1.644 +
1.645 + private:
1.646 + void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
1.647 + {
1.648 + if (!f.empty()) {
1.649 + this->vtable = f.vtable;
1.650 + f.vtable->manager(f.functor, this->functor,
1.651 + boost::detail::function::clone_functor_tag);
1.652 + }
1.653 + }
1.654 +
1.655 + template<typename Functor>
1.656 + void assign_to(Functor f)
1.657 + {
1.658 + static vtable_type stored_vtable(f);
1.659 + if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable;
1.660 + else vtable = 0;
1.661 + }
1.662 + };
1.663 +
1.664 + template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
1.665 + typename Allocator>
1.666 + inline void swap(BOOST_FUNCTION_FUNCTION<
1.667 + R BOOST_FUNCTION_COMMA
1.668 + BOOST_FUNCTION_TEMPLATE_ARGS ,
1.669 + Allocator
1.670 + >& f1,
1.671 + BOOST_FUNCTION_FUNCTION<
1.672 + R BOOST_FUNCTION_COMMA
1.673 + BOOST_FUNCTION_TEMPLATE_ARGS,
1.674 + Allocator
1.675 + >& f2)
1.676 + {
1.677 + f1.swap(f2);
1.678 + }
1.679 +
1.680 +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
1.681 + template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
1.682 + typename Allocator>
1.683 + typename BOOST_FUNCTION_FUNCTION<
1.684 + R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS,
1.685 + Allocator>::result_type
1.686 + BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS,
1.687 +
1.688 + Allocator>
1.689 + ::operator()(BOOST_FUNCTION_PARMS) const
1.690 + {
1.691 + if (this->empty())
1.692 + boost::throw_exception(bad_function_call());
1.693 +
1.694 + return static_cast<vtable_type*>(vtable)->invoker
1.695 + (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
1.696 + }
1.697 +#endif
1.698 +
1.699 +// Poison comparisons between boost::function objects of the same type.
1.700 +template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
1.701 + typename Allocator>
1.702 + void operator==(const BOOST_FUNCTION_FUNCTION<
1.703 + R BOOST_FUNCTION_COMMA
1.704 + BOOST_FUNCTION_TEMPLATE_ARGS ,
1.705 + Allocator>&,
1.706 + const BOOST_FUNCTION_FUNCTION<
1.707 + R BOOST_FUNCTION_COMMA
1.708 + BOOST_FUNCTION_TEMPLATE_ARGS ,
1.709 + Allocator>&);
1.710 +template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
1.711 + typename Allocator>
1.712 + void operator!=(const BOOST_FUNCTION_FUNCTION<
1.713 + R BOOST_FUNCTION_COMMA
1.714 + BOOST_FUNCTION_TEMPLATE_ARGS ,
1.715 + Allocator>&,
1.716 + const BOOST_FUNCTION_FUNCTION<
1.717 + R BOOST_FUNCTION_COMMA
1.718 + BOOST_FUNCTION_TEMPLATE_ARGS ,
1.719 + Allocator>&);
1.720 +
1.721 +#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
1.722 +
1.723 +#if BOOST_FUNCTION_NUM_ARGS == 0
1.724 +#define BOOST_FUNCTION_PARTIAL_SPEC R (void)
1.725 +#else
1.726 +#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
1.727 +#endif
1.728 +
1.729 +template<typename R BOOST_FUNCTION_COMMA
1.730 + BOOST_FUNCTION_TEMPLATE_PARMS,
1.731 + typename Allocator>
1.732 +class function<BOOST_FUNCTION_PARTIAL_SPEC, Allocator>
1.733 + : public BOOST_FUNCTION_FUNCTION<R, BOOST_FUNCTION_TEMPLATE_ARGS
1.734 + BOOST_FUNCTION_COMMA Allocator>
1.735 +{
1.736 + typedef BOOST_FUNCTION_FUNCTION<R, BOOST_FUNCTION_TEMPLATE_ARGS
1.737 + BOOST_FUNCTION_COMMA Allocator> base_type;
1.738 + typedef function self_type;
1.739 +
1.740 + struct clear_type {};
1.741 +
1.742 +public:
1.743 + typedef typename base_type::allocator_type allocator_type;
1.744 +
1.745 + function() : base_type() {}
1.746 +
1.747 + template<typename Functor>
1.748 + function(Functor f
1.749 +#ifndef BOOST_NO_SFINAE
1.750 + ,typename enable_if_c<
1.751 + (boost::type_traits::ice_not<
1.752 + (is_integral<Functor>::value)>::value),
1.753 + int>::type = 0
1.754 +#endif
1.755 + ) :
1.756 + base_type(f)
1.757 + {
1.758 + }
1.759 +
1.760 +#ifndef BOOST_NO_SFINAE
1.761 + function(clear_type*) : base_type() {}
1.762 +#endif
1.763 +
1.764 + function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
1.765 +
1.766 + function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
1.767 +
1.768 + self_type& operator=(const self_type& f)
1.769 + {
1.770 + self_type(f).swap(*this);
1.771 + return *this;
1.772 + }
1.773 +
1.774 + template<typename Functor>
1.775 +#ifndef BOOST_NO_SFINAE
1.776 + typename enable_if_c<
1.777 + (boost::type_traits::ice_not<
1.778 + (is_integral<Functor>::value)>::value),
1.779 + self_type&>::type
1.780 +#else
1.781 + self_type&
1.782 +#endif
1.783 + operator=(Functor f)
1.784 + {
1.785 + self_type(f).swap(*this);
1.786 + return *this;
1.787 + }
1.788 +
1.789 +#ifndef BOOST_NO_SFINAE
1.790 + self_type& operator=(clear_type*)
1.791 + {
1.792 + this->clear();
1.793 + return *this;
1.794 + }
1.795 +#endif
1.796 +
1.797 + self_type& operator=(const base_type& f)
1.798 + {
1.799 + self_type(f).swap(*this);
1.800 + return *this;
1.801 + }
1.802 +};
1.803 +
1.804 +#ifdef BOOST_MSVC
1.805 +# pragma warning(pop)
1.806 +#endif
1.807 +
1.808 +#undef BOOST_FUNCTION_PARTIAL_SPEC
1.809 +#endif // have partial specialization
1.810 +
1.811 +} // end namespace boost
1.812 +
1.813 +#ifdef BOOST_MSVC
1.814 +# pragma warning(pop)
1.815 +#endif
1.816 +
1.817 +// Cleanup after ourselves...
1.818 +#undef BOOST_FUNCTION_VTABLE
1.819 +#undef BOOST_FUNCTION_DEFAULT_ALLOCATOR
1.820 +#undef BOOST_FUNCTION_COMMA
1.821 +#undef BOOST_FUNCTION_FUNCTION
1.822 +#undef BOOST_FUNCTION_FUNCTION_INVOKER
1.823 +#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
1.824 +#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
1.825 +#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
1.826 +#undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
1.827 +#undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
1.828 +#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
1.829 +#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
1.830 +#undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
1.831 +#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
1.832 +#undef BOOST_FUNCTION_TEMPLATE_PARMS
1.833 +#undef BOOST_FUNCTION_TEMPLATE_ARGS
1.834 +#undef BOOST_FUNCTION_PARMS
1.835 +#undef BOOST_FUNCTION_PARM
1.836 +#undef BOOST_FUNCTION_ARGS
1.837 +#undef BOOST_FUNCTION_ARG_TYPE
1.838 +#undef BOOST_FUNCTION_ARG_TYPES
1.839 +#undef BOOST_FUNCTION_VOID_RETURN_TYPE
1.840 +#undef BOOST_FUNCTION_RETURN