Warning, file /include/boost/type_erasure/binding.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_TYPE_ERASURE_BINDING_HPP_INCLUDED
0012 #define BOOST_TYPE_ERASURE_BINDING_HPP_INCLUDED
0013
0014 #include <boost/config.hpp>
0015 #include <boost/shared_ptr.hpp>
0016 #include <boost/make_shared.hpp>
0017 #include <boost/utility/enable_if.hpp>
0018 #include <boost/mpl/transform.hpp>
0019 #include <boost/mpl/find_if.hpp>
0020 #include <boost/mpl/and.hpp>
0021 #include <boost/mpl/not.hpp>
0022 #include <boost/mpl/end.hpp>
0023 #include <boost/mpl/bool.hpp>
0024 #include <boost/mpl/pair.hpp>
0025 #include <boost/type_traits/is_same.hpp>
0026 #include <boost/type_erasure/static_binding.hpp>
0027 #include <boost/type_erasure/is_subconcept.hpp>
0028 #include <boost/type_erasure/detail/adapt_to_vtable.hpp>
0029 #include <boost/type_erasure/detail/null.hpp>
0030 #include <boost/type_erasure/detail/rebind_placeholders.hpp>
0031 #include <boost/type_erasure/detail/vtable.hpp>
0032 #include <boost/type_erasure/detail/normalize.hpp>
0033 #include <boost/type_erasure/detail/instantiate.hpp>
0034 #include <boost/type_erasure/detail/check_map.hpp>
0035
0036 namespace boost {
0037 namespace type_erasure {
0038
0039 template<class P>
0040 class dynamic_binding;
0041
0042 namespace detail {
0043
0044 template<class Source, class Dest, class Map>
0045 struct can_optimize_conversion : ::boost::mpl::and_<
0046 ::boost::is_same<Source, Dest>,
0047 ::boost::is_same<
0048 typename ::boost::mpl::find_if<
0049 Map,
0050 ::boost::mpl::not_<
0051 ::boost::is_same<
0052 ::boost::mpl::first< ::boost::mpl::_1>,
0053 ::boost::mpl::second< ::boost::mpl::_1>
0054 >
0055 >
0056 >::type,
0057 typename ::boost::mpl::end<Map>::type
0058 >
0059 >::type
0060 {};
0061
0062 }
0063
0064
0065
0066
0067
0068 template<class Concept>
0069 class binding
0070 {
0071 typedef typename ::boost::type_erasure::detail::normalize_concept<
0072 Concept>::type normalized;
0073 typedef typename ::boost::mpl::transform<normalized,
0074 ::boost::type_erasure::detail::maybe_adapt_to_vtable< ::boost::mpl::_1>
0075 >::type actual_concept;
0076 typedef typename ::boost::type_erasure::detail::make_vtable<
0077 actual_concept>::type table_type;
0078 typedef typename ::boost::type_erasure::detail::get_placeholder_normalization_map<
0079 Concept
0080 >::type placeholder_subs;
0081 public:
0082
0083
0084
0085
0086
0087
0088 binding() { BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed<Concept>)); }
0089
0090
0091
0092
0093
0094
0095
0096 template<class Map>
0097 explicit binding(const Map&)
0098 : impl((
0099 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
0100 static_binding<Map>()
0101 ))
0102 {}
0103
0104
0105
0106
0107
0108
0109
0110 template<class Map>
0111 binding(const static_binding<Map>&)
0112 : impl((
0113 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
0114 static_binding<Map>()
0115 ))
0116 {}
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127 template<class Concept2, class Map>
0128 binding(const binding<Concept2>& other, const Map&
0129 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
0130 , typename ::boost::enable_if<
0131 ::boost::mpl::and_<
0132 ::boost::type_erasure::detail::check_map<Concept, Map>,
0133 ::boost::type_erasure::is_subconcept<Concept, Concept2, Map>
0134 >
0135 >::type* = 0
0136 #endif
0137 )
0138 : impl(
0139 other,
0140 static_binding<Map>(),
0141 ::boost::type_erasure::detail::can_optimize_conversion<Concept2, Concept, Map>()
0142 )
0143 {}
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 template<class Concept2, class Map>
0155 binding(const binding<Concept2>& other, const static_binding<Map>&
0156 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
0157 , typename ::boost::enable_if<
0158 ::boost::mpl::and_<
0159 ::boost::type_erasure::detail::check_map<Concept, Map>,
0160 ::boost::type_erasure::is_subconcept<Concept, Concept2, Map>
0161 >
0162 >::type* = 0
0163 #endif
0164 )
0165 : impl(
0166 other,
0167 static_binding<Map>(),
0168 ::boost::type_erasure::detail::can_optimize_conversion<Concept2, Concept, Map>()
0169 )
0170 {}
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 template<class Placeholders, class Map>
0183 binding(const dynamic_binding<Placeholders>& other, const static_binding<Map>&)
0184 : impl(
0185 other,
0186 static_binding<Map>()
0187 )
0188 {}
0189
0190
0191
0192
0193
0194
0195
0196 friend bool operator==(const binding& lhs, const binding& rhs)
0197 { return *lhs.impl.table == *rhs.impl.table; }
0198
0199
0200
0201
0202
0203
0204
0205 friend bool operator!=(const binding& lhs, const binding& rhs)
0206 { return !(lhs == rhs); }
0207
0208
0209 template<class T>
0210 typename T::type find() const { return impl.table->lookup((T*)0); }
0211 private:
0212 template<class C2>
0213 friend class binding;
0214 template<class P>
0215 friend class dynamic_binding;
0216
0217 struct impl_type
0218 {
0219 impl_type() {
0220 table = &::boost::type_erasure::detail::make_vtable_init<
0221 typename ::boost::mpl::transform<
0222 actual_concept,
0223 ::boost::type_erasure::detail::get_null_vtable_entry<
0224 ::boost::mpl::_1
0225 >
0226 >::type,
0227 table_type
0228 >::type::value;
0229 }
0230 template<class Map>
0231 impl_type(const static_binding<Map>&)
0232 {
0233 table = &::boost::type_erasure::detail::make_vtable_init<
0234 typename ::boost::mpl::transform<
0235 actual_concept,
0236 ::boost::type_erasure::detail::rebind_placeholders<
0237 ::boost::mpl::_1,
0238 typename ::boost::type_erasure::detail::add_deductions<
0239 Map,
0240 placeholder_subs
0241 >::type
0242 >
0243 >::type,
0244 table_type
0245 >::type::value;
0246 }
0247 template<class Concept2, class Map>
0248 impl_type(const binding<Concept2>& other, const static_binding<Map>&, boost::mpl::false_)
0249 : manager(new table_type)
0250 {
0251 manager->template convert_from<
0252 typename ::boost::type_erasure::detail::convert_deductions<
0253 Map,
0254 placeholder_subs,
0255 typename binding<Concept2>::placeholder_subs
0256 >::type
0257 >(*other.impl.table);
0258 table = manager.get();
0259 }
0260 template<class PlaceholderList, class Map>
0261 impl_type(const dynamic_binding<PlaceholderList>& other, const static_binding<Map>&)
0262 : manager(new table_type)
0263 {
0264 manager->template convert_from<
0265
0266 typename ::boost::type_erasure::detail::add_deductions<
0267 Map,
0268 placeholder_subs
0269 >::type
0270 >(other.impl);
0271 table = manager.get();
0272 }
0273 template<class Concept2, class Map>
0274 impl_type(const binding<Concept2>& other, const static_binding<Map>&, boost::mpl::true_)
0275 : table(other.impl.table),
0276 manager(other.impl.manager)
0277 {}
0278 const table_type* table;
0279 ::boost::shared_ptr<table_type> manager;
0280 } impl;
0281 };
0282
0283 }
0284 }
0285
0286 #endif