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/type_traits/is_pointer.hpp> |
22 | # include <boost/type_traits/is_polymorphic.hpp> |
23 | |
24 | # include <boost/mpl/bool.hpp> |
25 | |
26 | # if defined(__ICL) && __ICL < 600 |
27 | # include <boost/shared_ptr.hpp> |
28 | # else |
29 | # include <memory> |
30 | # endif |
31 | |
32 | namespace boost { namespace python { |
33 | |
34 | template <class T, class MakeHolder> |
35 | struct to_python_indirect |
36 | { |
37 | template <class U> |
38 | inline PyObject* |
39 | operator()(U const& ref) const |
40 | { |
41 | return this->execute(const_cast<U&>(ref), is_pointer<U>()); |
42 | } |
43 | #ifndef BOOST_PYTHON_NO_PY_SIGNATURES |
44 | inline PyTypeObject const* |
45 | get_pytype()const |
46 | { |
47 | return converter::registered_pytype<T>::get_pytype(); |
48 | } |
49 | #endif |
50 | private: |
51 | template <class U> |
52 | inline PyObject* execute(U* ptr, mpl::true_) const |
53 | { |
54 | // No special NULL treatment for references |
55 | if (ptr == 0) |
56 | return python::detail::none(); |
57 | else |
58 | return this->execute(*ptr, mpl::false_()); |
59 | } |
60 | |
61 | template <class U> |
62 | inline PyObject* execute(U const& x, mpl::false_) const |
63 | { |
64 | U* const p = &const_cast<U&>(x); |
65 | if (is_polymorphic<U>::value) |
66 | { |
67 | if (PyObject* o = detail::wrapper_base_::owner(p)) |
68 | return incref(o); |
69 | } |
70 | return MakeHolder::execute(p); |
71 | } |
72 | }; |
73 | |
74 | // |
75 | // implementations |
76 | // |
77 | namespace detail |
78 | { |
79 | struct make_owning_holder |
80 | { |
81 | template <class T> |
82 | static PyObject* execute(T* p) |
83 | { |
84 | // can't use auto_ptr with Intel 5 and VC6 Dinkum library |
85 | // for some reason. We get link errors against the auto_ptr |
86 | // copy constructor. |
87 | # if defined(__ICL) && __ICL < 600 |
88 | typedef boost::shared_ptr<T> smart_pointer; |
89 | # else |
90 | typedef std::auto_ptr<T> smart_pointer; |
91 | # endif |
92 | typedef objects::pointer_holder<smart_pointer, T> holder_t; |
93 | |
94 | smart_pointer ptr(const_cast<T*>(p)); |
95 | return objects::make_ptr_instance<T, holder_t>::execute(ptr); |
96 | } |
97 | }; |
98 | |
99 | struct make_reference_holder |
100 | { |
101 | template <class T> |
102 | static PyObject* execute(T* p) |
103 | { |
104 | typedef objects::pointer_holder<T*, T> holder_t; |
105 | T* q = const_cast<T*>(p); |
106 | return objects::make_ptr_instance<T, holder_t>::execute(q); |
107 | } |
108 | }; |
109 | } |
110 | |
111 | }} // namespace boost::python |
112 | |
113 | #endif // TO_PYTHON_INDIRECT_DWA200221_HPP |
114 | |