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/type_traits/is_polymorphic.hpp>
9 # include <boost/mpl/bool.hpp>
10 
11 namespace boost { namespace python {
12 
13 class override;
14 
15 namespace detail
16 {
17   class BOOST_PYTHON_DECL_FORWARD wrapper_base;
18 
19   namespace wrapper_base_ // ADL disabler
20   {
21     inline PyObject* get_owner(wrapper_base const volatile& w);
22 
23     inline PyObject*
owner_impl(void const volatile *,mpl::false_)24     owner_impl(void const volatile* /*x*/, mpl::false_)
25     {
26         return 0;
27     }
28 
29     template <class T>
30     inline PyObject*
31     owner_impl(T const volatile* x, mpl::true_);
32 
33     template <class T>
34     inline PyObject*
owner(T const volatile * x)35     owner(T const volatile* x)
36     {
37         return wrapper_base_::owner_impl(x,is_polymorphic<T>());
38     }
39   }
40 
41   class BOOST_PYTHON_DECL wrapper_base
42   {
43       friend void initialize_wrapper(PyObject* self, wrapper_base* w);
44       friend PyObject* wrapper_base_::get_owner(wrapper_base const volatile& w);
45    protected:
wrapper_base()46       wrapper_base() : m_self(0) {}
47 
48       override get_override(
49           char const* name, PyTypeObject* class_object) const;
50 
51    private:
52       void detach();
53 
54    private:
55       PyObject* m_self;
56   };
57 
58   namespace wrapper_base_ // ADL disabler
59   {
60     template <class T>
61     inline PyObject*
owner_impl(T const volatile * x,mpl::true_)62     owner_impl(T const volatile* x, mpl::true_)
63     {
64         if (wrapper_base const volatile* w = dynamic_cast<wrapper_base const volatile*>(x))
65         {
66             return wrapper_base_::get_owner(*w);
67         }
68         return 0;
69     }
70 
get_owner(wrapper_base const volatile & w)71     inline PyObject* get_owner(wrapper_base const volatile& w)
72     {
73         return w.m_self;
74     }
75   }
76 
initialize_wrapper(PyObject * self,wrapper_base * w)77   inline void initialize_wrapper(PyObject* self, wrapper_base* w)
78   {
79       w->m_self = self;
80   }
81 
initialize_wrapper(PyObject *,...)82   inline void initialize_wrapper(PyObject* /*self*/, ...) {}
83 
84 
85 
86 } // namespace detail
87 
88 }} // namespace boost::python
89 
90 #endif // WRAPPER_BASE_DWA2004722_HPP
91