Skip to content

Commit 7926e1b

Browse files
committed
Fixes for reference parameters to constructors
[SVN r12364]
1 parent b796db6 commit 7926e1b

5 files changed

Lines changed: 328 additions & 92 deletions

File tree

‎include/boost/python/detail/extension_class.hpp‎

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
1+
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
22
// distribute this software is granted provided this copyright notice appears
33
// in all copies. This software is provided "as is" without express or implied
44
// warranty, and with no claim as to its suitability for any purpose.
@@ -727,25 +727,80 @@ class held_instance : public Held
727727
public:
728728
held_instance(PyObject*) : Held() {}
729729
template <class A1>
730-
held_instance(PyObject*, A1 a1) : Held(a1) {}
730+
held_instance(PyObject*, A1 a1) : Held(
731+
typename unwrap_parameter<A1>::type(a1)) {}
731732
template <class A1, class A2>
732-
held_instance(PyObject*, A1 a1, A2 a2) : Held(a1, a2) {}
733+
held_instance(PyObject*, A1 a1, A2 a2) : Held(
734+
typename unwrap_parameter<A1>::type(a1)
735+
, typename unwrap_parameter<A2>::type(a2)) {}
733736
template <class A1, class A2, class A3>
734-
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(a1, a2, a3) {}
737+
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(
738+
typename unwrap_parameter<A1>::type(a1)
739+
, typename unwrap_parameter<A2>::type(a2)
740+
, typename unwrap_parameter<A3>::type(a3)) {}
735741
template <class A1, class A2, class A3, class A4>
736-
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(a1, a2, a3, a4) {}
742+
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(
743+
typename unwrap_parameter<A1>::type(a1)
744+
, typename unwrap_parameter<A2>::type(a2)
745+
, typename unwrap_parameter<A3>::type(a3)
746+
, typename unwrap_parameter<A4>::type(a4)) {}
737747
template <class A1, class A2, class A3, class A4, class A5>
738-
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(a1, a2, a3, a4, a5) {}
748+
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(
749+
typename unwrap_parameter<A1>::type(a1)
750+
, typename unwrap_parameter<A2>::type(a2)
751+
, typename unwrap_parameter<A3>::type(a3)
752+
, typename unwrap_parameter<A4>::type(a4)
753+
, typename unwrap_parameter<A5>::type(a5)) {}
739754
template <class A1, class A2, class A3, class A4, class A5, class A6>
740-
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(a1, a2, a3, a4, a5, a6) {}
755+
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(
756+
typename unwrap_parameter<A1>::type(a1)
757+
, typename unwrap_parameter<A2>::type(a2)
758+
, typename unwrap_parameter<A3>::type(a3)
759+
, typename unwrap_parameter<A4>::type(a4)
760+
, typename unwrap_parameter<A5>::type(a5)
761+
, typename unwrap_parameter<A6>::type(a6)) {}
741762
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
742-
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(a1, a2, a3, a4, a5, a6, a7) {}
763+
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(
764+
typename unwrap_parameter<A1>::type(a1)
765+
, typename unwrap_parameter<A2>::type(a2)
766+
, typename unwrap_parameter<A3>::type(a3)
767+
, typename unwrap_parameter<A4>::type(a4)
768+
, typename unwrap_parameter<A5>::type(a5)
769+
, typename unwrap_parameter<A6>::type(a6)
770+
, typename unwrap_parameter<A7>::type(a7)) {}
743771
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
744-
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(a1, a2, a3, a4, a5, a6, a7, a8) {}
772+
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(
773+
typename unwrap_parameter<A1>::type(a1)
774+
, typename unwrap_parameter<A2>::type(a2)
775+
, typename unwrap_parameter<A3>::type(a3)
776+
, typename unwrap_parameter<A4>::type(a4)
777+
, typename unwrap_parameter<A5>::type(a5)
778+
, typename unwrap_parameter<A6>::type(a6)
779+
, typename unwrap_parameter<A7>::type(a7)
780+
, typename unwrap_parameter<A8>::type(a8)) {}
745781
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
746-
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
782+
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(
783+
typename unwrap_parameter<A1>::type(a1)
784+
, typename unwrap_parameter<A2>::type(a2)
785+
, typename unwrap_parameter<A3>::type(a3)
786+
, typename unwrap_parameter<A4>::type(a4)
787+
, typename unwrap_parameter<A5>::type(a5)
788+
, typename unwrap_parameter<A6>::type(a6)
789+
, typename unwrap_parameter<A7>::type(a7)
790+
, typename unwrap_parameter<A8>::type(a8)
791+
, typename unwrap_parameter<A9>::type(a9)) {}
747792
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
748-
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
793+
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(
794+
typename unwrap_parameter<A1>::type(a1)
795+
, typename unwrap_parameter<A2>::type(a2)
796+
, typename unwrap_parameter<A3>::type(a3)
797+
, typename unwrap_parameter<A4>::type(a4)
798+
, typename unwrap_parameter<A5>::type(a5)
799+
, typename unwrap_parameter<A6>::type(a6)
800+
, typename unwrap_parameter<A7>::type(a7)
801+
, typename unwrap_parameter<A8>::type(a8)
802+
, typename unwrap_parameter<A9>::type(a9)
803+
, typename unwrap_parameter<A10>::type(a10)) {}
749804
};
750805

