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 HANDLE_DWA200269_HPP
6 # define HANDLE_DWA200269_HPP
8 # include <boost/python/detail/prefix.hpp>
10 # include <boost/python/cast.hpp>
11 # include <boost/python/errors.hpp>
12 # include <boost/python/borrowed.hpp>
13 # include <boost/python/handle_fwd.hpp>
14 # include <boost/python/refcount.hpp>
15 # include <boost/python/tag.hpp>
16 # include <boost/python/detail/raw_pyobject.hpp>
18 namespace boost
{ namespace python
{
20 template <class T
> struct null_ok
;
23 inline null_ok
<T
>* allow_null(T
* p
)
25 return (null_ok
<T
>*)p
;
31 inline T
* manage_ptr(detail::borrowed
<null_ok
<T
> >* p
, int)
33 return python::xincref((T
*)p
);
37 inline T
* manage_ptr(null_ok
<detail::borrowed
<T
> >* p
, int)
39 return python::xincref((T
*)p
);
43 inline T
* manage_ptr(detail::borrowed
<T
>* p
, long)
45 return python::incref(expect_non_null((T
*)p
));
49 inline T
* manage_ptr(null_ok
<T
>* p
, long)
55 inline T
* manage_ptr(T
* p
, ...)
57 return expect_non_null(p
);
64 typedef T
* (handle::* bool_type
)() const;
67 typedef T element_type
;
69 public: // member functions
77 detail::manage_ptr(p
, 0)
83 handle
& operator=(handle
const& r
)
86 m_p
= python::xincref(r
.m_p
);
90 #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
93 handle
& operator=(handle
<Y
> const & r
) // never throws
96 m_p
= python::xincref(python::upcast
<T
>(r
.get()));
102 template <typename Y
>
103 handle(handle
<Y
> const& r
)
104 : m_p(python::xincref(python::upcast
<T
>(r
.get())))
108 handle(handle
const& r
)
109 : m_p(python::xincref(r
.m_p
))
113 T
* operator-> () const;
114 T
& operator* () const;
119 operator bool_type() const // never throws
121 return m_p
? &handle
<T
>::get
: 0;
123 bool operator! () const; // never throws
125 public: // implementation details -- do not touch
126 // Defining this in the class body suppresses a VC7 link failure
127 inline handle(detail::borrowed_reference x
)
130 downcast
<T
>((PyObject
*)x
)
135 private: // data members
139 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
140 } // namespace python
143 template<class T
> inline T
* get_pointer(python::handle
<T
> const & p
)
148 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
152 // We don't want get_pointer above to hide the others
153 using boost::get_pointer
;
157 typedef handle
<PyTypeObject
> type_handle
;
160 // Compile-time introspection
162 # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
167 BOOST_STATIC_CONSTANT(bool, value
= false);
171 class is_handle
<handle
<T
> >
174 BOOST_STATIC_CONSTANT(bool, value
= true);
179 typedef char (&yes_handle_t
)[1];
180 typedef char (&no_handle_t
)[2];
182 no_handle_t
is_handle_test(...);
185 yes_handle_t
is_handle_test(boost::type
< handle
<T
> >);
192 BOOST_STATIC_CONSTANT(
194 sizeof(detail::is_handle_test(boost::type
<T
>()))
195 == sizeof(detail::yes_handle_t
)));
203 inline handle
<T
>::handle()
209 inline handle
<T
>::~handle()
211 python::xdecref(m_p
);
215 inline T
* handle
<T
>::operator->() const
221 inline T
& handle
<T
>::operator*() const
227 inline T
* handle
<T
>::get() const
233 inline bool handle
<T
>::operator!() const
239 inline T
* handle
<T
>::release()
247 inline void handle
<T
>::reset()
249 python::xdecref(m_p
);
253 // Because get_managed_object must return a non-null PyObject*, we
254 // return Py_None if the handle is null.
256 inline PyObject
* get_managed_object(handle
<T
> const& h
, tag_t
)
258 return h
.get() ? python::upcast
<PyObject
>(h
.get()) : Py_None
;
261 }} // namespace boost::python
264 #endif // HANDLE_DWA200269_HPP