1 // Copyright David Abrahams 2004. Distributed under the Boost
2 // Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4 #ifndef WRAPPER_BASE_DWA2004722_HPP
5 # define WRAPPER_BASE_DWA2004722_HPP
6 
7 # include <boost/python/detail/prefix.hpp>
8 # include <boost/python/detail/type_traits.hpp>
9 
10 namespace boost { namespace python {
11 
12 class override;
13 
14 namespace detail
15 {
16   class wrapper_base;
17 
18   namespace wrapper_base_ // ADL disabler
19   {
20     inline PyObject* get_owner(wrapper_base const volatile& w);
21 
22     inline PyObject*
owner_impl(void const volatile *,detail::false_)23     owner_impl(void const volatile* /*x*/, detail::false_)
24     {
25         return 0;
26     }
27 
28     template <class T>
29     inline PyObject*
30     owner_impl(T const volatile* x, detail::true_);
31 
32     template <class T>
33     inline PyObject*
owner(T const volatile * x)34     owner(T const volatile* x)
35     {
36         return wrapper_base_::owner_impl(x,is_polymorphic<T>());
37     }
38   }
39 
40   class BOOST_PYTHON_DECL wrapper_base
41   {
42       friend void initialize_wrapper(PyObject* self, wrapper_base* w);
43       friend PyObject* wrapper_base_::get_owner(wrapper_base const volatile& w);
44    protected:
wrapper_base()45       wrapper_base() : m_self(0) {}
46 
47       override get_override(
48           char const* name, PyTypeObject* class_object) const;
49 
50    private:
51       void detach();
52 
53    private:
54       PyObject* m_self;
55   };
56 
57   namespace wrapper_base_ // ADL disabler
58   {
59     template <class T>
60     inline PyObject*
owner_impl(T const volatile * x,detail::true_)61     owner_impl(T const volatile* x, detail::true_)
62     {
63         if (wrapper_base const volatile* w = dynamic_cast<wrapper_base const volatile*>(x))
64         {
65             return wrapper_base_::get_owner(*w);
66         }
67         return 0;
68     }
69 
get_owner(wrapper_base const volatile & w)70     inline PyObject* get_owner(wrapper_base const volatile& w)
71     {
72         return w.m_self;
73     }
74   }
75 
initialize_wrapper(PyObject * self,wrapper_base * w)76   inline void initialize_wrapper(PyObject* self, wrapper_base* w)
77   {
78       w->m_self = self;
79   }
80 
initialize_wrapper(PyObject *,...)81   inline void initialize_wrapper(PyObject* /*self*/, ...) {}
82 
83 
84 
85 } // namespace detail
86 
87 }} // namespace boost::python
88 
89 #endif // WRAPPER_BASE_DWA2004722_HPP
90