Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:10:14

0001 // Boost.TypeErasure library
0002 //
0003 // Copyright 2015 Steven Watanabe
0004 //
0005 // Distributed under the Boost Software License Version 1.0. (See
0006 // accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // $Id$
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 // This placeholder exists solely to create a normalized
0066 // representation of a primitive concept.  For the moment
0067 // I'm going to be conservative and require a bijection
0068 // between the original placeholders and the normalized
0069 // placeholders.  It should be safe to map everything
0070 // to a single placeholder, though, as long as the
0071 // key includes every instance of each placeholder
0072 // as a separate element.  i.e. we should be able to
0073 // turn addable<_a, _b> into addable<_, _> and
0074 // addable<_a, _a> into addable<_, _> as well if we always
0075 // add typeids for both arguments to the search key.
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  * Registers a model of a concept to allow downcasting @ref any
0122  * via \dynamic_any_cast.
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  * \overload
0142  */
0143 template<class Concept, class T>
0144 void register_binding()
0145 {
0146     // Find all placeholders
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     // remove deduced placeholders
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     // Bind the single remaining placeholder to T
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