• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright David Abrahams 2002.
2 // Copyright Stefan Seefeld 2016.
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 #include "test_class.hpp"
8 
9 using namespace boost::python;
10 
11 typedef test_class<> X;
12 typedef test_class<1> Y;
13 
14 template <class T>
15 struct functions
16 {
lookfunctions17     static int look(shared_ptr<T> const& x)
18     {
19         return (x.get()) ? x->value() : -1;
20     }
21 
storefunctions22     static void store(shared_ptr<T> x)
23     {
24         storage = x;
25     }
26 
release_storefunctions27     static void release_store()
28     {
29         store(shared_ptr<T>());
30     }
31 
modifyfunctions32     static void modify(shared_ptr<T>& x)
33     {
34         x.reset();
35     }
36 
getfunctions37     static shared_ptr<T> get() { return storage; }
get1functions38     static shared_ptr<T> &get1() { return storage; }
39 
look_storefunctions40     static int look_store()
41     {
42         return look(get());
43     }
44 
45     template <class C>
exposefunctions46     static void expose(C const& c)
47     {
48         def("look", &look);
49         def("store", &store);
50         def("modify", &modify);
51         def("identity", &identity);
52         def("null", &null);
53 
54         const_cast<C&>(c)
55             .def("look", &look)
56             .staticmethod("look")
57             .def("store", &store)
58             .staticmethod("store")
59             .def("modify", &modify)
60             .staticmethod("modify")
61             .def("look_store", &look_store)
62             .staticmethod("look_store")
63             .def("identity", &identity)
64             .staticmethod("identity")
65             .def("null", &null)
66             .staticmethod("null")
67             .def("get1", &get1, return_internal_reference<>())
68             .staticmethod("get1")
69             .def("get", &get)
70             .staticmethod("get")
71             .def("count", &T::count)
72             .staticmethod("count")
73             .def("release", &release_store)
74             .staticmethod("release")
75             ;
76     }
77 
identityfunctions78     static shared_ptr<T> identity(shared_ptr<T> x) { return x; }
nullfunctions79     static shared_ptr<T> null(T const&) { return shared_ptr<T>(); }
80 
81 
82     static shared_ptr<T> storage;
83 };
84 
85 template <class T> shared_ptr<T> functions<T>::storage;
86 
87 struct Z : test_class<2>
88 {
ZZ89     Z(int x) : test_class<2>(x) {}
vZ90     virtual int v() { return this->value(); }
91 };
92 
93 struct ZWrap : Z
94 {
ZWrapZWrap95     ZWrap(PyObject* self, int x)
96         : Z(x), m_self(self) {}
97 
98 
vZWrap99     virtual int v() { return call_method<int>(m_self, "v"); }
default_vZWrap100     int default_v() { return Z::v(); }
101 
102 
103     PyObject* m_self;
104 };
105 
106 struct YY : Y
107 {
YYYY108     YY(int n) : Y(n) {}
109 };
110 
111 struct YYY : Y
112 {
YYYYYY113     YYY(int n) : Y(n) {}
114 };
115 
factory(int n)116 shared_ptr<Y> factory(int n)
117 {
118     return shared_ptr<Y>(n < 42 ? new Y(n) : new YY(n));
119 }
120 
121 // regressions from Nicodemus
122     struct A
123     {
~AA124         virtual ~A() {}; // silence compiler warnings
125         virtual int f() = 0;
call_fA126         static int call_f(shared_ptr<A>& a) { return a->f(); }
127     };
128 
129     struct B: A
130     {
fB131         int f() { return 1; }
132     };
133 
New(bool make)134     shared_ptr<A> New(bool make)
135     {
136         return shared_ptr<A>( make ? new B() : 0 );
137     }
138 
139     struct A_Wrapper: A
140     {
A_WrapperA_Wrapper141         A_Wrapper(PyObject* self_):
142             A(), self(self_) {}
143 
fA_Wrapper144         int f() {
145             return call_method< int >(self, "f");
146         }
147 
148         PyObject* self;
149     };
150 
151 // ------
152 
153 // from Neal Becker
154 
155 struct Test {
156   shared_ptr<X> x;
157 };
158 // ------
159 
160 
BOOST_PYTHON_MODULE(MODULE)161 BOOST_PYTHON_MODULE(MODULE)
162 {
163   class_<A, shared_ptr<A_Wrapper>, boost::noncopyable>("A")
164       .def("call_f", &A::call_f)
165       .staticmethod("call_f")
166       ;
167 
168     // This is the ugliness required to register a to-python converter
169     // for shared_ptr<A>.
170     objects::class_value_wrapper<
171         shared_ptr<A>
172       , objects::make_ptr_instance<A, objects::pointer_holder<shared_ptr<A>,A> >
173     >();
174 
175     def("New", &New);
176 
177     def("factory", factory);
178 
179     functions<X>::expose(
180         class_<X, boost::noncopyable>("X", init<int>())
181              .def("value", &X::value)
182         );
183 
184     functions<Y>::expose(
185         class_<Y, shared_ptr<Y> >("Y", init<int>())
186             .def("value", &Y::value)
187         );
188 
189     class_<YY, bases<Y>, boost::noncopyable>("YY", init<int>())
190         ;
191 
192     class_<YYY, shared_ptr<YYY>, bases<Y> >("YYY", init<int>())
193         ;
194 
195     functions<Z>::expose(
196         class_<Z, ZWrap>("Z", init<int>())
197             .def("value", &Z::value)
198             .def("v", &Z::v, &ZWrap::default_v)
199         );
200 
201 // from Neal Becker
202     class_<Test> ("Test")
203        .def_readonly ("x", &Test::x, "x")
204        ;
205 // ------
206 }
207