]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/signals2/detail/variadic_slot_invoker.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / signals2 / detail / variadic_slot_invoker.hpp
1 /*
2 Helper class used by variadic implementation of variadic boost::signals2::signal.
3
4 Author: Frank Mori Hess <fmhess@users.sourceforge.net>
5 Begin: 2009-05-27
6 */
7 // Copyright Frank Mori Hess 2009
8 // Use, modification and
9 // distribution is subject to the Boost Software License, Version
10 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12
13 // For more information, see http://www.boost.org
14
15 #ifndef BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP
16 #define BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP
17
18 #include <boost/mpl/size_t.hpp>
19 #include <boost/signals2/detail/variadic_arg_type.hpp>
20
21 // if compiler has std::tuple use it instead of boost::tuple
22 // because boost::tuple does not have variadic template support at present.
23 #ifdef BOOST_NO_CXX11_HDR_TUPLE
24 #include <boost/tuple/tuple.hpp>
25 #define BOOST_SIGNALS2_TUPLE boost::tuple
26 #define BOOST_SIGNALS2_GET boost::get
27 #else
28 #include <tuple>
29 #define BOOST_SIGNALS2_TUPLE std::tuple
30 #define BOOST_SIGNALS2_GET std::get
31 #endif
32
33 // vc12 seems to erroneously report formal parameters as unreferenced (warning C4100)
34 // if parameters of variadic template functions are only referenced by calling
35 // other varadic template functions. silence these warnings:
36 #if defined(BOOST_MSVC)
37 #pragma warning(push)
38 #if BOOST_MSVC >= 1800
39 #pragma warning(disable:4100)
40 #endif
41 #endif
42
43 namespace boost
44 {
45 namespace signals2
46 {
47 namespace detail
48 {
49 template<unsigned ... values> class unsigned_meta_array {};
50
51 template<typename UnsignedMetaArray, unsigned n> class unsigned_meta_array_appender;
52
53 template<unsigned n, unsigned ... Args>
54 class unsigned_meta_array_appender<unsigned_meta_array<Args...>, n>
55 {
56 public:
57 typedef unsigned_meta_array<Args..., n> type;
58 };
59
60 template<unsigned n> class make_unsigned_meta_array;
61
62 template<> class make_unsigned_meta_array<0>
63 {
64 public:
65 typedef unsigned_meta_array<> type;
66 };
67
68 template<> class make_unsigned_meta_array<1>
69 {
70 public:
71 typedef unsigned_meta_array<0> type;
72 };
73
74 template<unsigned n> class make_unsigned_meta_array
75 {
76 public:
77 typedef typename unsigned_meta_array_appender<typename make_unsigned_meta_array<n-1>::type, n - 1>::type type;
78 };
79
80 template<typename R>
81 class call_with_tuple_args
82 {
83 public:
84 typedef R result_type;
85
86 template<typename Func, typename ... Args, std::size_t N>
87 R operator()(Func &func, const BOOST_SIGNALS2_TUPLE<Args...> & args, mpl::size_t<N>) const
88 {
89 typedef typename make_unsigned_meta_array<N>::type indices_type;
90 return m_invoke<Func>(func, indices_type(), args);
91 }
92 private:
93 template<typename Func, unsigned ... indices, typename ... Args>
94 R m_invoke(Func &func, unsigned_meta_array<indices...>, const BOOST_SIGNALS2_TUPLE<Args...> & args,
95 typename boost::disable_if<boost::is_void<typename Func::result_type> >::type * = 0
96 ) const
97 {
98 return func(BOOST_SIGNALS2_GET<indices>(args)...);
99 }
100 template<typename Func, unsigned ... indices, typename ... Args>
101 R m_invoke(Func &func, unsigned_meta_array<indices...>, const BOOST_SIGNALS2_TUPLE<Args...> & args,
102 typename boost::enable_if<boost::is_void<typename Func::result_type> >::type * = 0
103 ) const
104 {
105 func(BOOST_SIGNALS2_GET<indices>(args)...);
106 return R();
107 }
108 // This overload is redundant, as it is the same as the previous variadic method when
109 // it has zero "indices" or "Args" variadic template parameters. This overload
110 // only exists to quiet some unused parameter warnings
111 // on certain compilers (some versions of gcc and msvc)
112 template<typename Func>
113 R m_invoke(Func &func, unsigned_meta_array<>, const BOOST_SIGNALS2_TUPLE<> &,
114 typename boost::enable_if<boost::is_void<typename Func::result_type> >::type * = 0
115 ) const
116 {
117 func();
118 return R();
119 }
120 };
121
122 template<typename R, typename ... Args>
123 class variadic_slot_invoker
124 {
125 public:
126 typedef R result_type;
127
128 variadic_slot_invoker(Args & ... args): _args(args...)
129 {}
130 template<typename ConnectionBodyType>
131 result_type operator ()(const ConnectionBodyType &connectionBody) const
132 {
133 return call_with_tuple_args<result_type>()(connectionBody->slot().slot_function(),
134 _args, mpl::size_t<sizeof...(Args)>());
135 }
136 private:
137 BOOST_SIGNALS2_TUPLE<Args& ...> _args;
138 };
139 } // namespace detail
140 } // namespace signals2
141 } // namespace boost
142
143 #if defined(BOOST_MSVC)
144 #pragma warning(pop)
145 #endif
146
147
148 #endif // BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP