// 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 |