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