Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r52778 - sandbox/boost0x/boost/function
From: gordon_at_[hidden]
Date: 2009-05-05 18:58:37


Author: gordon.woodhull
Date: 2009-05-05 18:58:36 EDT (Tue, 05 May 2009)
New Revision: 52778
URL: http://svn.boost.org/trac/boost/changeset/52778

Log:
add invoker and vtable
Added:
   sandbox/boost0x/boost/function/function_variadic_invoker.hpp (contents, props changed)
   sandbox/boost0x/boost/function/function_variadic_vtable.hpp (contents, props changed)

Added: sandbox/boost0x/boost/function/function_variadic_invoker.hpp
==============================================================================
--- (empty file)
+++ sandbox/boost0x/boost/function/function_variadic_invoker.hpp 2009-05-05 18:58:36 EDT (Tue, 05 May 2009)
@@ -0,0 +1,378 @@
+namespace boost {
+ namespace detail {
+ namespace function {
+ template<
+ typename FunctionPtr,
+ typename R,
+ typename ... Args
+ >
+ struct function_invoker
+ {
+ static R invoke(function_buffer& function_ptr, Args... args)
+ {
+ FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
+ return f(args...);
+ }
+ };
+
+ template<
+ typename FunctionPtr,
+ typename R,
+
 typename ... Args
+ >
+ struct void_function_invoker
+ {
+ static BOOST_FUNCTION_VOID_RETURN_TYPE
+ invoke(function_buffer& function_ptr, Args... args)
+
+ {
+ FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
+ BOOST_FUNCTION_RETURN(f(args...));
+ }
+ };
+
+ template<
+ typename FunctionObj,
+ typename R,
+
 typename ... Args
+ >
+ struct function_obj_invoker
+ {
+ static R invoke(function_buffer& function_obj_ptr, Args... args)
+
+ {
+ FunctionObj* f;
+ if (function_allows_small_object_optimization<FunctionObj>::value)
+ f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
+ else
+ f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+ return (*f)(args...);
+ }
+ };
+
+ template<
+ typename FunctionObj,
+ typename R,
+
 typename ... Args
+ >
+ struct void_function_obj_invoker
+ {
+ static BOOST_FUNCTION_VOID_RETURN_TYPE
+ invoke(function_buffer& function_obj_ptr, Args... args)
+
+ {
+ FunctionObj* f;
+ if (function_allows_small_object_optimization<FunctionObj>::value)
+ f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
+ else
+ f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+ BOOST_FUNCTION_RETURN((*f)(args...));
+ }
+ };
+
+ template<
+ typename FunctionObj,
+ typename R,
+
 typename ... Args
+ >
+ struct function_ref_invoker
+ {
+ static R invoke(function_buffer& function_obj_ptr, Args... args)
+
+ {
+ FunctionObj* f =
+ reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+ return (*f)(args...);
+ }
+ };
+
+ template<
+ typename FunctionObj,
+ typename R,
+
 typename ... Args
+ >
+ struct void_function_ref_invoker
+ {
+ static BOOST_FUNCTION_VOID_RETURN_TYPE
+ invoke(function_buffer& function_obj_ptr, Args... args)
+
+ {
+ FunctionObj* f =
+ reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+ BOOST_FUNCTION_RETURN((*f)(args...));
+ }
+ };
+
+#if BOOST_FUNCTION_NUM_ARGS > 0
+ /* Handle invocation of member pointers. */
+ template<
+ typename MemberPtr,
+ typename R,
+
 typename ... Args
+ >
+ struct function_mem_invoker
+ {
+ static R invoke(function_buffer& function_obj_ptr, Args... args)
+
+ {
+ MemberPtr* f =
+ reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
+ return boost::mem_fn(*f)(args...);
+ }
+ };
+
+ template<
+ typename MemberPtr,
+ typename R,
+
 typename ... Args
+ >
+ struct function_void_mem_invoker
+ {
+ static BOOST_FUNCTION_VOID_RETURN_TYPE
+ invoke(function_buffer& function_obj_ptr, Args... args)
+
+ {
+ MemberPtr* f =
+ reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
+ BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(args...));
+ }
+ };
+#endif
+
+ template<
+ typename FunctionPtr,
+ typename R,
+
 typename ... Args
+ >
+ struct get_function_invoker
+ {
+ typedef typename mpl::if_c<(is_void<R>::value),
+ void_function_invoker<
+ FunctionPtr,
+ R,
+
 Args...
+ >,
+ function_invoker<
+ FunctionPtr,
+ R,
+
 Args...
+ >
+ >::type type;
+ };
+
+ template<
+ typename FunctionObj,
+ typename R,
+
 typename ... Args
+ >
+ struct get_function_obj_invoker
+ {
+ typedef typename mpl::if_c<(is_void<R>::value),
+ void_function_obj_invoker<
+ FunctionObj,
+ R,
+
 Args...
+ >,
+ function_obj_invoker<
+ FunctionObj,
+ R,
+
 Args...
+ >
+ >::type type;
+ };
+
+ template<
+ typename FunctionObj,
+ typename R,
+
 typename ... Args
+ >
+ struct get_function_ref_invoker
+ {
+ typedef typename mpl::if_c<(is_void<R>::value),
+ BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
+ FunctionObj,
+ R,
+
 Args...
+ >,
+ function_ref_invoker<
+ FunctionObj,
+ R,
+
 Args...
+ >
+ >::type type;
+ };
+
+#if BOOST_FUNCTION_NUM_ARGS > 0
+ /* Retrieve the appropriate invoker for a member pointer. */
+ template<
+ typename MemberPtr,
+ typename R,
+
 typename ... Args
+ >
+ struct get_member_invoker
+ {
+ typedef typename mpl::if_c<(is_void<R>::value),
+ function_void_mem_invoker<
+ MemberPtr,
+ R,
+
 Args...
+ >,
+ function_mem_invoker<
+ MemberPtr,
+ R,
+
 Args...
+ >
+ >::type type;
+ };
+#endif
+
+ /* Given the tag returned by get_function_tag, retrieve the
+ actual invoker that will be used for the given function
+ object.
+
+ Each specialization contains an "apply" nested class template
+ that accepts the function object, return type, function
+ argument types, and allocator. The resulting "apply" class
+ contains two typedefs, "invoker_type" and "manager_type",
+ which correspond to the invoker and manager types. */
+ template<typename Tag>
+ struct get_invoker { };
+
+ /* Retrieve the invoker for a function pointer. */
+ template<>
+ struct get_invoker<function_ptr_tag>
+ {
+ template<typename FunctionPtr,
+ typename R, typename ... Args>
+ struct apply
+ {
+ typedef typename get_function_invoker<
+ FunctionPtr,
+ R,
+
 Args...
+ >::type
+ invoker_type;
+
+ typedef functor_manager<FunctionPtr> manager_type;
+ };
+
+ template<typename FunctionPtr,
+ typename R, typename ... Args,
+ typename Allocator>
+ struct apply_a
+ {
+ typedef typename get_function_invoker<
+ FunctionPtr,
+ R,
+
 Args...
+ >::type
+ invoker_type;
+
+ typedef functor_manager<FunctionPtr> manager_type;
+ };
+ };
+
+#if BOOST_FUNCTION_NUM_ARGS > 0
+ /* Retrieve the invoker for a member pointer. */
+ template<>
+ struct get_invoker<member_ptr_tag>
+ {
+ template<typename MemberPtr,
+ typename R, typename ... Args>
+ struct apply
+ {
+ typedef typename get_member_invoker<
+ MemberPtr,
+ R,
+
 Args...
+ >::type
+ invoker_type;
+
+ typedef functor_manager<MemberPtr> manager_type;
+ };
+
+ template<typename MemberPtr,
+ typename R, typename ... Args,
+ typename Allocator>
+ struct apply_a
+ {
+ typedef typename get_member_invoker<
+ MemberPtr,
+ R,
+
 Args...
+ >::type
+ invoker_type;
+
+ typedef functor_manager<MemberPtr> manager_type;
+ };
+ };
+#endif
+
+ /* Retrieve the invoker for a function object. */
+ template<>
+ struct get_invoker<function_obj_tag>
+ {
+ template<typename FunctionObj,
+ typename R, typename ... Args>
+ struct apply
+ {
+ typedef typename get_function_obj_invoker<
+ FunctionObj,
+ R,
+
 Args...
+ >::type
+ invoker_type;
+
+ typedef functor_manager<FunctionObj> manager_type;
+ };
+
+ template<typename FunctionObj,
+ typename R, typename ... Args,
+ typename Allocator>
+ struct apply_a
+ {
+ typedef typename get_function_obj_invoker<
+ FunctionObj,
+ R,
+
 Args...
+ >::type
+ invoker_type;
+
+ typedef functor_manager_a<FunctionObj, Allocator> manager_type;
+ };
+ };
+
+ /* Retrieve the invoker for a reference to a function object. */
+ template<>
+ struct get_invoker<function_obj_ref_tag>
+ {
+ template<typename RefWrapper,
+ typename R, typename ... Args>
+ struct apply
+ {
+ typedef typename get_function_ref_invoker<
+ typename RefWrapper::type,
+ R,
+
 Args...
+ >::type
+ invoker_type;
+
+ typedef reference_manager<typename RefWrapper::type> manager_type;
+ };
+
+ template<typename RefWrapper,
+ typename Allocator,
+ typename R, typename ... Args>
+ struct apply_a
+ {
+ typedef typename get_function_ref_invoker<
+ typename RefWrapper::type,
+ R,
+
 Args...
+ >::type
+ invoker_type;
+
+ typedef reference_manager<typename RefWrapper::type> manager_type;
+ };
+ };
+

Added: sandbox/boost0x/boost/function/function_variadic_vtable.hpp
==============================================================================
--- (empty file)
+++ sandbox/boost0x/boost/function/function_variadic_vtable.hpp 2009-05-05 18:58:36 EDT (Tue, 05 May 2009)
@@ -0,0 +1,186 @@
+namespace boost {
+ namespace detail {
+ namespace function {
+
+ /**
+ * vtable for a specific boost::function instance. This
+ * structure must be an aggregate so that we can use static
+ * initialization in boost::function's assign_to and assign_to_a
+ * members. It therefore cannot have any constructors,
+ * destructors, base classes, etc.
+ */
+ template<typename R, typename ... Args>
+ struct BOOST_FUNCTION_VTABLE
+ {
+#ifndef BOOST_NO_VOID_RETURNS
+ typedef R result_type;
+#else
+ typedef typename function_return_type<R>::type result_type;
+#endif // BOOST_NO_VOID_RETURNS
+
+ typedef result_type (*invoker_type)(function_buffer&, Args...);
+
+ template<typename F>
+ bool assign_to(F f, function_buffer& functor)
+ {
+ typedef typename get_function_tag<F>::type tag;
+ return assign_to(f, functor, tag());
+ }
+ template<typename F,typename Allocator>
+ bool assign_to_a(F f, function_buffer& functor, Allocator a)
+ {
+ typedef typename get_function_tag<F>::type tag;
+ return assign_to_a(f, functor, a, tag());
+ }
+
+ void clear(function_buffer& functor)
+ {
+ if (base.manager)
+ base.manager(functor, functor, destroy_functor_tag);
+ }
+
+ private:
+ // Function pointers
+ template<typename FunctionPtr>
+ bool
+ assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag)
+ {
+ this->clear(functor);
+ if (f) {
+ // should be a reinterpret cast, but some compilers insist
+ // on giving cv-qualifiers to free functions
+ functor.func_ptr = (void (*)())(f);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ template<typename FunctionPtr,typename Allocator>
+ bool
+ assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag)
+ {
+ return assign_to(f,functor,function_ptr_tag());
+ }
+
+ // Member pointers
+#if BOOST_FUNCTION_NUM_ARGS > 0
+ template<typename MemberPtr>
+ bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag)
+ {
+ // DPG TBD: Add explicit support for member function
+ // objects, so we invoke through mem_fn() but we retain the
+ // right target_type() values.
+ if (f) {
+ this->assign_to(mem_fn(f), functor);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ template<typename MemberPtr,typename Allocator>
+ bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag)
+ {
+ // DPG TBD: Add explicit support for member function
+ // objects, so we invoke through mem_fn() but we retain the
+ // right target_type() values.
+ if (f) {
+ this->assign_to_a(mem_fn(f), functor, a);
+ return true;
+ } else {
+ return false;
+ }
+ }
+#endif // BOOST_FUNCTION_NUM_ARGS > 0
+
+ // Function objects
+ // Assign to a function object using the small object optimization
+ template<typename FunctionObj>
+ void
+ assign_functor(FunctionObj f, function_buffer& functor, mpl::true_)
+ {
+ new ((void*)&functor.data) FunctionObj(f);
+ }
+ template<typename FunctionObj,typename Allocator>
+ void
+ assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_)
+ {
+ assign_functor(f,functor,mpl::true_());
+ }
+
+ // Assign to a function object allocated on the heap.
+ template<typename FunctionObj>
+ void
+ assign_functor(FunctionObj f, function_buffer& functor, mpl::false_)
+ {
+ functor.obj_ptr = new FunctionObj(f);
+ }
+ template<typename FunctionObj,typename Allocator>
+ void
+ assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_)
+ {
+ typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
+ typedef typename Allocator::template rebind<functor_wrapper_type>::other
+ wrapper_allocator_type;
+ typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
+ wrapper_allocator_type wrapper_allocator(a);
+ wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
+ wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
+ functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
+ functor.obj_ptr = new_f;
+ }
+
+ template<typename FunctionObj>
+ bool
+ assign_to(FunctionObj f, function_buffer& functor, function_obj_tag)
+ {
+ if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
+ assign_functor(f, functor,
+ mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
+ return true;
+ } else {
+ return false;
+ }
+ }
+ template<typename FunctionObj,typename Allocator>
+ bool
+ assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag)
+ {
+ if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
+ assign_functor_a(f, functor, a,
+ mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // Reference to a function object
+ template<typename FunctionObj>
+ bool
+ assign_to(const reference_wrapper<FunctionObj>& f,
+ function_buffer& functor, function_obj_ref_tag)
+ {
+ if (!boost::detail::function::has_empty_target(f.get_pointer())) {
+ functor.obj_ref.obj_ptr = (void *)f.get_pointer();
+ functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
+ functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ template<typename FunctionObj,typename Allocator>
+ bool
+ assign_to_a(const reference_wrapper<FunctionObj>& f,
+ function_buffer& functor, Allocator, function_obj_ref_tag)
+ {
+ return assign_to(f,functor,function_obj_ref_tag());
+ }
+
+ public:
+ vtable_base base;
+ invoker_type invoker;
+ };
+ } // end namespace function
+ } // end namespace detail
+} // end namespaces boost


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk