]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/type_erasure/detail/dynamic_vtable.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / type_erasure / detail / dynamic_vtable.hpp
1 // Boost.TypeErasure library
2 //
3 // Copyright 2015 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_DYNAMIC_VTABLE_HPP_INCLUDED
12 #define BOOST_TYPE_ERASURE_DETAIL_DYNAMIC_VTABLE_HPP_INCLUDED
13
14 #include <boost/type_erasure/detail/get_placeholders.hpp>
15 #include <boost/type_erasure/detail/rebind_placeholders.hpp>
16 #include <boost/type_erasure/detail/normalize.hpp>
17 #include <boost/type_erasure/detail/adapt_to_vtable.hpp>
18 #include <boost/type_erasure/detail/vtable.hpp>
19 #include <boost/type_erasure/static_binding.hpp>
20 #include <boost/type_erasure/register_binding.hpp>
21 #include <boost/mpl/transform.hpp>
22 #include <boost/mpl/at.hpp>
23 #include <boost/mpl/set.hpp>
24 #include <boost/mpl/for_each.hpp>
25 #include <boost/mpl/index_of.hpp>
26 #include <typeinfo>
27
28 namespace boost {
29 namespace type_erasure {
30 namespace detail {
31
32 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
33
34 template<class P>
35 struct dynamic_binding_impl
36 {
37 const std::type_info * type;
38 };
39
40 template<class Table>
41 struct append_to_key {
42 template<class P>
43 void operator()(P) {
44 key->push_back(static_cast<const dynamic_binding_impl<P>*>(table)->type);
45 }
46 const Table * table;
47 key_type * key;
48 };
49
50 template<class... P>
51 struct dynamic_vtable : dynamic_binding_impl<P>... {
52 dynamic_vtable() = default;
53 template<class... T>
54 constexpr dynamic_vtable(T* ...t) : dynamic_binding_impl<P>{t}... {}
55 template<class F>
56 typename F::type lookup(F*) const {
57 key_type key;
58 typedef typename ::boost::type_erasure::detail::get_placeholders<F, ::boost::mpl::set0<> >::type placeholders;
59 typedef typename ::boost::mpl::fold<
60 placeholders,
61 ::boost::mpl::map0<>,
62 ::boost::type_erasure::detail::counting_map_appender
63 >::type placeholder_map;
64 key.push_back(&typeid(typename ::boost::type_erasure::detail::rebind_placeholders<F, placeholder_map>::type));
65 ::boost::mpl::for_each<placeholders>(append_to_key<dynamic_vtable>{this, &key});
66 return reinterpret_cast<typename F::type>(lookup_function_impl(key));
67 }
68 template<class Bindings>
69 void init() {
70 *this = dynamic_vtable(&typeid(typename boost::mpl::at<Bindings, P>::type)...);
71 }
72 template<class Bindings, class Src>
73 void convert_from(const Src& src) {
74 *this = dynamic_vtable(
75 (&src.lookup((::boost::type_erasure::typeid_<typename ::boost::mpl::at<Bindings, P>::type>*)0)())...);
76 }
77 };
78
79 template<class L>
80 struct make_dynamic_vtable_impl;
81
82 template<class... P>
83 struct make_dynamic_vtable_impl<stored_arg_pack<P...> >
84 {
85 typedef dynamic_vtable<P...> type;
86 };
87
88 template<class PlaceholderList>
89 struct make_dynamic_vtable
90 : make_dynamic_vtable_impl<typename make_arg_pack<PlaceholderList>::type>
91 {};
92
93 #else
94
95 template<class Bindings>
96 struct dynamic_vtable_initializer
97 {
98 dynamic_vtable_initializer(const std::type_info**& ptr) : types(&ptr) {}
99 template<class P>
100 void operator()(P)
101 {
102 *(*types)++ = &typeid(typename ::boost::mpl::at<Bindings, P>::type);
103 }
104 const ::std::type_info*** types;
105 };
106
107 template<class Placeholders>
108 struct dynamic_vtable
109 {
110 const ::std::type_info * types[(::boost::mpl::size<Placeholders>::value)];
111 struct append_to_key
112 {
113 append_to_key(const std::type_info * const * t, key_type* k) : types(t), key(k) {}
114 template<class P>
115 void operator()(P)
116 {
117 key->push_back(types[(::boost::mpl::index_of<Placeholders, P>::type::value)]);
118 }
119 const std::type_info * const * types;
120 key_type * key;
121 };
122 template<class F>
123 typename F::type lookup(F*) const {
124 key_type key;
125 typedef typename ::boost::type_erasure::detail::get_placeholders<F, ::boost::mpl::set0<> >::type placeholders;
126 typedef typename ::boost::mpl::fold<
127 placeholders,
128 ::boost::mpl::map0<>,
129 ::boost::type_erasure::detail::counting_map_appender
130 >::type placeholder_map;
131 key.push_back(&typeid(typename ::boost::type_erasure::detail::rebind_placeholders<F, placeholder_map>::type));
132 ::boost::mpl::for_each<placeholders>(append_to_key(types, &key));
133 return reinterpret_cast<typename F::type>(lookup_function_impl(key));
134 }
135 template<class Bindings>
136 void init()
137 {
138 const std::type_info* ptr = types;
139 ::boost::mpl::for_each<Placeholders>(dynamic_vtable_initializer<Bindings>(ptr));
140 }
141 template<class Bindings, class Src>
142 struct converter
143 {
144 converter(const std::type_info**& t, const Src& s) : types(&t), src(&s) {}
145 template<class P>
146 void operator()(P)
147 {
148 *(*types)++ = &src->lookup((::boost::type_erasure::typeid_<typename ::boost::mpl::at<Bindings, P>::type>*)0)();
149 }
150 const std::type_info*** types;
151 const Src * src;
152 };
153 template<class Bindings, class Src>
154 void convert_from(const Src& src) {
155 const ::std::type_info** ptr = types;
156 ::boost::mpl::for_each<Placeholders>(converter<Bindings, Src>(ptr, src));
157 }
158 };
159
160 template<class Placeholders>
161 struct make_dynamic_vtable
162 {
163 typedef dynamic_vtable<Placeholders> type;
164 };
165
166 #endif
167
168 }
169 }
170 }
171
172 #endif