]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
b32b8144 | 21 | # include <boost/python/detail/type_traits.hpp> |
7c673cae FG |
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* | |
36 | operator()(U const& ref) const | |
37 | { | |
b32b8144 | 38 | return this->execute(const_cast<U&>(ref), detail::is_pointer<U>()); |
7c673cae FG |
39 | } |
40 | #ifndef BOOST_PYTHON_NO_PY_SIGNATURES | |
41 | inline PyTypeObject const* | |
42 | get_pytype()const | |
43 | { | |
44 | return converter::registered_pytype<T>::get_pytype(); | |
45 | } | |
46 | #endif | |
47 | private: | |
48 | template <class U> | |
b32b8144 | 49 | inline PyObject* execute(U* ptr, detail::true_) const |
7c673cae FG |
50 | { |
51 | // No special NULL treatment for references | |
52 | if (ptr == 0) | |
53 | return python::detail::none(); | |
54 | else | |
b32b8144 | 55 | return this->execute(*ptr, detail::false_()); |
7c673cae FG |
56 | } |
57 | ||
58 | template <class U> | |
b32b8144 | 59 | inline PyObject* execute(U const& x, detail::false_) const |
7c673cae FG |
60 | { |
61 | U* const p = &const_cast<U&>(x); | |
b32b8144 | 62 | if (detail::is_polymorphic<U>::value) |
7c673cae FG |
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> | |
79 | 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; | |
b32b8144 | 86 | # elif defined(BOOST_NO_CXX11_SMART_PTR) |
7c673cae FG |
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> | |
101 | 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 |