]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/type_erasure/include/boost/type_erasure/detail/vtable.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / type_erasure / include / boost / type_erasure / detail / vtable.hpp
CommitLineData
7c673cae
FG
1// Boost.TypeErasure library
2//
3// Copyright 2011 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#if !defined(BOOST_PP_IS_ITERATING)
12
13#ifndef BOOST_TYPE_ERASURE_DETAIL_VTABLE_HPP_INCLUDED
14#define BOOST_TYPE_ERASURE_DETAIL_VTABLE_HPP_INCLUDED
15
16#include <boost/config.hpp>
17#include <boost/mpl/at.hpp>
18#include <boost/mpl/size.hpp>
19#include <boost/preprocessor/cat.hpp>
20#include <boost/preprocessor/iteration/iterate.hpp>
21#include <boost/preprocessor/repetition/enum.hpp>
22#include <boost/preprocessor/repetition/enum_params.hpp>
23#include <boost/preprocessor/repetition/enum_trailing.hpp>
24#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
25#include <boost/preprocessor/repetition/repeat.hpp>
26#include <boost/type_erasure/detail/rebind_placeholders.hpp>
27#include <boost/type_erasure/config.hpp>
28
29namespace boost {
30namespace type_erasure {
31namespace detail {
32
33#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
34
35template<class... T>
36struct stored_arg_pack;
37
38template<class It, class End, class... T>
39struct make_arg_pack_impl
40{
41 typedef typename make_arg_pack_impl<
42 typename ::boost::mpl::next<It>::type,
43 End,
44 T...,
45 typename ::boost::mpl::deref<It>::type
46 >::type type;
47};
48
49template<class End, class... T>
50struct make_arg_pack_impl<End, End, T...>
51{
52 typedef stored_arg_pack<T...> type;
53};
54
55template<class Seq>
56struct make_arg_pack
57{
58 typedef typename make_arg_pack_impl<
59 typename ::boost::mpl::begin<Seq>::type,
60 typename ::boost::mpl::end<Seq>::type
61 >::type type;
62};
63
64template<class Args>
65struct make_vtable_impl;
66
67template<class Seq>
68struct make_vtable
69{
70 typedef typename ::boost::type_erasure::detail::make_vtable_impl<
71 typename ::boost::type_erasure::detail::make_arg_pack<Seq>::type
72 >::type type;
73};
74
75template<class Table, class Args>
76struct make_vtable_init_impl;
77
78template<class Seq, class Table>
79struct make_vtable_init
80{
81 typedef typename make_vtable_init_impl<
82 Table,
83 typename ::boost::type_erasure::detail::make_arg_pack<Seq>::type
84 >::type type;
85};
86
87template<class T>
88struct vtable_entry
89{
90 typename T::type value;
91 vtable_entry() = default;
92 constexpr vtable_entry(typename T::type arg) : value(arg) {}
93};
94
95template<class... T>
96struct compare_vtable;
97
98template<>
99struct compare_vtable<> {
100 template<class S>
101 static bool apply(const S& s1, const S& s2)
102 {
103 return true;
104 }
105};
106
107template<class T0, class... T>
108struct compare_vtable<T0, T...> {
109 template<class S>
110 static bool apply(const S& s1, const S& s2)
111 {
112 return static_cast<const vtable_entry<T0>&>(s1).value ==
113 static_cast<const vtable_entry<T0>&>(s2).value &&
114 compare_vtable<T...>::apply(s1, s2);
115 }
116};
117
118template<class... T>
119struct vtable_storage : vtable_entry<T>...
120{
121 vtable_storage() = default;
122
123 constexpr vtable_storage(typename T::type... arg)
124 : vtable_entry<T>(arg)... {}
125
126 template<class Bindings, class Src>
127 void convert_from(const Src& src)
128 {
129 *this = vtable_storage(
130 src.lookup(
131 (typename ::boost::type_erasure::detail::rebind_placeholders<
132 T, Bindings
133 >::type*)0)...);
134 }
135
136 bool operator==(const vtable_storage& other) const
137 { return compare_vtable<T...>::apply(*this, other); }
138
139 template<class U>
140 typename U::type lookup(U*) const
141 {
142 return static_cast<const vtable_entry<U>*>(this)->value;
143 }
144};
145
146// Provide this specialization manually.
147// gcc 4.7.2 fails to instantiate the primary template.
148template<>
149struct vtable_storage<>
150{
151 vtable_storage() = default;
152
153 template<class Bindings, class Src>
154 void convert_from(const Src& src) {}
155
156 bool operator==(const vtable_storage& other) const
157 { return true; }
158};
159
160template<class... T>
161struct make_vtable_impl<stored_arg_pack<T...> >
162{
163 typedef vtable_storage<T...> type;
164};
165
166template<class Table, class... T>
167struct vtable_init
168{
169 static constexpr Table value = Table(T::value...);
170};
171
172template<class Table, class... T>
173constexpr Table vtable_init<Table, T...>::value;
174
175template<class Table, class... T>
176struct make_vtable_init_impl<Table, stored_arg_pack<T...> >
177{
178 typedef vtable_init<Table, T...> type;
179};
180
181#else
182
183template<int N>
184struct make_vtable_impl;
185
186template<class Seq>
187struct make_vtable
188{
189 typedef typename make_vtable_impl<
190 (::boost::mpl::size<Seq>::value)>::template apply<Seq>::type type;
191};
192
193template<int N>
194struct make_vtable_init_impl;
195
196template<class Seq, class Table>
197struct make_vtable_init
198{
199 typedef typename make_vtable_init_impl<
200 (::boost::mpl::size<Seq>::value)>::template apply<Seq, Table>::type type;
201};
202
203#define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/vtable.hpp>
204#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_FUNCTIONS)
205#include BOOST_PP_ITERATE()
206
207#endif
208
209}
210}
211}
212
213#endif
214
215#else
216
217#define N BOOST_PP_ITERATION()
218
219#define BOOST_TYPE_ERASURE_VTABLE_ENTRY(z, n, data) \
220 typename BOOST_PP_CAT(T, n)::type BOOST_PP_CAT(t, n); \
221 typename BOOST_PP_CAT(T, n)::type lookup(BOOST_PP_CAT(T, n)*) const \
222 { \
223 return BOOST_PP_CAT(t, n); \
224 }
225
226#define BOOST_TYPE_ERASURE_VTABLE_COMPARE(z, n, data) \
227 && BOOST_PP_CAT(t, n) == other.BOOST_PP_CAT(t, n)
228
229#define BOOST_TYPE_ERASURE_VTABLE_INIT(z, n, data) \
230 BOOST_PP_CAT(data, n)::value
231
232#define BOOST_TYPE_ERASURE_AT(z, n, data) \
233 typename ::boost::mpl::at_c<data, n>::type
234
235#define BOOST_TYPE_ERASURE_CONVERT_ELEMENT(z, n, data) \
236 BOOST_PP_CAT(t, n) = src.lookup( \
237 (typename ::boost::type_erasure::detail::rebind_placeholders< \
238 BOOST_PP_CAT(T, n), Bindings \
239 >::type*)0 \
240 );
241
242#if N != 0
243template<BOOST_PP_ENUM_PARAMS(N, class T)>
244#else
245template<class D = void>
246#endif
247struct BOOST_PP_CAT(vtable_storage, N)
248{
249 BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_VTABLE_ENTRY, ~)
250
251 template<class Bindings, class Src>
252 void convert_from(const Src& src)
253 {
254 BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_CONVERT_ELEMENT, ~)
255 }
256
257 bool operator==(const BOOST_PP_CAT(vtable_storage, N)& other) const
258 { return true BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_VTABLE_COMPARE, ~); }
259};
260
261template<>
262struct make_vtable_impl<N>
263{
264 template<class Seq>
265 struct apply
266 {
267 typedef ::boost::type_erasure::detail::BOOST_PP_CAT(vtable_storage, N)<
268 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_AT, Seq)
269 > type;
270 };
271};
272template<class Table BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
273struct BOOST_PP_CAT(vtable_init, N)
274{
275 static const Table value;
276};
277
278template<class Table BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
279const Table BOOST_PP_CAT(vtable_init, N)<
280 Table BOOST_PP_ENUM_TRAILING_PARAMS(N, T)>::value =
281{
282 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_VTABLE_INIT, T)
283};
284
285template<>
286struct make_vtable_init_impl<N>
287{
288 template<class Seq, class Table>
289 struct apply
290 {
291 typedef ::boost::type_erasure::detail::BOOST_PP_CAT(vtable_init, N)<
292 Table
293 BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_AT, Seq)
294 > type;
295 };
296};
297
298#undef BOOST_TYPE_ERASURE_CONVERT_ELEMENT
299#undef BOOST_TYPE_ERASURE_AT
300#undef BOOST_TYPE_ERASURE_VTABLE_INIT
301#undef BOOST_TYPE_ERASURE_VTABLE_COMPARE
302#undef BOOST_TYPE_ERASURE_VTABLE_ENTRY
303#undef N
304
305#endif