]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/type_erasure/include/boost/type_erasure/binding.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / type_erasure / include / boost / type_erasure / binding.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#ifndef BOOST_TYPE_ERASURE_BINDING_HPP_INCLUDED
12#define BOOST_TYPE_ERASURE_BINDING_HPP_INCLUDED
13
14#include <boost/config.hpp>
15#include <boost/shared_ptr.hpp>
16#include <boost/make_shared.hpp>
17#include <boost/utility/enable_if.hpp>
18#include <boost/mpl/transform.hpp>
19#include <boost/mpl/find_if.hpp>
20#include <boost/mpl/and.hpp>
21#include <boost/mpl/not.hpp>
22#include <boost/mpl/end.hpp>
23#include <boost/mpl/bool.hpp>
24#include <boost/mpl/pair.hpp>
25#include <boost/type_traits/is_same.hpp>
26#include <boost/type_erasure/static_binding.hpp>
27#include <boost/type_erasure/is_subconcept.hpp>
28#include <boost/type_erasure/detail/adapt_to_vtable.hpp>
29#include <boost/type_erasure/detail/null.hpp>
30#include <boost/type_erasure/detail/rebind_placeholders.hpp>
31#include <boost/type_erasure/detail/vtable.hpp>
32#include <boost/type_erasure/detail/normalize.hpp>
33#include <boost/type_erasure/detail/instantiate.hpp>
34#include <boost/type_erasure/detail/check_map.hpp>
35
36namespace boost {
37namespace type_erasure {
38
39template<class P>
40class dynamic_binding;
41
42namespace detail {
43
44template<class Source, class Dest, class Map>
45struct can_optimize_conversion : ::boost::mpl::and_<
46 ::boost::is_same<Source, Dest>,
47 ::boost::is_same<
48 typename ::boost::mpl::find_if<
49 Map,
50 ::boost::mpl::not_<
51 ::boost::is_same<
52 ::boost::mpl::first< ::boost::mpl::_1>,
53 ::boost::mpl::second< ::boost::mpl::_1>
54 >
55 >
56 >::type,
57 typename ::boost::mpl::end<Map>::type
58 >
59 >::type
60{};
61
62}
63
64/**
65 * Stores the binding of a @c Concept to a set of actual types.
66 * @c Concept is interpreted in the same way as with @ref any.
67 */
68template<class Concept>
69class binding
70{
71 typedef typename ::boost::type_erasure::detail::normalize_concept<
72 Concept>::type normalized;
73 typedef typename ::boost::mpl::transform<normalized,
74 ::boost::type_erasure::detail::maybe_adapt_to_vtable< ::boost::mpl::_1>
75 >::type actual_concept;
76 typedef typename ::boost::type_erasure::detail::make_vtable<
77 actual_concept>::type table_type;
78 typedef typename ::boost::type_erasure::detail::get_placeholder_normalization_map<
79 Concept
80 >::type placeholder_subs;
81public:
82
83 /**
84 * \pre @ref relaxed must be in @c Concept.
85 *
86 * \throws Nothing.
87 */
88 binding() { BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed<Concept>)); }
89
90 /**
91 * \pre @c Map must be an MPL map with an entry for each placeholder
92 * referred to by @c Concept.
93 *
94 * \throws Nothing.
95 */
96 template<class Map>
97 explicit binding(const Map&)
98 : impl((
99 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
100 static_binding<Map>()
101 ))
102 {}
103
104 /**
105 * \pre @c Map must be an MPL map with an entry for each placeholder
106 * referred to by @c Concept.
107 *
108 * \throws Nothing.
109 */
110 template<class Map>
111 binding(const static_binding<Map>&)
112 : impl((
113 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
114 static_binding<Map>()
115 ))
116 {}
117
118 /**
119 * Converts from another set of bindings.
120 *
121 * \pre Map must be an MPL map with an entry for each placeholder
122 * referred to by @c Concept. The mapped type should be the
123 * corresponding placeholder in Concept2.
124 *
125 * \throws std::bad_alloc
126 */
127 template<class Concept2, class Map>
128 binding(const binding<Concept2>& other, const Map&
129#ifndef BOOST_TYPE_ERASURE_DOXYGEN
130 , typename ::boost::enable_if<
131 ::boost::mpl::and_<
132 ::boost::type_erasure::detail::check_map<Concept, Map>,
133 ::boost::type_erasure::is_subconcept<Concept, Concept2, Map>
134 >
135 >::type* = 0
136#endif
137 )
138 : impl(
139 other,
140 static_binding<Map>(),
141 ::boost::type_erasure::detail::can_optimize_conversion<Concept2, Concept, Map>()
142 )
143 {}
144
145 /**
146 * Converts from another set of bindings.
147 *
148 * \pre Map must be an MPL map with an entry for each placeholder
149 * referred to by @c Concept. The mapped type should be the
150 * corresponding placeholder in Concept2.
151 *
152 * \throws std::bad_alloc
153 */
154 template<class Concept2, class Map>
155 binding(const binding<Concept2>& other, const static_binding<Map>&
156#ifndef BOOST_TYPE_ERASURE_DOXYGEN
157 , typename ::boost::enable_if<
158 ::boost::mpl::and_<
159 ::boost::type_erasure::detail::check_map<Concept, Map>,
160 ::boost::type_erasure::is_subconcept<Concept, Concept2, Map>
161 >
162 >::type* = 0
163#endif
164 )
165 : impl(
166 other,
167 static_binding<Map>(),
168 ::boost::type_erasure::detail::can_optimize_conversion<Concept2, Concept, Map>()
169 )
170 {}
171
172 /**
173 * Converts from another set of bindings.
174 *
175 * \pre Map must be an MPL map with an entry for each placeholder
176 * referred to by @c Concept. The mapped type should be the
177 * corresponding placeholder in Concept2.
178 *
179 * \throws std::bad_alloc
180 * \throws std::bad_any_cast
181 */
182 template<class Placeholders, class Map>
183 binding(const dynamic_binding<Placeholders>& other, const static_binding<Map>&)
184 : impl(
185 other,
186 static_binding<Map>()
187 )
188 {}
189
190 /**
191 * \return true iff the sets of types that the placeholders
192 * bind to are the same for both arguments.
193 *
194 * \throws Nothing.
195 */
196 friend bool operator==(const binding& lhs, const binding& rhs)
197 { return *lhs.impl.table == *rhs.impl.table; }
198
199 /**
200 * \return true iff the arguments do not map to identical
201 * sets of types.
202 *
203 * \throws Nothing.
204 */
205 friend bool operator!=(const binding& lhs, const binding& rhs)
206 { return !(lhs == rhs); }
207
208 /** INTERNAL ONLY */
209 template<class T>
210 typename T::type find() const { return impl.table->lookup((T*)0); }
211private:
212 template<class C2>
213 friend class binding;
214 template<class P>
215 friend class dynamic_binding;
216 /** INTERNAL ONLY */
217 struct impl_type
218 {
219 impl_type() {
220 table = &::boost::type_erasure::detail::make_vtable_init<
221 typename ::boost::mpl::transform<
222 actual_concept,
223 ::boost::type_erasure::detail::get_null_vtable_entry<
224 ::boost::mpl::_1
225 >
226 >::type,
227 table_type
228 >::type::value;
229 }
230 template<class Map>
231 impl_type(const static_binding<Map>&)
232 {
233 table = &::boost::type_erasure::detail::make_vtable_init<
234 typename ::boost::mpl::transform<
235 actual_concept,
236 ::boost::type_erasure::detail::rebind_placeholders<
237 ::boost::mpl::_1,
238 typename ::boost::type_erasure::detail::add_deductions<
239 Map,
240 placeholder_subs
241 >::type
242 >
243 >::type,
244 table_type
245 >::type::value;
246 }
247 template<class Concept2, class Map>
248 impl_type(const binding<Concept2>& other, const static_binding<Map>&, boost::mpl::false_)
249 : manager(new table_type)
250 {
251 manager->template convert_from<
252 typename ::boost::type_erasure::detail::convert_deductions<
253 Map,
254 placeholder_subs,
255 typename binding<Concept2>::placeholder_subs
256 >::type
257 >(*other.impl.table);
258 table = manager.get();
259 }
260 template<class PlaceholderList, class Map>
261 impl_type(const dynamic_binding<PlaceholderList>& other, const static_binding<Map>&)
262 : manager(new table_type)
263 {
264 manager->template convert_from<
265 // FIXME: What do we need to do with deduced placeholder in other
266 typename ::boost::type_erasure::detail::add_deductions<
267 Map,
268 placeholder_subs
269 >::type
270 >(other.impl);
271 table = manager.get();
272 }
273 template<class Concept2, class Map>
274 impl_type(const binding<Concept2>& other, const static_binding<Map>&, boost::mpl::true_)
275 : table(other.impl.table),
276 manager(other.impl.manager)
277 {}
278 const table_type* table;
279 ::boost::shared_ptr<table_type> manager;
280 } impl;
281};
282
283}
284}
285
286#endif