]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/dll/include/boost/dll/detail/import_mangled_helpers.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / dll / include / boost / dll / detail / import_mangled_helpers.hpp
CommitLineData
7c673cae
FG
1// Copyright 2015-2016 Klemens D. Morgenstern
2//
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt
5// or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#ifndef BOOST_DLL_DETAIL_IMPORT_MANGLED_HELPERS_HPP_
8#define BOOST_DLL_DETAIL_IMPORT_MANGLED_HELPERS_HPP_
9
10
11#include <boost/type_traits/conditional.hpp>
12#include <boost/type_traits/is_same.hpp>
13#include <boost/type_traits/is_class.hpp>
14#include <boost/type_traits/is_function.hpp>
15#include <boost/type_traits/remove_cv.hpp>
16
17
18#ifdef BOOST_HAS_PRAGMA_ONCE
19# pragma once
20#endif
21
22namespace boost { namespace dll { namespace experimental { namespace detail {
23
24//the following could be done by fusion, though it's simple enough to just declare it here.
25template<class ...Args>
26struct sequence {};
27
28template<class Value, class Seq> struct push_front;
29template<class Value, class ...Args>
30struct push_front<Value, sequence<Args...>>
31{
32 typedef sequence<Value, Args...> type;
33};
34
35template<class Lhs, class Rhs>
36struct unqalified_is_same :
37 boost::is_same<
38 typename boost::remove_cv<Lhs>::type,
39 typename boost::remove_cv<Rhs>::type
40 >
41{
42};
43
44/* ********************************** function sequence type traits ******************************/
45
46//determine if it's a sequence of functions.
47template<class T> struct is_function_seq;
48
49//type-trait for function overloads
50template<class Class, class...Args> struct is_function_seq<sequence<Class, Args...>>
51 : boost::conditional<
52 boost::is_function<Class>::value,
53 is_function_seq<sequence<Args...>>,
54 boost::false_type>::type
55{};
56
57template<class Class>
58struct is_function_seq<sequence<Class>> : boost::is_function<Class>
59{
60};
61
62template<>
63struct is_function_seq<sequence<>> : boost::false_type
64{
65};
66
67/* ********************************* Function Tuple *************************** */
68
69//a tuple of plain functions.
70template <class ...Ts>
71struct function_tuple;
72
73template <class Return, class...Args, class T2, class ...Ts>
74struct function_tuple<Return(Args...), T2, Ts...> : function_tuple<T2, Ts...>
75{
76 constexpr function_tuple(Return(* t)(Args...), T2* t2, Ts* ... ts) : function_tuple<T2, Ts...>(t2, ts...), _f(t) {};
77 Return(*_f)(Args...);
78
79 Return operator()(Args...args)
80 {
81 return (*_f)(static_cast<Args>(args)...);
82 }
83 using function_tuple<T2, Ts...>::operator();
84
85};
86
87template <class Return, class...Args>
88struct function_tuple<Return(Args...)>
89{
90 constexpr function_tuple(Return(* t)(Args...)) : _f(t) {};
91 Return(*_f)(Args...);
92
93 Return operator()(Args...args)
94 {
95 return (*_f)(static_cast<Args>(args)...);
96 }
97};
98
99
100/* ********************************** MemFn sequence type traits ******************************/
101
102template<class Class, class Func>
103struct mem_fn_def
104{
105 typedef Class class_type;
106 typedef Func func_type;
107 typedef typename boost::dll::detail::get_mem_fn_type<Class, Func>::mem_fn mem_fn;
108};
109
110template<class ...Args>
111struct make_mem_fn_seq;
112
113// B: is T1 another version of T0?
114template<bool, class T0, class T1, class T2>
115struct make_mem_fn_seq_getter;
116
117template<class T0, class T1, class T2>
118struct make_mem_fn_seq_getter<true, T0, T1, T2>
119{
120 typedef mem_fn_def<T1, T2> type;
121};
122
123template<class T0, class T1, class T2>
124struct make_mem_fn_seq_getter<false, T0, T1, T2>
125{
126 typedef mem_fn_def<T0, T1> type;
127};
128
129template<class Class, class Signature>
130struct make_mem_fn_seq<Class, Signature>
131{
132 typedef mem_fn_def<Class, Signature> mem_fn;
133 typedef sequence<mem_fn> type;
134};
135
136template<class Class>
137struct make_mem_fn_seq<Class>
138{
139 typedef sequence<> type;
140};
141
142template<class T0, class T1, class T2, class ... Args>
143struct make_mem_fn_seq<T0, T1, T2, Args...>
144{
145 /* Since we might have ovls, it might be :
146 * Class, void(int), void(int, int) //--> just us class for both
147 * Class, const Class, void(int)//--> ovl class.
148 *
149 */
150 static_assert(boost::is_object<T0>::value, "");
151 typedef typename make_mem_fn_seq_getter<
152 unqalified_is_same<T0, T1>::value, T0, T1, T2>::type mem_fn_type;
153
154 typedef typename boost::conditional<
155 unqalified_is_same<T0, T1>::value,
156 make_mem_fn_seq<T1, Args...>,
157 make_mem_fn_seq<T0, T2, Args...>> ::type next;
158
159 typedef typename push_front<mem_fn_type, typename next::type>::type type;
160};
161
162
163
164
165/* Ok, this needs to be documented, so here's some pseudo-code:
166 *
167 * @code
168 *
169 * bool unqalified_is_same(lhs, rhs)
170 * {
171 * return remove_cv(lhs) == remove_cv(rhs);
172 * }
173 *
174 * mem_fn make_mem_fn_seq_getter(b, cl, T2, T3)
175 * {
176 * if (b) //b means, that T2 is another version of cl, i.e. qualified
177 * return get_mem_fn_type(T2, T3);
178 * else //means that T2 is a function.
179 * return get_mem_fn_type(cl, T2);
180 * }
181 *
182 * sequence make_mem_fn_seq(type cl, type T2, type T3, types...)
183 * {
184 * mem_fn = make_mem_fn_seq_getter(
185 * unqalified_is_same(cl, T2), cl, T2, T3);
186 *
187 * next = unqalified_is_same(cl, T2) ?
188 * make_mem_fn_seq(T2, types...) //because: T2 is another version of cl, hence i use this. T3 was already consumed.
189 * :
190 * make_mem_fn_seq(Class, T3, types...) //because: T2 was a function, hence it is consumed and class remains unchanged.
191 * ;
192 * return push_front(mem_fn, next) ;
193 * };
194 * @endcode
195 */
196
197
198
199template<class T, class U, class ...Args>
200struct is_mem_fn_seq_impl
201{
202 typedef typename boost::conditional<
203 boost::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value,
204 typename is_mem_fn_seq_impl<T, Args...>::type,
205 boost::false_type>::type type;
206};
207
208template<class T, class U>
209struct is_mem_fn_seq_impl<T, U>
210{
211 typedef typename boost::conditional<
212 boost::is_function<U>::value && boost::is_object<T>::value,
213 boost::true_type, boost::false_type>::type type;
214};
215
216template<class T, class U, class Last>
217struct is_mem_fn_seq_impl<T, U, Last>
218{
219 typedef typename boost::conditional<
220 (boost::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value)
221 && boost::is_function<Last>::value,
222 boost::true_type, boost::false_type>::type type;
223};
224
225template<class T> struct is_mem_fn_seq : boost::false_type {};
226
227//If only two arguments are provided at all.
228template<class T, class U>
229struct is_mem_fn_seq<sequence<T, U>> : boost::conditional<
230 boost::is_object<T>::value && boost::is_function<U>::value,
231 boost::true_type, boost::false_type>::type
232{
233};
234
235
236template<class T, class Func, class ...Args>
237struct is_mem_fn_seq<sequence<T, Func, Args...>> :
238 boost::conditional<
239 boost::is_class<T>::value && boost::is_function<Func>::value,
240 typename is_mem_fn_seq_impl<T, Args...>::type,
241 boost::false_type>::type {};
242
243
244/* ********************************** mem fn sequence tuple ******************************/
245
246/* A tuple of member functions
247 * Unlike for plain functions a sequence here might contain classes as well as functions.
248 */
249template <class ...Ts>
250struct mem_fn_tuple;
251
252template <class Class, class Return, class...Args, class T2, class ...Ts>
253struct mem_fn_tuple<mem_fn_def<Class, Return(Args...)>, T2, Ts...> : mem_fn_tuple<T2, Ts...>
254{
255 typedef typename boost::dll::detail::get_mem_fn_type<Class, Return(Args...)>::mem_fn mem_fn;
256
257 constexpr mem_fn_tuple(mem_fn f, typename T2::mem_fn t2, typename Ts::mem_fn ... ts)
258 : mem_fn_tuple<T2, Ts...>(t2, ts...), _f(f) {};
259 mem_fn _f;
260
261 Return operator()(Class* const cl, Args...args)
262 {
263 return (cl->*_f)(static_cast<Args>(args)...);
264 }
265 using mem_fn_tuple<T2, Ts...>::operator();
266
267};
268
269template <class Class, class Return, class...Args>
270struct mem_fn_tuple<mem_fn_def<Class, Return(Args...)>>
271{
272 typedef typename boost::dll::detail::get_mem_fn_type<Class, Return(Args...)>::mem_fn mem_fn;
273
274 constexpr mem_fn_tuple(mem_fn f) : _f(f) {};
275 mem_fn _f;
276
277 Return operator()(Class * const cl, Args...args)
278 {
279 return (cl->*_f)(static_cast<Args>(args)...);
280 }
281};
282
283}}}}
284#endif /* BOOST_DLL_DETAIL_IMPORT_MANGLED_HELPERS_HPP_ */