/* Helper class used by variadic implementation of variadic boost::signals2::signal. Author: Frank Mori Hess Begin: 2009-05-27 */ // Copyright Frank Mori Hess 2009 // Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org #ifndef BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP #define BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP #include #include // if compiler has std::tuple use it instead of boost::tuple // because boost::tuple does not have variadic template support at present. #ifdef BOOST_NO_CXX11_HDR_TUPLE #include #define BOOST_SIGNALS2_TUPLE boost::tuple #define BOOST_SIGNALS2_GET boost::get #else #include #define BOOST_SIGNALS2_TUPLE std::tuple #define BOOST_SIGNALS2_GET std::get #endif namespace boost { namespace signals2 { namespace detail { template class unsigned_meta_array {}; template class unsigned_meta_array_appender; template class unsigned_meta_array_appender, n> { public: typedef unsigned_meta_array type; }; template class make_unsigned_meta_array; template<> class make_unsigned_meta_array<0> { public: typedef unsigned_meta_array<> type; }; template<> class make_unsigned_meta_array<1> { public: typedef unsigned_meta_array<0> type; }; template class make_unsigned_meta_array { public: typedef typename unsigned_meta_array_appender::type, n - 1>::type type; }; template class call_with_tuple_args { public: typedef R result_type; template R operator()(Func &func, BOOST_SIGNALS2_TUPLE args, mpl::size_t) const { typedef typename make_unsigned_meta_array::type indices_type; typename Func::result_type *resolver = 0; return m_invoke(resolver, func, indices_type(), args); } private: template R m_invoke(T *, Func &func, unsigned_meta_array, BOOST_SIGNALS2_TUPLE args) const { return func(BOOST_SIGNALS2_GET(args)...); } template R m_invoke(void *, Func &func, unsigned_meta_array, BOOST_SIGNALS2_TUPLE args) const { func(BOOST_SIGNALS2_GET(args)...); return R(); } // This overload is redundant, as it is the same as the previous variadic method when // it has zero "indices" or "Args" variadic template parameters. This overload // only exists to quiet some unused parameter warnings // on certain compilers (some versions of gcc and msvc) template R m_invoke(void *, Func &func, unsigned_meta_array<>, BOOST_SIGNALS2_TUPLE<>) const { func(); return R(); } }; template class variadic_slot_invoker { public: typedef R result_type; variadic_slot_invoker(Args & ... args): _args(args...) {} template result_type operator ()(const ConnectionBodyType &connectionBody) const { result_type *resolver = 0; return m_invoke(connectionBody, resolver); } private: template result_type m_invoke(const ConnectionBodyType &connectionBody, const void_type *) const { return call_with_tuple_args()(connectionBody->slot.slot_function(), _args, mpl::size_t()); } template result_type m_invoke(const ConnectionBodyType &connectionBody, ...) const { return call_with_tuple_args()(connectionBody->slot.slot_function(), _args, mpl::size_t()); } BOOST_SIGNALS2_TUPLE _args; }; } // namespace detail } // namespace signals2 } // namespace boost #endif // BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP