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
							 |