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