751806
// Abstract base class for all obj holders. Base for template class

‎include/boost/python/detail/init_function.hpp‎

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
1+
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
22
// distribute this software is granted provided this copyright notice appears
33
// in all copies. This software is provided "as is" without express or implied
44
// warranty, and with no claim as to its suitability for any purpose.
@@ -89,18 +89,66 @@ namespace detail {
8989
typedef void const_reference;
9090
};
9191

92+
struct reference_parameter_base {};
93+
9294
template <class T>
9395
class reference_parameter
96+
: public reference_parameter_base
9497
{
95-
typedef typename parameter_traits<T>::const_reference const_reference;
9698
public:
99+
typedef typename parameter_traits<T>::const_reference const_reference;
97100
reference_parameter(const_reference value)
98101
: value(value) {}
99102
operator const_reference() { return value; }
100103
private:
101104
const_reference value;
102105
};
103106

107+
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
108+
template <class T>
109+
struct unwrap_parameter
110+
{
111+
typedef typename boost::add_reference<T>::type type;
112+
};
113+
114+
template <class T>
115+
struct unwrap_parameter<reference_parameter<T> >
116+
{
117+
typedef typename reference_parameter<T>::const_reference type;
118+
};
119+
# else
120+
template <bool is_wrapped>
121+
struct unwrap_parameter_helper
122+
{
123+
template <class T>
124+
struct apply
125+
{
126+
typedef typename T::const_reference type;
127+
};
128+
};
129+
130+
template <>
131+
struct unwrap_parameter_helper<false>
132+
{
133+
template <class T>
134+
struct apply
135+
{
136+
typedef typename add_reference<T>::type type;
137+
};
138+
};
139+
140+
template <class T>
141+
struct unwrap_parameter
142+
{
143+
BOOST_STATIC_CONSTANT(
144+
bool, is_wrapped = (is_base_and_derived<T,reference_parameter_base>::value));
145+
146+
typedef typename unwrap_parameter_helper<
147+
is_wrapped
148+
>::template apply<T>::type type;
149+
};
150+
# endif
151+
104152
class extension_instance;
105153
class instance_holder_base;
106154

‎include/boost/python/reference.hpp‎

Lines changed: 82 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,10 @@ class reference
5959
reference(const reference& rhs)
6060
: m_p(rhs.m_p)
6161
{
62-
Py_XINCREF(object());
62+
assert(m_p == 0 || m_p->ob_refcnt > 0);
63+
Py_XINCREF(m_p);
6364
}
6465

65-
#if !defined(BOOST_MSVC6_OR_EARLIER)
66-
template <class T2>
67-
reference(const reference<T2>& rhs)
68-
: m_p(rhs.object())
69-
{
70-
Py_XINCREF(object());
71-
}
72-
#endif
73-
7466
reference() : m_p(0) {}
7567

7668
// These are two ways of spelling the same thing, that we need to increment
@@ -81,85 +73,140 @@ class reference
8173

8274
template <class T2>
8375
explicit reference(T2* x)
84-
: m_p(expect_non_null(x)) {}
76+
: m_p(expect_non_null(x))
77+
{
78+
assert(m_p->ob_refcnt > 0);
79+
}
8580

8681
template <class T2>
8782
reference(T2* x, increment_count_t)
88-
: m_p(expect_non_null(x)) { Py_INCREF(object()); }
83+
: m_p(expect_non_null(x))
84+
{
85+
assert(m_p->ob_refcnt > 0);
86+
Py_INCREF(m_p);
87+
}
8988

9089
template <class T2>
9190
reference(T2* x, allow_null)
92-
: m_p(x) {}
91+
: m_p(x)
92+
{
93+
assert(m_p == 0 || m_p->ob_refcnt > 0);
94+
}
9395

9496
template <class T2>
9597
reference(T2* x, allow_null, increment_count_t)
96-
: m_p(x) { Py_XINCREF(object()); }
98+
: m_p(x)
99+
{
100+
assert(m_p == 0 || m_p->ob_refcnt > 0);
101+
Py_XINCREF(m_p);
102+
}
97103

