]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/type_erasure/detail/member11.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / type_erasure / detail / member11.hpp
1 // Boost.TypeErasure library
2 //
3 // Copyright 2018 Steven Watanabe
4 //
5 // Distributed under the Boost Software License Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // $Id$
10
11 #ifndef BOOST_TYPE_ERASURE_DETAIL_MEMBER11_HPP_INCLUDED
12 #define BOOST_TYPE_ERASURE_DETAIL_MEMBER11_HPP_INCLUDED
13
14 #include <boost/config.hpp>
15 #include <boost/config/workaround.hpp>
16
17 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && \
18 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
19 !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
20 !defined(BOOST_NO_CXX11_DECLTYPE) && \
21 !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
22
23 #include <boost/preprocessor/cat.hpp>
24 #include <boost/preprocessor/control/if.hpp>
25 #include <boost/preprocessor/punctuation/is_begin_parens.hpp>
26 #include <boost/vmd/is_empty.hpp>
27 #include <boost/type_traits/remove_reference.hpp>
28 #include <boost/type_traits/remove_cv.hpp>
29 #include <boost/mpl/if.hpp>
30 #include <boost/type_erasure/detail/const.hpp>
31 #include <boost/type_erasure/detail/macro.hpp>
32 #include <boost/type_erasure/rebind_any.hpp>
33 #include <boost/type_erasure/param.hpp>
34 #include <boost/type_erasure/is_placeholder.hpp>
35 #include <boost/type_erasure/call.hpp>
36
37 namespace boost {
38 namespace type_erasure {
39 namespace detail {
40
41 template<class P, template<class ...> class interface, class Sig, class Concept, class Base, class ID>
42 using choose_member_interface = typename ::boost::mpl::if_c< ::boost::is_reference<P>::value,
43 typename ::boost::mpl::if_c< ::boost::type_erasure::detail::is_non_const_ref<P>::value,
44 interface<Sig, Concept, Base, const ID>,
45 Base
46 >::type,
47 interface<Sig, Concept, Base, ID>
48 >::type;
49
50
51 struct dummy {};
52
53 template<class Sig>
54 struct choose_member_impl;
55
56 template<class R, class C, class... T>
57 struct choose_member_impl<R (C::*)(T...) const>
58 {
59 template<class P, template<class> class M, template<class,class> class S>
60 using apply = ::boost::mpl::vector1<S<R(T...), const P> >;
61 };
62
63 template<class R, class C, class... T>
64 struct choose_member_impl<R (C::*)(T...)>
65 {
66 template<class P, template<class> class M, template<class,class> class S>
67 using apply = M<R(P&, T...)>;
68 };
69
70 template<class Sig, class P, template<class> class M, template<class, class> class Self>
71 using choose_member_impl_t =
72 typename ::boost::type_erasure::detail::choose_member_impl<
73 Sig (::boost::type_erasure::detail::dummy::*)
74 >::template apply<P, M, Self>;
75
76 template<class Sig, class T, class ID>
77 struct member_interface_chooser
78 {
79 template<class Base, template<class, class> class C, template<class...> class M>
80 using apply = Base;
81 };
82
83 template<class R, class T, class... A>
84 struct member_interface_chooser<R(A...), T, T>
85 {
86 template<class Base, template<class, class> class C, template<class...> class M>
87 using apply = ::boost::type_erasure::detail::choose_member_interface<
88 ::boost::type_erasure::placeholder_of_t<Base>,
89 M,
90 R(A...), C<R(A...), T>, Base, T>;
91 };
92
93 template<class R, class T, class... A>
94 struct member_interface_chooser<R(A...), const T, T>
95 {
96 template<class Base, template<class, class> class C, template<class...> class M>
97 using apply = M<R(A...), C<R(A...), const T>, Base, const T>;
98 };
99
100 template<class Sig, class T, template<class, class> class C, template<class...> class M>
101 struct member_choose_interface
102 {
103 template<class Concept, class Base, class ID>
104 using apply = typename ::boost::type_erasure::detail::member_interface_chooser<Sig, T, ID>::template apply<Base, C, M>;
105 };
106
107 }
108 }
109 }
110
111 #define BOOST_TYPE_ERASURE_MEMBER_I(concept_name, function_name) \
112 template<class Sig, class T = ::boost::type_erasure::_self> \
113 struct concept_name; \
114 \
115 namespace boost_type_erasure_impl { \
116 \
117 template<class Sig, class T> \
118 using concept_name ## self = concept_name<Sig, T>; \
119 \
120 template<class Sig, class Concept, class Base, class ID, class Enable = void>\
121 struct concept_name ## _member_interface; \
122 \
123 template<class R, class... A, class Concept, class Base, class ID, class V> \
124 struct concept_name ## _member_interface<R(A...), Concept, Base, ID, V> : Base\
125 { \
126 typedef void _boost_type_erasure_has_member ## function_name; \
127 ::boost::type_erasure::rebind_any_t<Base, R> function_name(::boost::type_erasure::as_param_t<Base, A>... a)\
128 { return ::boost::type_erasure::call(Concept(), *this, std::forward<A>(a)...); }\
129 }; \
130 \
131 template<class R, class... A, class Concept, class Base, class ID> \
132 struct concept_name ## _member_interface<R(A...), Concept, Base, ID, \
133 typename Base::_boost_type_erasure_has_member ## function_name> : Base \
134 { \
135 using Base::function_name; \
136 ::boost::type_erasure::rebind_any_t<Base, R> function_name(::boost::type_erasure::as_param_t<Base, A>... a)\
137 { return ::boost::type_erasure::call(Concept(), *this, std::forward<A>(a)...); }\
138 }; \
139 \
140 template<class R, class... A, class Concept, class Base, class ID, class V> \
141 struct concept_name ## _member_interface<R(A...), Concept, Base, const ID, V> : Base\
142 { \
143 typedef void _boost_type_erasure_has_member ## function_name; \
144 ::boost::type_erasure::rebind_any_t<Base, R> function_name(::boost::type_erasure::as_param_t<Base, A>... a) const\
145 { return ::boost::type_erasure::call(Concept(), *this, std::forward<A>(a)...); }\
146 }; \
147 \
148 template<class R, class... A, class Concept, class Base, class ID> \
149 struct concept_name ## _member_interface<R(A...), Concept, Base, const ID, \
150 typename Base::_boost_type_erasure_has_member ## function_name> : Base \
151 { \
152 using Base::function_name; \
153 ::boost::type_erasure::rebind_any_t<Base, R> function_name(::boost::type_erasure::as_param_t<Base, A>... a) const\
154 { return ::boost::type_erasure::call(Concept(), *this, std::forward<A>(a)...); }\
155 }; \
156 \
157 template<class Sig> \
158 struct concept_name ## member; \
159 \
160 template<class R, class T0, class... T> \
161 struct concept_name ## member<R(T0, T...)> { \
162 static R apply(T0 t0, T... t) \
163 { return t0.function_name(std::forward<T>(t)...); } \
164 }; \
165 \
166 template<class T0, class... T> \
167 struct concept_name ## member<void(T0, T...)> { \
168 static void apply(T0 t0, T... t) \
169 { t0.function_name(std::forward<T>(t)...); } \
170 }; \
171 \
172 } \
173 \
174 template<class Sig, class T> \
175 struct concept_name : \
176 ::boost::type_erasure::detail::choose_member_impl_t<Sig, T, \
177 boost_type_erasure_impl::concept_name##member, \
178 boost_type_erasure_impl::concept_name##self \
179 > \
180 {}; \
181 \
182 template<class Sig, class T> \
183 ::boost::type_erasure::detail::member_choose_interface<Sig, T, concept_name,\
184 boost_type_erasure_impl::concept_name ## _member_interface> \
185 boost_type_erasure_find_interface(concept_name<Sig, T>);
186
187 #define BOOST_TYPE_ERASURE_MEMBER_SIMPLE(name, ...) \
188 BOOST_TYPE_ERASURE_MEMBER_I(has_ ## name, name)
189
190 #define BOOST_TYPE_ERASURE_MEMBER_NS_I(concept_name, name) \
191 BOOST_TYPE_ERASURE_MEMBER_I(concept_name, name)
192
193 #define BOOST_TYPE_ERASURE_MEMBER_NS(concept_name, name) \
194 BOOST_TYPE_ERASURE_OPEN_NAMESPACE(concept_name) \
195 BOOST_TYPE_ERASURE_MEMBER_NS_I(BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(concept_name)), concept_name), name) \
196 BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(concept_name)
197
198 #define BOOST_TYPE_ERASURE_MEMBER_NAMED(concept_name, name, ...) \
199 BOOST_PP_IF(BOOST_PP_IS_BEGIN_PARENS(concept_name), \
200 BOOST_TYPE_ERASURE_MEMBER_NS, \
201 BOOST_TYPE_ERASURE_MEMBER_I) \
202 (concept_name, name)
203
204 #define BOOST_TYPE_ERASURE_MEMBER_CAT(x, y) x y
205
206 #define BOOST_TYPE_ERASURE_MEMBER(name, ...) \
207 BOOST_TYPE_ERASURE_MEMBER_CAT( \
208 BOOST_PP_IF(BOOST_VMD_IS_EMPTY(__VA_ARGS__), \
209 BOOST_TYPE_ERASURE_MEMBER_SIMPLE, \
210 BOOST_TYPE_ERASURE_MEMBER_NAMED), \
211 (name, __VA_ARGS__))
212
213 #endif
214
215 #endif