source: NonGTP/Boost/boost/python/object/pointer_holder.hpp @ 857

Revision 857, 6.1 KB checked in by igarcia, 19 years ago (diff)
Line 
1#if !defined(BOOST_PP_IS_ITERATING)
2
3// Copyright David Abrahams 2001.
4// Distributed under the Boost Software License, Version 1.0. (See
5// accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7
8# ifndef POINTER_HOLDER_DWA20011215_HPP
9#  define POINTER_HOLDER_DWA20011215_HPP
10
11# include <boost/get_pointer.hpp>
12#  include <boost/type.hpp>
13
14#  include <boost/python/instance_holder.hpp>
15#  include <boost/python/object/inheritance_query.hpp>
16#  include <boost/python/object/forward.hpp>
17
18#  include <boost/python/pointee.hpp>
19#  include <boost/python/type_id.hpp>
20
21#  include <boost/python/detail/wrapper_base.hpp>
22#  include <boost/python/detail/force_instantiate.hpp>
23#  include <boost/python/detail/preprocessor.hpp>
24
25
26#  include <boost/mpl/if.hpp>
27#  include <boost/mpl/apply.hpp>
28
29#  include <boost/preprocessor/comma_if.hpp>
30#  include <boost/preprocessor/iterate.hpp>
31#  include <boost/preprocessor/repeat.hpp>
32#  include <boost/preprocessor/debug/line.hpp>
33#  include <boost/preprocessor/enum_params.hpp>
34#  include <boost/preprocessor/repetition/enum_binary_params.hpp>
35
36#  include <boost/detail/workaround.hpp>
37
38namespace boost { namespace python {
39
40template <class T> class wrapper;
41
42}}
43
44
45namespace boost { namespace python { namespace objects {
46
47#  if BOOST_WORKAROUND(__GNUC__, == 2)
48#   define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward<A##n>::type)objects::do_unforward(a##n,0)
49#  else
50#   define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)
51#  endif
52
53template <class Pointer, class Value>
54struct pointer_holder : instance_holder
55{
56    typedef Value value_type;
57   
58    pointer_holder(Pointer);
59
60    // Forward construction to the held object
61
62#  define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/object/pointer_holder.hpp>, 1))
63#  include BOOST_PP_ITERATE()
64
65 private: // types
66   
67 private: // required holder implementation
68    void* holds(type_info, bool null_ptr_only);
69   
70    template <class T>
71    inline void* holds_wrapped(type_info dst_t, wrapper<T>*,T* p)
72    {
73        return python::type_id<T>() == dst_t ? p : 0;
74    }
75   
76    inline void* holds_wrapped(type_info, ...)
77    {
78        return 0;
79    }
80
81 private: // data members
82    Pointer m_p;
83};
84
85template <class Pointer, class Value>
86struct pointer_holder_back_reference : instance_holder
87{
88 private:
89    typedef typename python::pointee<Pointer>::type held_type;
90 public:
91    typedef Value value_type;
92
93    // Not sure about this one -- can it work? The source object
94    // undoubtedly does not carry the correct back reference pointer.
95    pointer_holder_back_reference(Pointer);
96
97    // Forward construction to the held object
98#  define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/object/pointer_holder.hpp>, 2))
99#  include BOOST_PP_ITERATE()
100
101 private: // required holder implementation
102    void* holds(type_info, bool null_ptr_only);
103
104 private: // data members
105    Pointer m_p;
106};
107
108#  undef BOOST_PYTHON_UNFORWARD_LOCAL
109
110template <class Pointer, class Value>
111inline pointer_holder<Pointer,Value>::pointer_holder(Pointer p)
112    : m_p(p)
113{
114}
115
116template <class Pointer, class Value>
117inline pointer_holder_back_reference<Pointer,Value>::pointer_holder_back_reference(Pointer p)
118    : m_p(p)
119{
120}
121
122template <class Pointer, class Value>
123void* pointer_holder<Pointer, Value>::holds(type_info dst_t, bool null_ptr_only)
124{
125    if (dst_t == python::type_id<Pointer>()
126        && !(null_ptr_only && get_pointer(this->m_p))
127    )
128        return &this->m_p;
129
130    Value* p = get_pointer(this->m_p);
131    if (p == 0)
132        return 0;
133   
134    if (void* wrapped = holds_wrapped(dst_t, p, p))
135        return wrapped;
136   
137    type_info src_t = python::type_id<Value>();
138    return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t);
139}
140
141template <class Pointer, class Value>
142void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t, bool null_ptr_only)
143{
144    if (dst_t == python::type_id<Pointer>()
145        && !(null_ptr_only && get_pointer(this->m_p))
146    )
147        return &this->m_p;
148
149    if (!get_pointer(this->m_p))
150        return 0;
151   
152    Value* p = get_pointer(m_p);
153   
154    if (dst_t == python::type_id<held_type>())
155        return p;
156
157    type_info src_t = python::type_id<Value>();
158    return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t);
159}
160
161}}} // namespace boost::python::objects
162
163# endif // POINTER_HOLDER_DWA20011215_HPP
164
165/* --------------- pointer_holder --------------- */
166#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
167# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100)                      \
168        && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
169#  line BOOST_PP_LINE(__LINE__, pointer_holder.hpp)
170# endif
171
172# define N BOOST_PP_ITERATION()
173
174# if (N != 0)
175    template< BOOST_PP_ENUM_PARAMS_Z(1, N, class A) >
176# endif
177    pointer_holder(PyObject* self BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a))
178        : m_p(new Value(
179                BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil)
180            ))
181    {
182        python::detail::initialize_wrapper(self, &*this->m_p);
183    }
184
185# undef N
186
187/* --------------- pointer_holder_back_reference --------------- */
188#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2
189# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100)                      \
190        && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
191#  line BOOST_PP_LINE(__LINE__, pointer_holder.hpp(pointer_holder_back_reference))
192# endif
193
194# define N BOOST_PP_ITERATION()
195
196# if (N != 0)
197    template < BOOST_PP_ENUM_PARAMS_Z(1, N, class A) >
198# endif
199    pointer_holder_back_reference(
200        PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a))
201        : m_p(new held_type(
202                    p BOOST_PP_COMMA_IF(N) BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil)
203            ))
204    {}
205
206# undef N
207
208#endif
Note: See TracBrowser for help on using the repository browser.