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/python/detail/type_traits.hpp> 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* operator ()boost::python::to_python_indirect36 operator()(U const& ref) const 37 { 38 return this->execute(const_cast<U&>(ref), detail::is_pointer<U>()); 39 } 40 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES 41 inline PyTypeObject const* get_pytypeboost::python::to_python_indirect42 get_pytype()const 43 { 44 return converter::registered_pytype<T>::get_pytype(); 45 } 46 #endif 47 private: 48 template <class U> executeboost::python::to_python_indirect49 inline PyObject* execute(U* ptr, detail::true_) const 50 { 51 // No special NULL treatment for references 52 if (ptr == 0) 53 return python::detail::none(); 54 else 55 return this->execute(*ptr, detail::false_()); 56 } 57 58 template <class U> executeboost::python::to_python_indirect59 inline PyObject* execute(U const& x, detail::false_) const 60 { 61 U* const p = &const_cast<U&>(x); 62 if (detail::is_polymorphic<U>::value) 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> executeboost::python::detail::make_owning_holder79 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; 86 # elif defined(BOOST_NO_CXX11_SMART_PTR) 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> executeboost::python::detail::make_reference_holder101 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 113