EVOLUTION-MANAGER
Edit File: variadic_slot_invoker.hpp
/* Helper class used by variadic implementation of variadic boost::signals2::signal. Author: Frank Mori Hess <fmhess@users.sourceforge.net> 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 <boost/mpl/size_t.hpp> #include <boost/signals2/detail/variadic_arg_type.hpp> // 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 <boost/tuple/tuple.hpp> #define BOOST_SIGNALS2_TUPLE boost::tuple #define BOOST_SIGNALS2_GET boost::get #else #include <tuple> #define BOOST_SIGNALS2_TUPLE std::tuple #define BOOST_SIGNALS2_GET std::get #endif // vc12 seems to erroneously report formal parameters as unreferenced (warning C4100) // if parameters of variadic template functions are only referenced by calling // other varadic template functions. silence these warnings: #if defined(BOOST_MSVC) #pragma warning(push) #if BOOST_MSVC >= 1800 #pragma warning(disable:4100) #endif #endif namespace boost { namespace signals2 { namespace detail { template<unsigned ... values> class unsigned_meta_array {}; template<typename UnsignedMetaArray, unsigned n> class unsigned_meta_array_appender; template<unsigned n, unsigned ... Args> class unsigned_meta_array_appender<unsigned_meta_array<Args...>, n> { public: typedef unsigned_meta_array<Args..., n> type; }; template<unsigned n> 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<unsigned n> class make_unsigned_meta_array { public: typedef typename unsigned_meta_array_appender<typename make_unsigned_meta_array<n-1>::type, n - 1>::type type; }; template<typename R> class call_with_tuple_args { public: typedef R result_type; template<typename Func, typename ... Args, std::size_t N> R operator()(Func &func, const BOOST_SIGNALS2_TUPLE<Args...> & args, mpl::size_t<N>) const { typedef typename make_unsigned_meta_array<N>::type indices_type; return m_invoke<Func>(func, indices_type(), args); } private: template<typename Func, unsigned ... indices, typename ... Args> R m_invoke(Func &func, unsigned_meta_array<indices...>, const BOOST_SIGNALS2_TUPLE<Args...> & args, typename boost::disable_if<boost::is_void<typename Func::result_type> >::type * = 0 ) const { return func(BOOST_SIGNALS2_GET<indices>(args)...); } template<typename Func, unsigned ... indices, typename ... Args> R m_invoke(Func &func, unsigned_meta_array<indices...>, const BOOST_SIGNALS2_TUPLE<Args...> & args, typename boost::enable_if<boost::is_void<typename Func::result_type> >::type * = 0 ) const { func(BOOST_SIGNALS2_GET<indices>(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<typename Func> R m_invoke(Func &func, unsigned_meta_array<>, const BOOST_SIGNALS2_TUPLE<> &, typename boost::enable_if<boost::is_void<typename Func::result_type> >::type * = 0 ) const { func(); return R(); } }; template<typename R, typename ... Args> class variadic_slot_invoker { public: typedef R result_type; variadic_slot_invoker(Args & ... args): _args(args...) {} template<typename ConnectionBodyType> result_type operator ()(const ConnectionBodyType &connectionBody) const { return call_with_tuple_args<result_type>()(connectionBody->slot().slot_function(), _args, mpl::size_t<sizeof...(Args)>()); } private: BOOST_SIGNALS2_TUPLE<Args& ...> _args; }; } // namespace detail } // namespace signals2 } // namespace boost #if defined(BOOST_MSVC) #pragma warning(pop) #endif #endif // BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP