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