Skip to content

Commit 8112478

Browse files
committed
Support for constructor policies
[SVN r13350]
1 parent aed7e14 commit 8112478

6 files changed

Lines changed: 141 additions & 0 deletions

File tree

include/boost/python/class.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,19 @@ class class_ : public objects::class_base
132132
return *this;
133133
}
134134

135+
template <class Args, class CallPolicy>
136+
self& def_init(Args const&, CallPolicy policy)
137+
{
138+
def("__init__",
139+
make_constructor<Args>(
140+
policy
141+
// Using runtime type selection works around a CWPro7 bug.
142+
, objects::select_holder<T,held_type>((held_type*)0).get()
143+
)
144+
);
145+
return *this;
146+
}
147+
135148
// Define the default constructor.
136149
self& def_init()
137150
{

include/boost/python/detail/indirect_traits.hpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# define INDIRECT_TRAITS_DWA2002131_HPP
88
# include <boost/type_traits/cv_traits.hpp>
99
# include <boost/type_traits/composite_traits.hpp>
10+
# include <boost/type_traits/function_traits.hpp>
1011
# include <boost/mpl/select_type.hpp>
1112

1213
namespace boost { namespace python { namespace detail {
@@ -24,6 +25,68 @@ struct is_reference_to_const<T const&>
2425
BOOST_STATIC_CONSTANT(bool, value = true);
2526
};
2627

28+
# if 0 // Corresponding code doesn't work on MSVC yet
29+
template <class T>
30+
struct is_reference_to_function
31+
{
32+
BOOST_STATIC_CONSTANT(bool, value = false);
33+
};
34+
35+
template <class T>
36+
struct is_reference_to_function<T&>
37+
{
38+
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
39+
};
40+
41+
template <class T>
42+
struct is_reference_to_function<T const&>
43+
{
44+
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
45+
};
46+
47+
template <class T>
48+
struct is_reference_to_function<T volatile&>
49+
{
50+
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
51+
};
52+
53+
template <class T>
54+
struct is_reference_to_function<T const volatile&>
55+
{
56+
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
57+
};
58+
# endif
59+
60+
template <class T>
61+
struct is_pointer_to_function
62+
{
63+
BOOST_STATIC_CONSTANT(bool, value = false);
64+
};
65+
66+
template <class T>
67+
struct is_pointer_to_function<T*>
68+
{
69+
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
70+
};
71+
72+
template <class T>
73+
struct is_pointer_to_function<T const*>
74+
{
75+
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
76+
};
77+
78+
template <class T>
79+
struct is_pointer_to_function<T volatile*>
80+
{
81+
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
82+
};
83+
84+
template <class T>
85+
struct is_pointer_to_function<T const volatile*>
86+
{
87+
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
88+
};
89+
2790
template <class T>
2891
struct is_reference_to_non_const
2992
{
@@ -114,6 +177,25 @@ struct is_pointer_help
114177
>::type type;
115178
};
116179

180+
# if 0 // doesn't seem to work yet
181+
template <class T>
182+
struct is_reference_to_function
183+
{
184+
static T t;
185+
BOOST_STATIC_CONSTANT(
186+
bool, value
187+
= sizeof(::boost::detail::is_function_tester(t)) == sizeof(::boost::type_traits::yes_type));
188+
# endif
189+
190+
template <class T>
191+
struct is_pointer_to_function
192+
{
193+
static T t;
194+
BOOST_STATIC_CONSTANT(
195+
bool, value
196+
= sizeof(::boost::detail::is_function_tester(t)) == sizeof(::boost::type_traits::yes_type));
197+
};
198+
117199
template <typename V>
118200
typename is_const_help<V>::type reference_to_const_helper(V&);
119201
outer_no_type

include/boost/python/make_function.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ objects::function* make_constructor(Holder* = 0, ArgList* = 0)
4949
, nargs + 1);
5050
}
5151

52+
template <class ArgList, class Holder, class Policies>
53+
objects::function* make_constructor(Policies const& policies, Holder* = 0, ArgList* = 0)
54+
{
55+
enum { nargs = mpl::size<ArgList>::value };
56+
57+
return new objects::function(
58+
objects::py_function(
59+
::boost::bind<PyObject*>(detail::caller(),
60+
objects::make_holder<nargs>
61+
::template apply<Holder,ArgList>::execute
62+
, _1, _2, policies))
63+
, nargs + 1);
64+
}
65+
5266
}} // namespace boost::python
5367

5468
#endif // MAKE_FUNCTION_DWA20011221_HPP

test/indirect_traits_test.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ int main()
88
{
99
using namespace boost::python::detail;
1010

11+
#if 0 // not yet supported
12+
assert(is_reference_to_function<int (&)()>::value);
13+
assert(!is_reference_to_function<int (*)()>::value);
14+
#endif
15+
16+
assert(!is_pointer_to_function<int (&)()>::value);
17+
assert(is_pointer_to_function<int (*)()>::value);
18+
1119
assert(is_reference_to_pointer<int*&>::value);
1220
assert(is_reference_to_pointer<int* const&>::value);
1321
assert(is_reference_to_pointer<int*volatile&>::value);

test/test_pointer_adoption.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ struct A
6060
struct B
6161
{
6262
B() : x(0) {}
63+
B(A* x_) : x(x_) {}
6364

6465
inner const* adopt(A* x) { this->x = x; return &x->get_inner(); }
6566

@@ -101,6 +102,7 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext)
101102
.add(
102103
class_<B>("B")
103104
.def_init()
105+
.def_init(args<A*>(), with_custodian_and_ward_postcall<1,2>())
104106

105107
.def("adopt", &B::adopt
106108
// Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self")

test/test_pointer_adoption.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,28 @@
4848
>>> del b
4949
>>> num_a_instances()
5050
0
51+
52+
Test call policies for constructors here
53+
54+
>>> a = create('second a')
55+
>>> num_a_instances()
56+
1
57+
>>> b = B(a)
58+
>>> num_a_instances()
59+
1
60+
>>> a.content()
61+
'second a'
62+
63+
>>> del a
64+
>>> num_a_instances()
65+
1
66+
>>> b.a_content()
67+
'second a'
68+
69+
>>> del b
70+
>>> num_a_instances()
71+
0
72+
5173
"""
5274
def run(args = None):
5375
import sys

0 commit comments

Comments
 (0)