238 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			238 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | // 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 <boost/python/detail/prefix.hpp> | ||
|  | 
 | ||
|  | # include <boost/python/cast.hpp> | ||
|  | # include <boost/python/errors.hpp> | ||
|  | # include <boost/python/borrowed.hpp> | ||
|  | # include <boost/python/handle_fwd.hpp> | ||
|  | # include <boost/python/refcount.hpp> | ||
|  | # include <boost/python/tag.hpp> | ||
|  | # include <boost/python/detail/raw_pyobject.hpp> | ||
|  | 
 | ||
|  | namespace boost { namespace python {  | ||
|  | 
 | ||
|  | template <class T> struct null_ok; | ||
|  | 
 | ||
|  | template <class T> | ||
|  | inline null_ok<T>* allow_null(T* p) | ||
|  | { | ||
|  |     return (null_ok<T>*)p; | ||
|  | } | ||
|  | 
 | ||
|  | namespace detail | ||
|  | { | ||
|  |   template <class T> | ||
|  |   inline T* manage_ptr(detail::borrowed<null_ok<T> >* p, int) | ||
|  |   { | ||
|  |       return python::xincref((T*)p); | ||
|  |   } | ||
|  |    | ||
|  |   template <class T> | ||
|  |   inline T* manage_ptr(null_ok<detail::borrowed<T> >* p, int) | ||
|  |   { | ||
|  |       return python::xincref((T*)p); | ||
|  |   } | ||
|  |    | ||
|  |   template <class T> | ||
|  |   inline T* manage_ptr(detail::borrowed<T>* p, long) | ||
|  |   { | ||
|  |       return python::incref(expect_non_null((T*)p)); | ||
|  |   } | ||
|  |    | ||
|  |   template <class T> | ||
|  |   inline T* manage_ptr(null_ok<T>* p, long) | ||
|  |   { | ||
|  |       return (T*)p; | ||
|  |   } | ||
|  |    | ||
|  |   template <class T> | ||
|  |   inline T* manage_ptr(T* p, ...) | ||
|  |   { | ||
|  |       return expect_non_null(p); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | template <class T> | ||
|  | class handle | ||
|  | { | ||
|  |     typedef T* (handle::* bool_type )() const; | ||
|  | 
 | ||
|  |  public: // types | ||
|  |     typedef T element_type; | ||
|  |      | ||
|  |  public: // member functions | ||
|  |     handle(); | ||
|  |     ~handle(); | ||
|  | 
 | ||
|  |     template <class Y> | ||
|  |     explicit handle(Y* p) | ||
|  |         : m_p( | ||
|  |             python::upcast<T>( | ||
|  |                 detail::manage_ptr(p, 0) | ||
|  |                 ) | ||
|  |             ) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     handle& operator=(handle const& r) | ||
|  |     { | ||
|  |         python::xdecref(m_p); | ||
|  |         m_p = python::xincref(r.m_p); | ||
|  |         return *this; | ||
|  |     } | ||
|  | 
 | ||
|  |     template<typename Y> | ||
|  |     handle& operator=(handle<Y> const & r) // never throws | ||
|  |     { | ||
|  |         python::xdecref(m_p); | ||
|  |         m_p = python::xincref(python::upcast<T>(r.get())); | ||
|  |         return *this; | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename Y> | ||
|  |     handle(handle<Y> const& r) | ||
|  |         : m_p(python::xincref(python::upcast<T>(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<T>::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<T>((PyObject*)x) | ||
|  |                 )) | ||
|  |     { | ||
|  |     } | ||
|  |      | ||
|  |  private: // data members | ||
|  |     T* m_p; | ||
|  | }; | ||
|  | 
 | ||
|  | #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP | ||
|  | } // namespace python | ||
|  | #endif | ||
|  | 
 | ||
|  | template<class T> inline T * get_pointer(python::handle<T> 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<PyTypeObject> type_handle; | ||
|  | 
 | ||
|  | // | ||
|  | // Compile-time introspection | ||
|  | // | ||
|  | template<typename T> | ||
|  | class is_handle | ||
|  | { | ||
|  |  public: | ||
|  |     BOOST_STATIC_CONSTANT(bool, value = false);  | ||
|  | }; | ||
|  | 
 | ||
|  | template<typename T> | ||
|  | class is_handle<handle<T> > | ||
|  | { | ||
|  |  public: | ||
|  |     BOOST_STATIC_CONSTANT(bool, value = true); | ||
|  | }; | ||
|  | 
 | ||
|  | // | ||
|  | // implementations | ||
|  | // | ||
|  | template <class T> | ||
|  | inline handle<T>::handle() | ||
|  |     : m_p(0) | ||
|  | { | ||
|  | } | ||
|  | 
 | ||
|  | template <class T> | ||
|  | inline handle<T>::~handle() | ||
|  | { | ||
|  |     python::xdecref(m_p); | ||
|  | } | ||
|  | 
 | ||
|  | template <class T> | ||
|  | inline T* handle<T>::operator->() const | ||
|  | { | ||
|  |     return m_p; | ||
|  | } | ||
|  | 
 | ||
|  | template <class T> | ||
|  | inline T& handle<T>::operator*() const | ||
|  | { | ||
|  |     return *m_p; | ||
|  | } | ||
|  | 
 | ||
|  | template <class T> | ||
|  | inline T* handle<T>::get() const | ||
|  | { | ||
|  |     return m_p; | ||
|  | } | ||
|  |      | ||
|  | template <class T> | ||
|  | inline bool handle<T>::operator!() const | ||
|  | { | ||
|  |     return m_p == 0; | ||
|  | } | ||
|  | 
 | ||
|  | template <class T> | ||
|  | inline T* handle<T>::release() | ||
|  | { | ||
|  |     T* result = m_p; | ||
|  |     m_p = 0; | ||
|  |     return result; | ||
|  | } | ||
|  | 
 | ||
|  | template <class T> | ||
|  | inline void handle<T>::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 <class T> | ||
|  | inline PyObject* get_managed_object(handle<T> const& h, tag_t) | ||
|  | { | ||
|  |     return h.get() ? python::upcast<PyObject>(h.get()) : Py_None; | ||
|  | } | ||
|  | 
 | ||
|  | }} // namespace boost::python | ||
|  | 
 | ||
|  | 
 | ||
|  | #endif // HANDLE_DWA200269_HPP |