// Boost.Function library // Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu) // // Permission to copy, use, sell and distribute this software is granted // provided this copyright notice appears in all copies. // Permission to modify the code and to distribute modified code is granted // provided this copyright notice appears in all copies, and a notice // that the code was modified is included with the copyright notice. // // This software is provided "as is" without express or implied warranty, // and with no claim as to its suitability for any purpose. // For more information, see http://www.boost.org // William Kempf, Jesse Jones and Karl Nelson were all very helpful in the // design of this library. #ifndef BOOST_FUNCTION_HPP #define BOOST_FUNCTION_HPP #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace detail { namespace function { // Choose the appropriate underlying implementation template struct real_get_function_impl {}; template<> struct real_get_function_impl<0> { template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct params { typedef function0 type; }; }; template<> struct real_get_function_impl<1> { template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct params { typedef function1 type; }; }; template<> struct real_get_function_impl<2> { template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct params { typedef function2 type; }; }; template<> struct real_get_function_impl<3> { template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct params { typedef function3 type; }; }; template<> struct real_get_function_impl<4> { template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct params { typedef function4 type; }; }; template<> struct real_get_function_impl<5> { template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct params { typedef function5 type; }; }; template<> struct real_get_function_impl<6> { template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct params { typedef function6 type; }; }; template<> struct real_get_function_impl<7> { template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct params { typedef function7 type; }; }; template<> struct real_get_function_impl<8> { template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct params { typedef function8 type; }; }; template<> struct real_get_function_impl<9> { template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct params { typedef function9 type; }; }; template<> struct real_get_function_impl<10> { template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct params { typedef function10 type; }; }; template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename Policy = empty_function_policy, typename Mixin = empty_function_mixin, typename Allocator = std::allocator > struct get_function_impl { typedef typename real_get_function_impl< (count_used_args::value) >::template params::type type; }; template< typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename MyPolicy = empty_function_policy, typename MyMixin = empty_function_mixin, typename MyAllocator = std::allocator > struct function_traits_builder { typedef typename get_function_impl::type type; typedef MyPolicy policy_type; typedef MyMixin mixin_type; typedef MyAllocator allocator_type; #ifndef BOOST_NO_DEPENDENT_NESTED_DERIVATIONS template struct policy : public function_traits_builder {}; template struct mixin : public function_traits_builder {}; template struct allocator : public function_traits_builder {}; #else template struct policy { typedef typename function_traits_builder::type type; }; template struct mixin { typedef typename function_traits_builder::type type; }; template struct allocator { typedef typename function_traits_builder::type type; }; #endif }; } // end namespace function } // end namespace detail template< typename R, typename T1 = detail::function::unusable, typename T2 = detail::function::unusable, typename T3 = detail::function::unusable, typename T4 = detail::function::unusable, typename T5 = detail::function::unusable, typename T6 = detail::function::unusable, typename T7 = detail::function::unusable, typename T8 = detail::function::unusable, typename T9 = detail::function::unusable, typename T10 = detail::function::unusable > class function : public detail::function::get_function_impl::type, public detail::function::function_traits_builder { typedef typename detail::function::get_function_impl::type base_type; public: typedef typename base_type::policy_type policy_type; typedef typename base_type::mixin_type mixin_type; typedef typename base_type::allocator_type allocator_type; typedef function self_type; function() : base_type() {} template function(const Functor& f) : base_type(f) {} #ifdef __BORLANDC__ template function(Functor* f) : base_type(f) {} #endif // __BORLANDC__ function(const function& f) : base_type(static_cast(f)){} template function& operator=(const Functor& f) { function(f).swap(*this); return *this; } #ifdef __BORLANDC__ template function& operator=(Functor* f) { function(f).swap(*this); return *this; } #endif // __BORLANDC__ function& operator=(const base_type& f) { function(f).swap(*this); return *this; } function& operator=(const function& f) { function(f).swap(*this); return *this; } template void set(const Functor& f) { function(f).swap(*this); } #ifdef __BORLANDC__ template void set(Functor* f) { function(f).swap(*this); } #endif // __BORLANDC__ void set(const base_type& f) { function(f).swap(*this); } void set(const function& f) { function(f).swap(*this); } }; template inline void swap(function& f1, function& f2) { f1.swap(f2); } } #endif