| // Copyright David Abrahams 2002. |
| // Distributed under the Boost Software License, Version 1.0. (See |
| // accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| #ifndef TO_PYTHON_INDIRECT_DWA200221_HPP |
| # define TO_PYTHON_INDIRECT_DWA200221_HPP |
| |
| # include <boost/python/detail/prefix.hpp> |
| |
| # include <boost/python/object/pointer_holder.hpp> |
| # include <boost/python/object/make_ptr_instance.hpp> |
| |
| # include <boost/python/detail/none.hpp> |
| |
| #ifndef BOOST_PYTHON_NO_PY_SIGNATURES |
| # include <boost/python/converter/pytype_function.hpp> |
| #endif |
| |
| # include <boost/python/refcount.hpp> |
| |
| # include <boost/type_traits/is_pointer.hpp> |
| # include <boost/type_traits/is_polymorphic.hpp> |
| |
| # include <boost/mpl/bool.hpp> |
| |
| # if defined(__ICL) && __ICL < 600 |
| # include <boost/shared_ptr.hpp> |
| # else |
| # include <memory> |
| # endif |
| |
| namespace boost { namespace python { |
| |
| template <class T, class MakeHolder> |
| struct to_python_indirect |
| { |
| template <class U> |
| inline PyObject* |
| operator()(U const& ref) const |
| { |
| return this->execute(const_cast<U&>(ref), is_pointer<U>()); |
| } |
| #ifndef BOOST_PYTHON_NO_PY_SIGNATURES |
| inline PyTypeObject const* |
| get_pytype()const |
| { |
| return converter::registered_pytype<T>::get_pytype(); |
| } |
| #endif |
| private: |
| template <class U> |
| inline PyObject* execute(U* ptr, mpl::true_) const |
| { |
| // No special NULL treatment for references |
| if (ptr == 0) |
| return python::detail::none(); |
| else |
| return this->execute(*ptr, mpl::false_()); |
| } |
| |
| template <class U> |
| inline PyObject* execute(U const& x, mpl::false_) const |
| { |
| U* const p = &const_cast<U&>(x); |
| if (is_polymorphic<U>::value) |
| { |
| if (PyObject* o = detail::wrapper_base_::owner(p)) |
| return incref(o); |
| } |
| return MakeHolder::execute(p); |
| } |
| }; |
| |
| // |
| // implementations |
| // |
| namespace detail |
| { |
| struct make_owning_holder |
| { |
| template <class T> |
| static PyObject* execute(T* p) |
| { |
| // can't use auto_ptr with Intel 5 and VC6 Dinkum library |
| // for some reason. We get link errors against the auto_ptr |
| // copy constructor. |
| # if defined(__ICL) && __ICL < 600 |
| typedef boost::shared_ptr<T> smart_pointer; |
| # else |
| typedef std::auto_ptr<T> smart_pointer; |
| # endif |
| typedef objects::pointer_holder<smart_pointer, T> holder_t; |
| |
| smart_pointer ptr(const_cast<T*>(p)); |
| return objects::make_ptr_instance<T, holder_t>::execute(ptr); |
| } |
| }; |
| |
| struct make_reference_holder |
| { |
| template <class T> |
| static PyObject* execute(T* p) |
| { |
| typedef objects::pointer_holder<T*, T> holder_t; |
| T* q = const_cast<T*>(p); |
| return objects::make_ptr_instance<T, holder_t>::execute(q); |
| } |
| }; |
| } |
| |
| }} // namespace boost::python |
| |
| #endif // TO_PYTHON_INDIRECT_DWA200221_HPP |