// 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 HANDLE_DWA200269_HPP # define HANDLE_DWA200269_HPP # include # include # include # include # include # include # include # include namespace boost { namespace python { template struct null_ok; template inline null_ok* allow_null(T* p) { return (null_ok*)p; } namespace detail { template inline T* manage_ptr(detail::borrowed >* p, int) { return python::xincref((T*)p); } template inline T* manage_ptr(null_ok >* p, int) { return python::xincref((T*)p); } template inline T* manage_ptr(detail::borrowed* p, long) { return python::incref(expect_non_null((T*)p)); } template inline T* manage_ptr(null_ok* p, long) { return (T*)p; } template inline T* manage_ptr(T* p, ...) { return expect_non_null(p); } } template class handle { typedef T* (handle::* bool_type )() const; public: // types typedef T element_type; public: // member functions handle(); ~handle(); template explicit handle(Y* p) : m_p( python::upcast( detail::manage_ptr(p, 0) ) ) { } handle& operator=(handle const& r) { python::xdecref(m_p); m_p = python::xincref(r.m_p); return *this; } #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300) template handle& operator=(handle const & r) // never throws { python::xdecref(m_p); m_p = python::xincref(python::upcast(r.get())); return *this; } #endif template handle(handle const& r) : m_p(python::xincref(python::upcast(r.get()))) { } handle(handle const& r) : m_p(python::xincref(r.m_p)) { } T* operator-> () const; T& operator* () const; T* get() const; T* release(); void reset(); operator bool_type() const // never throws { return m_p ? &handle::get : 0; } bool operator! () const; // never throws public: // implementation details -- do not touch // Defining this in the class body suppresses a VC7 link failure inline handle(detail::borrowed_reference x) : m_p( python::incref( downcast((PyObject*)x) )) { } private: // data members T* m_p; }; #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP } // namespace python #endif template inline T * get_pointer(python::handle const & p) { return p.get(); } #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP namespace python { #else // We don't want get_pointer above to hide the others using boost::get_pointer; #endif typedef handle type_handle; // // Compile-time introspection // # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template class is_handle { public: BOOST_STATIC_CONSTANT(bool, value = false); }; template class is_handle > { public: BOOST_STATIC_CONSTANT(bool, value = true); }; # else namespace detail { typedef char (&yes_handle_t)[1]; typedef char (&no_handle_t)[2]; no_handle_t is_handle_test(...); template yes_handle_t is_handle_test(boost::type< handle >); } template class is_handle { public: BOOST_STATIC_CONSTANT( bool, value = ( sizeof(detail::is_handle_test(boost::type())) == sizeof(detail::yes_handle_t))); }; # endif // // implementations // template inline handle::handle() : m_p(0) { } template inline handle::~handle() { python::xdecref(m_p); } template inline T* handle::operator->() const { return m_p; } template inline T& handle::operator*() const { return *m_p; } template inline T* handle::get() const { return m_p; } template inline bool handle::operator!() const { return m_p == 0; } template inline T* handle::release() { T* result = m_p; m_p = 0; return result; } template inline void handle::reset() { python::xdecref(m_p); m_p = 0; } // Because get_managed_object must return a non-null PyObject*, we // return Py_None if the handle is null. template inline PyObject* get_managed_object(handle const& h, tag_t) { return h.get() ? python::upcast(h.get()) : Py_None; } }} // namespace boost::python #endif // HANDLE_DWA200269_HPP