123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- /*
- 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
|