Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:40

0001 // Copyright David Abrahams 2002.
0002 // Distributed under the Boost Software License, Version 1.0. (See
0003 // accompanying file LICENSE_1_0.txt or copy at
0004 // http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef HANDLE_DWA200269_HPP
0006 # define HANDLE_DWA200269_HPP
0007 
0008 # include <boost/python/detail/prefix.hpp>
0009 
0010 # include <boost/python/cast.hpp>
0011 # include <boost/python/errors.hpp>
0012 # include <boost/python/borrowed.hpp>
0013 # include <boost/python/handle_fwd.hpp>
0014 # include <boost/python/refcount.hpp>
0015 # include <boost/python/tag.hpp>
0016 # include <boost/python/detail/raw_pyobject.hpp>
0017 
0018 namespace boost { namespace python { 
0019 
0020 template <class T> struct null_ok;
0021 
0022 template <class T>
0023 inline null_ok<T>* allow_null(T* p)
0024 {
0025     return (null_ok<T>*)p;
0026 }
0027 
0028 namespace detail
0029 {
0030   template <class T>
0031   inline T* manage_ptr(detail::borrowed<null_ok<T> >* p, int)
0032   {
0033       return python::xincref((T*)p);
0034   }
0035   
0036   template <class T>
0037   inline T* manage_ptr(null_ok<detail::borrowed<T> >* p, int)
0038   {
0039       return python::xincref((T*)p);
0040   }
0041   
0042   template <class T>
0043   inline T* manage_ptr(detail::borrowed<T>* p, long)
0044   {
0045       return python::incref(expect_non_null((T*)p));
0046   }
0047   
0048   template <class T>
0049   inline T* manage_ptr(null_ok<T>* p, long)
0050   {
0051       return (T*)p;
0052   }
0053   
0054   template <class T>
0055   inline T* manage_ptr(T* p, ...)
0056   {
0057       return expect_non_null(p);
0058   }
0059 }
0060 
0061 template <class T>
0062 class handle
0063 {
0064     typedef T* (handle::* bool_type )() const;
0065 
0066  public: // types
0067     typedef T element_type;
0068     
0069  public: // member functions
0070     handle();
0071     ~handle();
0072 
0073     template <class Y>
0074     explicit handle(Y* p)
0075         : m_p(
0076             python::upcast<T>(
0077                 detail::manage_ptr(p, 0)
0078                 )
0079             )
0080     {
0081     }
0082 
0083     handle& operator=(handle const& r)
0084     {
0085         python::xdecref(m_p);
0086         m_p = python::xincref(r.m_p);
0087         return *this;
0088     }
0089 
0090     template<typename Y>
0091     handle& operator=(handle<Y> const & r) // never throws
0092     {
0093         python::xdecref(m_p);
0094         m_p = python::xincref(python::upcast<T>(r.get()));
0095         return *this;
0096     }
0097 
0098     template <typename Y>
0099     handle(handle<Y> const& r)
0100         : m_p(python::xincref(python::upcast<T>(r.get())))
0101     {
0102     }
0103     
0104     handle(handle const& r)
0105         : m_p(python::xincref(r.m_p))
0106     {
0107     }
0108     
0109     T* operator-> () const;
0110     T& operator* () const;
0111     T* get() const;
0112     T* release();
0113     void reset();
0114     
0115     operator bool_type() const // never throws
0116     {
0117         return m_p ? &handle<T>::get : 0;
0118     }
0119     bool operator! () const; // never throws
0120 
0121  public: // implementation details -- do not touch
0122     // Defining this in the class body suppresses a VC7 link failure
0123     inline handle(detail::borrowed_reference x)
0124         : m_p(
0125             python::incref(
0126                 downcast<T>((PyObject*)x)
0127                 ))
0128     {
0129     }
0130     
0131  private: // data members
0132     T* m_p;
0133 };
0134 
0135 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
0136 } // namespace python
0137 #endif
0138 
0139 template<class T> inline T * get_pointer(python::handle<T> const & p)
0140 {
0141     return p.get();
0142 }
0143 
0144 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
0145 namespace python {
0146 #else
0147 
0148 // We don't want get_pointer above to hide the others
0149 using boost::get_pointer;
0150 
0151 #endif
0152 
0153 typedef handle<PyTypeObject> type_handle;
0154 
0155 //
0156 // Compile-time introspection
0157 //
0158 template<typename T>
0159 class is_handle
0160 {
0161  public:
0162     BOOST_STATIC_CONSTANT(bool, value = false); 
0163 };
0164 
0165 template<typename T>
0166 class is_handle<handle<T> >
0167 {
0168  public:
0169     BOOST_STATIC_CONSTANT(bool, value = true);
0170 };
0171 
0172 //
0173 // implementations
0174 //
0175 template <class T>
0176 inline handle<T>::handle()
0177     : m_p(0)
0178 {
0179 }
0180 
0181 template <class T>
0182 inline handle<T>::~handle()
0183 {
0184     python::xdecref(m_p);
0185 }
0186 
0187 template <class T>
0188 inline T* handle<T>::operator->() const
0189 {
0190     return m_p;
0191 }
0192 
0193 template <class T>
0194 inline T& handle<T>::operator*() const
0195 {
0196     return *m_p;
0197 }
0198 
0199 template <class T>
0200 inline T* handle<T>::get() const
0201 {
0202     return m_p;
0203 }
0204     
0205 template <class T>
0206 inline bool handle<T>::operator!() const
0207 {
0208     return m_p == 0;
0209 }
0210 
0211 template <class T>
0212 inline T* handle<T>::release()
0213 {
0214     T* result = m_p;
0215     m_p = 0;
0216     return result;
0217 }
0218 
0219 template <class T>
0220 inline void handle<T>::reset()
0221 {
0222     python::xdecref(m_p);
0223     m_p = 0;
0224 }
0225 
0226 // Because get_managed_object must return a non-null PyObject*, we
0227 // return Py_None if the handle is null.
0228 template <class T>
0229 inline PyObject* get_managed_object(handle<T> const& h, tag_t)
0230 {
0231     return h.get() ? python::upcast<PyObject>(h.get()) : Py_None;
0232 }
0233 
0234 }} // namespace boost::python
0235 
0236 
0237 #endif // HANDLE_DWA200269_HPP