1 // Copyright David Abrahams 2002. 2 // Copyright Stefan Seefeld 2016. 3 // Distributed under the Boost Software License, Version 1.0. (See 4 // accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 #ifndef boost_python_converter_registered_hpp_ 8 #define boost_python_converter_registered_hpp_ 9 10 #include <boost/python/type_id.hpp> 11 #include <boost/python/converter/registry.hpp> 12 #include <boost/python/converter/registrations.hpp> 13 #include <boost/python/detail/type_traits.hpp> 14 #include <boost/detail/workaround.hpp> 15 #include <boost/type.hpp> 16 #include <memory> 17 #if defined(BOOST_PYTHON_TRACE_REGISTRY) \ 18 || defined(BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND) 19 # include <iostream> 20 #endif 21 22 namespace boost { 23 24 // You'll see shared_ptr mentioned in this header because we need to 25 // note which types are shared_ptrs in their registrations, to 26 // implement special shared_ptr handling for rvalue conversions. 27 template <class T> class shared_ptr; 28 29 namespace python { namespace converter { 30 31 struct registration; 32 33 namespace detail 34 { 35 template <class T> 36 struct registered_base 37 { 38 static registration const& converters; 39 }; 40 } 41 42 template <class T> 43 struct registered 44 : detail::registered_base< 45 typename boost::python::detail::add_lvalue_reference< 46 typename boost::python::detail::add_cv<T>::type 47 >::type 48 > 49 { 50 }; 51 52 # if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) 53 // collapses a few more types to the same static instance. MSVC7.1 54 // fails to strip cv-qualification from array types in typeid. For 55 // some reason we can't use this collapse there or array converters 56 // will not be found. 57 template <class T> 58 struct registered<T&> 59 : registered<T> {}; 60 # endif 61 62 // 63 // implementations 64 // 65 namespace detail 66 { 67 inline void register_shared_ptr0(...)68 register_shared_ptr0(...) 69 { 70 } 71 72 template <class T> 73 inline void register_shared_ptr0(shared_ptr<T> *)74 register_shared_ptr0(shared_ptr<T>*) 75 { 76 registry::lookup_shared_ptr(type_id<shared_ptr<T> >()); 77 } 78 79 #if !defined(BOOST_NO_CXX11_SMART_PTR) 80 template <class T> 81 inline void register_shared_ptr0(std::shared_ptr<T> *)82 register_shared_ptr0(std::shared_ptr<T>*) 83 { 84 registry::lookup_shared_ptr(type_id<std::shared_ptr<T> >()); 85 } 86 #endif 87 88 template <class T> 89 inline void register_shared_ptr1(T const volatile *)90 register_shared_ptr1(T const volatile*) 91 { 92 detail::register_shared_ptr0((T*)0); 93 } 94 95 template <class T> 96 inline registration const& registry_lookup2(T & (*)())97 registry_lookup2(T&(*)()) 98 { 99 detail::register_shared_ptr1((T*)0); 100 return registry::lookup(type_id<T&>()); 101 } 102 103 template <class T> 104 inline registration const& registry_lookup1(type<T>)105 registry_lookup1(type<T>) 106 { 107 return registry_lookup2((T(*)())0); 108 } 109 110 inline registration const& registry_lookup1(type<const volatile void>)111 registry_lookup1(type<const volatile void>) 112 { 113 detail::register_shared_ptr1((void*)0); 114 return registry::lookup(type_id<void>()); 115 } 116 117 template <class T> 118 registration const& registered_base<T>::converters = detail::registry_lookup1(type<T>()); 119 120 } 121 122 }}} // namespace boost::python::converter 123 124 #endif 125