98104
template <class T2>
99105
reference(T2* x, increment_count_t, allow_null)
100-
: m_p(x) { Py_XINCREF(object()); }
101-
102-
#if !defined(BOOST_MSVC6_OR_EARLIER)
103-
template <class T2>
104-
reference& operator=(const reference<T2>& rhs)
106+
: m_p(x)
105107
{
106-
Py_XDECREF(object());
107-
m_p = rhs.m_p;
108-
Py_XINCREF(object());
109-
return *this;
108+
assert(m_p == 0 || m_p->ob_refcnt > 0);
109+
Py_XINCREF(m_p);
110110
}
111-
#endif
112-
111+
113112
reference& operator=(const reference& rhs)
114113
{
114+
assert(rhs.m_p == 0 || rhs.m_p->ob_refcnt > 0);
115115
Py_XINCREF(static_cast<PyObject*>(rhs.m_p));
116-
Py_XDECREF(object());
116+
assert(m_p == 0 || m_p->ob_refcnt > 0);
117+
Py_XDECREF(m_p);
117118
m_p = rhs.m_p;
118119
return *this;
119120
}
120121

121122
~reference()
122123
{
124+
assert(m_p == 0 || m_p->ob_refcnt > 0);
123125
Py_XDECREF(m_p);
124126
}
125127

126-
T& operator*() const { return *m_p; }
128+
T& operator*() const
129+
{
130+
assert(m_p == 0 || m_p->ob_refcnt > 0);
131+
return *m_p;
132+
}
127133

128134
// MSVC doesn't like boost::dereferencable unless T has a default
129135
// constructor, so operator-> must be defined by hand :(
130-
T* operator->() const { return &**this; }
136+
T* operator->() const
137+
{
138+
assert(m_p == 0 || m_p->ob_refcnt > 0);
139+
return &**this;
140+
}
131141

132-
T* get() const { return m_p; }
142+
T* get() const
143+
{
144+
assert(m_p == 0 || m_p->ob_refcnt > 0);
145+
return m_p;
146+
}
133147

134148
T* release()
135149
{
150+
assert(m_p == 0 || m_p->ob_refcnt > 0);
136151
T* p = m_p;
137152
m_p = 0;
138153
return p;
139154
}
140155

141156
void reset()
142-
{ Py_XDECREF(m_p); m_p = 0; }
157+
{
158+
assert(m_p == 0 || m_p->ob_refcnt > 0);
159+
Py_XDECREF(m_p);
160+
m_p = 0;
161+
}
143162

144163
template <class T2>
145164
void reset(T2* x)
146-
{ Py_XDECREF(m_p); m_p = expect_non_null(x);}
165+
{
166+
assert(m_p == 0 || m_p->ob_refcnt > 0);
167+
Py_XDECREF(m_p);
168+
m_p = expect_non_null(x);
169+
assert(m_p == 0 || m_p->ob_refcnt > 0);
170+
}
147171

148172
template <class T2>
149173
void reset(T2* x, increment_count_t)
150-
{ Py_XDECREF(m_p); m_p = expect_non_null(x); Py_INCREF(object()); }
174+
{
175+
assert(m_p == 0 || m_p->ob_refcnt > 0);
176+
Py_XDECREF(m_p);
177+
m_p = expect_non_null(x);
178+
assert(m_p->ob_refcnt > 0);
179+
Py_INCREF(m_p);
180+
}
151181

152182
template <class T2>
153183
void reset(T2* x, allow_null)
154-
{ Py_XDECREF(m_p); m_p = x;}
184+
{
185+
assert(m_p == 0 || m_p->ob_refcnt > 0);
186+
Py_XDECREF(m_p);
187+
m_p = x;
188+
assert(m_p == 0 || m_p->ob_refcnt > 0);
189+
}
155190

156191
template <class T2>
157192
void reset(T2* x, allow_null, increment_count_t)
158-
{ Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); }
193+
{
194+
assert(m_p == 0 || m_p->ob_refcnt > 0);
195+
Py_XDECREF(m_p);
196+
m_p = x;
197+
assert(m_p == 0 || m_p->ob_refcnt > 0);
198+
Py_XINCREF(m_p);
199+
}
159200

160201
template <class T2>
161202
void reset(T2* x, increment_count_t, allow_null)
162-
{ Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); }
203+
{
204+
assert(m_p == 0 || m_p->ob_refcnt > 0);
205+
Py_XDECREF(m_p);
206+
m_p = x;
207+
assert(m_p == 0 || m_p->ob_refcnt > 0);
208+
Py_XINCREF(m_p);
209+
}
163210

164211
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
165212
private:

0 commit comments

Comments
 (0)