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
 |