1 // Copyright David Abrahams 2002.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 #ifndef TO_PYTHON_INDIRECT_DWA200221_HPP
6 # define TO_PYTHON_INDIRECT_DWA200221_HPP
7 
8 # include <boost/python/detail/prefix.hpp>
9 
10 # include <boost/python/object/pointer_holder.hpp>
11 # include <boost/python/object/make_ptr_instance.hpp>
12 
13 # include <boost/python/detail/none.hpp>
14 
15 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
16 # include <boost/python/converter/pytype_function.hpp>
17 #endif
18 
19 # include <boost/python/refcount.hpp>
20 
21 # include <boost/python/detail/type_traits.hpp>
22 
23 # if defined(__ICL) && __ICL < 600
24 #  include <boost/shared_ptr.hpp>
25 # else
26 #  include <memory>
27 # endif
28 
29 namespace boost { namespace python {
30 
31 template <class T, class MakeHolder>
32 struct to_python_indirect
33 {
34     template <class U>
35     inline PyObject*
operator ()boost::python::to_python_indirect36     operator()(U const& ref) const
37     {
38         return this->execute(const_cast<U&>(ref), detail::is_pointer<U>());
39     }
40 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
41     inline PyTypeObject const*
get_pytypeboost::python::to_python_indirect42     get_pytype()const
43     {
44         return converter::registered_pytype<T>::get_pytype();
45     }
46 #endif
47  private:
48     template <class U>
executeboost::python::to_python_indirect49     inline PyObject* execute(U* ptr, detail::true_) const
50     {
51         // No special NULL treatment for references
52         if (ptr == 0)
53             return python::detail::none();
54         else
55             return this->execute(*ptr, detail::false_());
56     }
57 
58     template <class U>
executeboost::python::to_python_indirect59     inline PyObject* execute(U const& x, detail::false_) const
60     {
61         U* const p = &const_cast<U&>(x);
62         if (detail::is_polymorphic<U>::value)
63         {
64             if (PyObject* o = detail::wrapper_base_::owner(p))
65                 return incref(o);
66         }
67         return MakeHolder::execute(p);
68     }
69 };
70 
71 //
72 // implementations
73 //
74 namespace detail
75 {
76   struct make_owning_holder
77   {
78       template <class T>
executeboost::python::detail::make_owning_holder79       static PyObject* execute(T* p)
80       {
81           // can't use auto_ptr with Intel 5 and VC6 Dinkum library
82           // for some reason. We get link errors against the auto_ptr
83           // copy constructor.
84 # if defined(__ICL) && __ICL < 600
85           typedef boost::shared_ptr<T> smart_pointer;
86 # elif defined(BOOST_NO_CXX11_SMART_PTR)
87           typedef std::auto_ptr<T> smart_pointer;
88 # else
89           typedef std::unique_ptr<T> smart_pointer;
90 # endif
91           typedef objects::pointer_holder<smart_pointer, T> holder_t;
92 
93           smart_pointer ptr(const_cast<T*>(p));
94           return objects::make_ptr_instance<T, holder_t>::execute(ptr);
95       }
96   };
97 
98   struct make_reference_holder
99   {
100       template <class T>
executeboost::python::detail::make_reference_holder101       static PyObject* execute(T* p)
102       {
103           typedef objects::pointer_holder<T*, T> holder_t;
104           T* q = const_cast<T*>(p);
105           return objects::make_ptr_instance<T, holder_t>::execute(q);
106       }
107   };
108 }
109 
110 }} // namespace boost::python
111 
112 #endif // TO_PYTHON_INDIRECT_DWA200221_HPP
113