1 | // Copyright David Abrahams 2002. |
---|
2 | // Distributed under the Boost Software License, Version 1.0. (See |
---|
3 | // accompanying file LICENSE_1_0.txt or copy at |
---|
4 | // http://www.boost.org/LICENSE_1_0.txt) |
---|
5 | #include <boost/python/module.hpp> |
---|
6 | #include <boost/python/def.hpp> |
---|
7 | #include <boost/python/return_value_policy.hpp> |
---|
8 | #include <boost/python/manage_new_object.hpp> |
---|
9 | #include <boost/python/return_internal_reference.hpp> |
---|
10 | #include <boost/python/class.hpp> |
---|
11 | |
---|
12 | using namespace boost::python; |
---|
13 | |
---|
14 | int a_instances = 0; |
---|
15 | |
---|
16 | int num_a_instances() { return a_instances; } |
---|
17 | |
---|
18 | struct inner |
---|
19 | { |
---|
20 | inner(std::string const& s) |
---|
21 | : s(s) |
---|
22 | {} |
---|
23 | |
---|
24 | void change(std::string const& new_s) |
---|
25 | { |
---|
26 | this->s = new_s; |
---|
27 | } |
---|
28 | |
---|
29 | std::string s; |
---|
30 | }; |
---|
31 | |
---|
32 | struct Base |
---|
33 | { |
---|
34 | virtual ~Base() {} |
---|
35 | }; |
---|
36 | |
---|
37 | struct A : Base |
---|
38 | { |
---|
39 | A(std::string const& s) |
---|
40 | : x(s) |
---|
41 | { |
---|
42 | ++a_instances; |
---|
43 | } |
---|
44 | |
---|
45 | ~A() |
---|
46 | { |
---|
47 | --a_instances; |
---|
48 | } |
---|
49 | |
---|
50 | std::string content() const |
---|
51 | { |
---|
52 | return x.s; |
---|
53 | } |
---|
54 | |
---|
55 | inner& get_inner() |
---|
56 | { |
---|
57 | return x; |
---|
58 | } |
---|
59 | |
---|
60 | inner x; |
---|
61 | }; |
---|
62 | |
---|
63 | struct B |
---|
64 | { |
---|
65 | B() : x(0) {} |
---|
66 | B(A* x_) : x(x_) {} |
---|
67 | |
---|
68 | inner const* adopt(A* x) { this->x = x; return &x->get_inner(); } |
---|
69 | |
---|
70 | std::string a_content() |
---|
71 | { |
---|
72 | return x ? x->content() : std::string("empty"); |
---|
73 | } |
---|
74 | |
---|
75 | A* x; |
---|
76 | }; |
---|
77 | |
---|
78 | |
---|
79 | A* create(std::string const& s) |
---|
80 | { |
---|
81 | return new A(s); |
---|
82 | } |
---|
83 | |
---|
84 | A* as_A(Base* b) |
---|
85 | { |
---|
86 | return dynamic_cast<A*>(b); |
---|
87 | } |
---|
88 | |
---|
89 | BOOST_PYTHON_MODULE(test_pointer_adoption_ext) |
---|
90 | { |
---|
91 | def("num_a_instances", num_a_instances); |
---|
92 | |
---|
93 | // Specify the manage_new_object return policy to take |
---|
94 | // ownership of create's result |
---|
95 | def("create", create, return_value_policy<manage_new_object>()); |
---|
96 | |
---|
97 | def("as_A", as_A, return_internal_reference<>()); |
---|
98 | |
---|
99 | class_<Base>("Base") |
---|
100 | ; |
---|
101 | |
---|
102 | class_<A, bases<Base> >("A", no_init) |
---|
103 | .def("content", &A::content) |
---|
104 | .def("get_inner", &A::get_inner, return_internal_reference<>()) |
---|
105 | ; |
---|
106 | |
---|
107 | class_<inner>("inner", no_init) |
---|
108 | .def("change", &inner::change) |
---|
109 | ; |
---|
110 | |
---|
111 | class_<B>("B") |
---|
112 | .def(init<A*>()[with_custodian_and_ward_postcall<1,2>()]) |
---|
113 | |
---|
114 | .def("adopt", &B::adopt |
---|
115 | // Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self") |
---|
116 | , return_internal_reference<2 |
---|
117 | // Meanwhile, self holds a reference to the 2nd argument. |
---|
118 | , with_custodian_and_ward<1,2> >() |
---|
119 | ) |
---|
120 | |
---|
121 | .def("a_content", &B::a_content) |
---|
122 | ; |
---|
123 | } |
---|
124 | |
---|
125 | #include "module_tail.cpp" |
---|