Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:08:48

0001 /*
0002   Helper class used by variadic implementation of variadic boost::signals2::signal.
0003 
0004   Author: Frank Mori Hess <fmhess@users.sourceforge.net>
0005   Begin: 2009-05-27
0006 */
0007 // Copyright Frank Mori Hess 2009
0008 // Use, modification and
0009 // distribution is subject to the Boost Software License, Version
0010 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0011 // http://www.boost.org/LICENSE_1_0.txt)
0012 
0013 // For more information, see http://www.boost.org
0014 
0015 #ifndef BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP
0016 #define BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP
0017 
0018 #include <boost/mpl/size_t.hpp>
0019 #include <boost/signals2/detail/variadic_arg_type.hpp>
0020 
0021 // if compiler has std::tuple use it instead of boost::tuple
0022 // because boost::tuple does not have variadic template support at present.
0023 #ifdef BOOST_NO_CXX11_HDR_TUPLE
0024 #include <boost/tuple/tuple.hpp>
0025 #define BOOST_SIGNALS2_TUPLE boost::tuple
0026 #define BOOST_SIGNALS2_GET boost::get
0027 #else
0028 #include <tuple>
0029 #define BOOST_SIGNALS2_TUPLE std::tuple
0030 #define BOOST_SIGNALS2_GET std::get
0031 #endif
0032 
0033 // vc12 seems to erroneously report formal parameters as unreferenced (warning C4100)
0034 // if parameters of variadic template functions are only referenced by calling
0035 // other varadic template functions. silence these warnings:
0036 #if defined(BOOST_MSVC)
0037 #pragma warning(push)
0038 #if  BOOST_MSVC >= 1800
0039 #pragma warning(disable:4100)
0040 #endif
0041 #endif
0042 
0043 namespace boost
0044 {
0045   namespace signals2
0046   {
0047     namespace detail
0048     {
0049       template<unsigned ... values> class unsigned_meta_array {};
0050 
0051       template<typename UnsignedMetaArray, unsigned n> class unsigned_meta_array_appender;
0052 
0053       template<unsigned n, unsigned ... Args>
0054         class unsigned_meta_array_appender<unsigned_meta_array<Args...>, n>
0055       {
0056       public:
0057         typedef unsigned_meta_array<Args..., n> type;
0058       };
0059 
0060       template<unsigned n> class make_unsigned_meta_array;
0061 
0062       template<> class make_unsigned_meta_array<0>
0063       {
0064       public:
0065         typedef unsigned_meta_array<> type;
0066       };
0067 
0068       template<> class make_unsigned_meta_array<1>
0069       {
0070       public:
0071         typedef unsigned_meta_array<0> type;
0072       };
0073 
0074       template<unsigned n> class make_unsigned_meta_array
0075       {
0076       public:
0077         typedef typename unsigned_meta_array_appender<typename make_unsigned_meta_array<n-1>::type, n - 1>::type type;
0078       };
0079 
0080       template<typename R>
0081         class call_with_tuple_args
0082       {
0083       public:
0084         typedef R result_type;
0085 
0086         template<typename Func, typename ... Args, std::size_t N>
0087         R operator()(Func &func, const BOOST_SIGNALS2_TUPLE<Args...> & args, mpl::size_t<N>) const
0088         {
0089           typedef typename make_unsigned_meta_array<N>::type indices_type;
0090           return m_invoke<Func>(func, indices_type(), args);
0091         }
0092       private:
0093         template<typename Func, unsigned ... indices, typename ... Args>
0094           R m_invoke(Func &func, unsigned_meta_array<indices...>, const BOOST_SIGNALS2_TUPLE<Args...> & args,
0095             typename boost::disable_if<boost::is_void<typename Func::result_type> >::type * = 0
0096           ) const
0097         {
0098           return func(BOOST_SIGNALS2_GET<indices>(args)...);
0099         }
0100         template<typename Func, unsigned ... indices, typename ... Args>
0101           R m_invoke(Func &func, unsigned_meta_array<indices...>, const BOOST_SIGNALS2_TUPLE<Args...> & args,
0102             typename boost::enable_if<boost::is_void<typename Func::result_type> >::type * = 0
0103           ) const
0104         {
0105           func(BOOST_SIGNALS2_GET<indices>(args)...);
0106           return R();
0107         }
0108         // This overload is redundant, as it is the same as the previous variadic method when
0109         // it has zero "indices" or "Args" variadic template parameters.  This overload
0110         // only exists to quiet some unused parameter warnings
0111         // on certain compilers (some versions of gcc and msvc)
0112         template<typename Func>
0113           R m_invoke(Func &func, unsigned_meta_array<>, const BOOST_SIGNALS2_TUPLE<> &, 
0114             typename boost::enable_if<boost::is_void<typename Func::result_type> >::type * = 0
0115           ) const
0116         {
0117           func();
0118           return R();
0119         }
0120       };
0121 
0122       template<typename R, typename ... Args>
0123         class variadic_slot_invoker
0124       {
0125       public:
0126         typedef R result_type;
0127 
0128         variadic_slot_invoker(Args & ... args): _args(args...)
0129         {}
0130         template<typename ConnectionBodyType>
0131           result_type operator ()(const ConnectionBodyType &connectionBody) const
0132         {
0133           return call_with_tuple_args<result_type>()(connectionBody->slot().slot_function(), 
0134             _args, mpl::size_t<sizeof...(Args)>());
0135         }
0136       private:
0137         BOOST_SIGNALS2_TUPLE<Args& ...> _args;
0138       };
0139     } // namespace detail
0140   } // namespace signals2
0141 } // namespace boost
0142 
0143 #if defined(BOOST_MSVC)
0144 #pragma warning(pop)
0145 #endif
0146 
0147 
0148 #endif // BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP