File indexing completed on 2025-12-16 10:10:14
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_TYPE_ERASURE_REGISTER_BINDING_HPP_INCLUDED
0012 #define BOOST_TYPE_ERASURE_REGISTER_BINDING_HPP_INCLUDED
0013
0014 #include <boost/type_erasure/detail/check_map.hpp>
0015 #include <boost/type_erasure/detail/get_placeholders.hpp>
0016 #include <boost/type_erasure/detail/rebind_placeholders.hpp>
0017 #include <boost/type_erasure/detail/normalize.hpp>
0018 #include <boost/type_erasure/detail/adapt_to_vtable.hpp>
0019 #include <boost/type_erasure/detail/auto_link.hpp>
0020 #include <boost/type_erasure/static_binding.hpp>
0021 #include <boost/mpl/transform.hpp>
0022 #include <boost/mpl/remove_if.hpp>
0023 #include <boost/mpl/fold.hpp>
0024 #include <boost/mpl/at.hpp>
0025 #include <boost/mpl/has_key.hpp>
0026 #include <boost/mpl/insert.hpp>
0027 #include <boost/mpl/front.hpp>
0028 #include <boost/mpl/size.hpp>
0029 #include <boost/mpl/equal_to.hpp>
0030 #include <boost/mpl/or.hpp>
0031 #include <boost/mpl/set.hpp>
0032 #include <boost/mpl/map.hpp>
0033 #include <boost/mpl/vector.hpp>
0034 #include <boost/mpl/int.hpp>
0035 #include <boost/mpl/bool.hpp>
0036 #include <boost/mpl/pair.hpp>
0037 #include <boost/mpl/back_inserter.hpp>
0038 #include <boost/mpl/for_each.hpp>
0039 #include <vector>
0040 #include <typeinfo>
0041
0042 namespace boost {
0043 namespace type_erasure {
0044 namespace detail {
0045
0046 typedef std::vector<const std::type_info*> key_type;
0047 typedef void (*value_type)();
0048 BOOST_TYPE_ERASURE_DECL void register_function_impl(const key_type& key, value_type fn);
0049 BOOST_TYPE_ERASURE_DECL value_type lookup_function_impl(const key_type& key);
0050
0051 template<class Map>
0052 struct append_to_key_static {
0053 append_to_key_static(key_type* k) : key(k) {}
0054 template<class P>
0055 void operator()(P) {
0056 #ifndef BOOST_TYPE_ERASURE_USE_MP11
0057 key->push_back(&typeid(typename ::boost::mpl::at<Map, P>::type));
0058 #else
0059 key->push_back(&typeid(::boost::mp11::mp_second< ::boost::mp11::mp_map_find<Map, P> >));
0060 #endif
0061 }
0062 key_type* key;
0063 };
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 template<int N>
0077 struct _ : ::boost::type_erasure::placeholder {};
0078
0079 struct counting_map_appender
0080 {
0081 template<class State, class Key>
0082 struct apply
0083 {
0084 typedef typename ::boost::mpl::insert<
0085 State,
0086 ::boost::mpl::pair<
0087 Key,
0088 ::boost::type_erasure::detail::_<
0089 ::boost::mpl::size<State>::value
0090 >
0091 >
0092 >::type type;
0093 };
0094 };
0095
0096 template<class Map>
0097 struct register_function {
0098 template<class F>
0099 void operator()(F) {
0100 key_type key;
0101 #ifndef BOOST_TYPE_ERASURE_USE_MP11
0102 typedef typename ::boost::type_erasure::detail::get_placeholders<F, ::boost::mpl::set0<> >::type placeholders;
0103 #else
0104 typedef typename ::boost::type_erasure::detail::get_placeholders<F, ::boost::mp11::mp_list<> >::type placeholders;
0105 #endif
0106 typedef typename ::boost::mpl::fold<
0107 placeholders,
0108 ::boost::mpl::map0<>,
0109 ::boost::type_erasure::detail::counting_map_appender
0110 >::type placeholder_map;
0111 key.push_back(&typeid(typename ::boost::type_erasure::detail::rebind_placeholders<F, placeholder_map>::type));
0112 ::boost::mpl::for_each<placeholders>(append_to_key_static<Map>(&key));
0113 value_type fn = reinterpret_cast<value_type>(&::boost::type_erasure::detail::rebind_placeholders<F, Map>::type::value);
0114 ::boost::type_erasure::detail::register_function_impl(key, fn);
0115 }
0116 };
0117
0118 }
0119
0120
0121
0122
0123
0124 template<class Concept, class Map>
0125 void register_binding(const static_binding<Map>&)
0126 {
0127 typedef typename ::boost::type_erasure::detail::normalize_concept<
0128 Concept
0129 >::type normalized;
0130 typedef typename ::boost::mpl::transform<normalized,
0131 ::boost::type_erasure::detail::maybe_adapt_to_vtable< ::boost::mpl::_1>
0132 >::type actual_concept;
0133 typedef typename ::boost::type_erasure::detail::get_placeholder_normalization_map<
0134 Concept
0135 >::type placeholder_subs;
0136 typedef typename ::boost::type_erasure::detail::add_deductions<Map, placeholder_subs>::type actual_map;
0137 ::boost::mpl::for_each<actual_concept>(::boost::type_erasure::detail::register_function<actual_map>());
0138 }
0139
0140
0141
0142
0143 template<class Concept, class T>
0144 void register_binding()
0145 {
0146
0147 typedef typename ::boost::type_erasure::detail::normalize_concept_impl<Concept>::type normalized;
0148 typedef typename normalized::first basic;
0149 typedef typename ::boost::mpl::fold<
0150 basic,
0151 #ifndef BOOST_TYPE_ERASURE_USE_MP11
0152 ::boost::mpl::set0<>,
0153 #else
0154 ::boost::mp11::mp_list<>,
0155 #endif
0156 ::boost::type_erasure::detail::get_placeholders< ::boost::mpl::_2, ::boost::mpl::_1>
0157 >::type all_placeholders;
0158
0159 typedef typename ::boost::mpl::fold<
0160 typename normalized::second,
0161 ::boost::mpl::set0<>,
0162 ::boost::mpl::insert< ::boost::mpl::_1, ::boost::mpl::second< ::boost::mpl::_2> >
0163 >::type xtra_deduced;
0164 typedef typename ::boost::mpl::remove_if<
0165 all_placeholders,
0166 ::boost::mpl::or_<
0167 ::boost::type_erasure::detail::is_deduced< ::boost::mpl::_1>,
0168 ::boost::mpl::has_key<xtra_deduced, ::boost::mpl::_1>
0169 >,
0170 ::boost::mpl::back_inserter< ::boost::mpl::vector0<> >
0171 >::type unknown_placeholders;
0172
0173 BOOST_MPL_ASSERT((boost::mpl::equal_to<boost::mpl::size<unknown_placeholders>, boost::mpl::int_<1> >));
0174 register_binding<Concept>(::boost::type_erasure::make_binding<
0175 ::boost::mpl::map< ::boost::mpl::pair<typename ::boost::mpl::front<unknown_placeholders>::type, T> > >());
0176 }
0177
0178 }
0179 }
0180
0181 #endif