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/object.hpp>
8 #include <boost/python/class.hpp>
9
10 using namespace boost::python;
11
12 class NotCopyable
13 {
14 } not_copyable;
15
ref_to_noncopyable()16 object ref_to_noncopyable()
17 {
18 return object(boost::ref(not_copyable));
19 }
20
call_object_3(object f)21 object call_object_3(object f)
22 {
23 return f(3);
24 }
25
message()26 object message()
27 {
28 return object("hello, world!");
29 }
30
number()31 object number()
32 {
33 return object(42);
34 }
35
obj_getattr(object x,char const * name)36 object obj_getattr(object x, char const* name)
37 {
38 return x.attr(name);
39 }
40
obj_objgetattr(object x,object const & name)41 object obj_objgetattr(object x, object const& name)
42 {
43 return x.attr(name);
44 }
45
obj_const_getattr(object const & x,char const * name)46 object obj_const_getattr(object const& x, char const* name)
47 {
48 return x.attr(name);
49 }
50
obj_const_objgetattr(object const & x,object const & name)51 object obj_const_objgetattr(object const& x, object const& name)
52 {
53 return x.attr(name);
54 }
55
obj_setattr(object x,char const * name,object value)56 void obj_setattr(object x, char const* name, object value)
57 {
58 x.attr(name) = value;
59 }
60
obj_objsetattr(object x,object const & name,object value)61 void obj_objsetattr(object x, object const& name, object value)
62 {
63 x.attr(name) = value;
64 }
65
obj_setattr42(object x,char const * name)66 void obj_setattr42(object x, char const* name)
67 {
68 x.attr(name) = 42;
69 }
70
obj_objsetattr42(object x,object const & name)71 void obj_objsetattr42(object x, object const& name)
72 {
73 x.attr(name) = 42;
74 }
75
obj_moveattr(object & x,char const * src,char const * dst)76 void obj_moveattr(object& x, char const* src, char const* dst)
77 {
78 x.attr(dst) = x.attr(src);
79 }
80
obj_objmoveattr(object & x,object const & src,object const & dst)81 void obj_objmoveattr(object& x, object const& src, object const& dst)
82 {
83 x.attr(dst) = x.attr(src);
84 }
85
obj_delattr(object x,char const * name)86 void obj_delattr(object x, char const* name)
87 {
88 x.attr(name).del();
89 }
90
obj_objdelattr(object x,object const & name)91 void obj_objdelattr(object x, object const& name)
92 {
93 x.attr(name).del();
94 }
95
obj_getitem(object x,object key)96 object obj_getitem(object x, object key)
97 {
98 return x[key];
99 }
100
obj_getitem3(object x)101 object obj_getitem3(object x)
102 {
103 return x[3];
104 }
105
obj_const_getitem(object const & x,object key)106 object obj_const_getitem(object const& x, object key)
107 {
108 return x[key];
109 }
110
obj_setitem(object x,object key,object value)111 void obj_setitem(object x, object key, object value)
112 {
113 x[key] = value;
114 }
115
obj_setitem42(object x,object key)116 void obj_setitem42(object x, object key)
117 {
118 x[key] = 42;
119 }
120
obj_moveitem(object & x,object src,object dst)121 void obj_moveitem(object& x, object src, object dst)
122 {
123 x[dst] = x[src];
124 }
125
obj_moveitem2(object const & x_src,object k_src,object & x_dst,object k_dst)126 void obj_moveitem2(object const& x_src, object k_src, object& x_dst, object k_dst)
127 {
128 x_dst[k_dst] = x_src[k_src];
129 }
130
test(object y)131 bool test(object y)
132 {
133 return y;
134 }
135
test_not(object y)136 bool test_not(object y)
137 {
138 return !y;
139 }
140
test_attr(object y,char * name)141 bool test_attr(object y, char* name)
142 {
143 return y.attr(name);
144 }
145
test_objattr(object y,object & name)146 bool test_objattr(object y, object& name)
147 {
148 return y.attr(name);
149 }
150
test_not_attr(object y,char * name)151 bool test_not_attr(object y, char* name)
152 {
153 return !y.attr(name);
154 }
155
test_not_objattr(object y,object & name)156 bool test_not_objattr(object y, object& name)
157 {
158 return !y.attr(name);
159 }
160
test_item(object y,object key)161 bool test_item(object y, object key)
162 {
163 return y[key];
164 }
165
test_not_item(object y,object key)166 bool test_not_item(object y, object key)
167 {
168 return !y[key];
169 }
170
check_string_slice()171 bool check_string_slice()
172 {
173 object s("hello, world");
174
175 if (s.slice(_,-3) != "hello, wo")
176 return false;
177
178 if (s.slice(-3,_) != "rld")
179 return false;
180
181 if (s.slice(_,_) != s)
182 return false;
183
184 if (", " != s.slice(5,7))
185 return false;
186
187 return s.slice(2,-1).slice(1,-1) == "lo, wor";
188 }
189
test_call(object c,object args,object kwds)190 object test_call(object c, object args, object kwds)
191 {
192 return c(*args, **kwds);
193 }
194
check_binary_operators()195 bool check_binary_operators()
196 {
197 int y;
198
199 object x(3);
200
201 #define TEST_BINARY(op) \
202 for (y = 1; y < 6; ++y) \
203 { \
204 if ((x op y) != (3 op y)) \
205 return false; \
206 } \
207 for (y = 1; y < 6; ++y) \
208 { \
209 if ((y op x) != (y op 3)) \
210 return false; \
211 } \
212 for (y = 1; y < 6; ++y) \
213 { \
214 object oy(y); \
215 if ((oy op x) != (oy op 3)) \
216 return false; \
217 }
218 TEST_BINARY(>)
219 TEST_BINARY(>=)
220 TEST_BINARY(<)
221 TEST_BINARY(<=)
222 TEST_BINARY(==)
223 TEST_BINARY(!=)
224
225 TEST_BINARY(+)
226 TEST_BINARY(-)
227 TEST_BINARY(*)
228 TEST_BINARY(/)
229 TEST_BINARY(%)
230 TEST_BINARY(<<)
231 TEST_BINARY(>>)
232 TEST_BINARY(&)
233 TEST_BINARY(^)
234 TEST_BINARY(|)
235 return true;
236 }
237
check_inplace(object l,object o)238 bool check_inplace(object l, object o)
239 {
240 int y;
241 #define TEST_INPLACE(op) \
242 for (y = 1; y < 6; ++y) \
243 { \
244 object x(666); \
245 x op##= y; \
246 if (x != (666 op y)) \
247 return false; \
248 } \
249 for (y = 1; y < 6; ++y) \
250 { \
251 object x(666); \
252 x op##= object(y); \
253 if (!(x == (666 op y))) \
254 return false; \
255 }
256 TEST_INPLACE(+)
257 TEST_INPLACE(-)
258 TEST_INPLACE(*)
259 TEST_INPLACE(/)
260 TEST_INPLACE(%)
261 TEST_INPLACE(<<)
262 TEST_INPLACE(>>)
263 TEST_INPLACE(&)
264 TEST_INPLACE(^)
265 TEST_INPLACE(|)
266
267 l += l;
268 for (y = 0; y < 6; ++y)
269 {
270 if (l[y] != y % 3)
271 return false;
272 }
273
274 #define TEST_ITEM_INPLACE(index, op, n, r1, r2) \
275 l[index] op##= n; \
276 if (l[index] != r1) \
277 return false; \
278 l[index] op##= object(n); \
279 if (!(l[index] == r2)) \
280 return false;
281
282 TEST_ITEM_INPLACE(0,+,7,7,14)
283 TEST_ITEM_INPLACE(1,-,2,-1,-3)
284 TEST_ITEM_INPLACE(2,*,3,6,18)
285 TEST_ITEM_INPLACE(2,/,2,9,4)
286 TEST_ITEM_INPLACE(0,%,4,2,2)
287 l[0] += 1;
288 TEST_ITEM_INPLACE(0,<<,2,12,48)
289 TEST_ITEM_INPLACE(0,>>,1,24,12)
290 l[4] = 15;
291 TEST_ITEM_INPLACE(4,&,(16+4+1),5,5)
292 TEST_ITEM_INPLACE(0,^,1,13,12)
293 TEST_ITEM_INPLACE(0,|,1,13,13)
294
295 o.attr("x0") = 0;
296 o.attr("x1") = 1;
297 o.attr("x2") = 2;
298 o.attr("x3") = 0;
299 o.attr("x4") = 1;
300
301 #define TEST_ATTR_INPLACE(index, op, n, r1, r2) \
302 o.attr("x" #index) op##= n; \
303 if (o.attr("x" #index) != r1) \
304 return false; \
305 o.attr("x" #index) op##= object(n); \
306 if (o.attr("x" #index) != r2) \
307 return false;
308
309 TEST_ATTR_INPLACE(0,+,7,7,14)
310 TEST_ATTR_INPLACE(1,-,2,-1,-3)
311 TEST_ATTR_INPLACE(2,*,3,6,18)
312 TEST_ATTR_INPLACE(2,/,2,9,4)
313 TEST_ATTR_INPLACE(0,%,4,2,2)
314 o.attr("x0") += 1;
315 TEST_ATTR_INPLACE(0,<<,2,12,48)
316 TEST_ATTR_INPLACE(0,>>,1,24,12)
317 o.attr("x4") = 15;
318 TEST_ATTR_INPLACE(4,&,(16+4+1),5,5)
319 TEST_ATTR_INPLACE(0,^,1,13,12)
320 TEST_ATTR_INPLACE(0,|,1,13,13)
321
322 if (l[0] != o.attr("x0"))
323 return false;
324 if (l[1] != o.attr("x1"))
325 return false;
326 if (l[2] != o.attr("x2"))
327 return false;
328 if (l[3] != o.attr("x3"))
329 return false;
330 if (l[4] != o.attr("x4"))
331 return false;
332
333 // set item 5 to be a list, by calling l.__class__
334 l[5] = l.attr("__class__")();
335 // append an element
336 l[5].attr("append")(2);
337 // Check its value
338 if (l[5][0] != 2)
339 return false;
340
341 return true;
342 }
343
BOOST_PYTHON_MODULE(object_ext)344 BOOST_PYTHON_MODULE(object_ext)
345 {
346 class_<NotCopyable, boost::noncopyable>("NotCopyable", no_init);
347
348 def("ref_to_noncopyable", ref_to_noncopyable);
349 def("call_object_3", call_object_3);
350 def("message", message);
351 def("number", number);
352
353 def("obj_getattr", obj_getattr);
354 def("obj_objgetattr", obj_objgetattr);
355 def("obj_const_getattr", obj_const_getattr);
356 def("obj_const_objgetattr", obj_const_objgetattr);
357 def("obj_setattr", obj_setattr);
358 def("obj_objsetattr", obj_objsetattr);
359 def("obj_setattr42", obj_setattr42);
360 def("obj_objsetattr42", obj_objsetattr42);
361 def("obj_moveattr", obj_moveattr);
362 def("obj_objmoveattr", obj_objmoveattr);
363 def("obj_delattr", obj_delattr);
364 def("obj_objdelattr", obj_objdelattr);
365
366 def("obj_getitem", obj_getitem);
367 def("obj_getitem3", obj_getitem);
368 def("obj_const_getitem", obj_const_getitem);
369 def("obj_setitem", obj_setitem);
370 def("obj_setitem42", obj_setitem42);
371 def("obj_moveitem", obj_moveitem);
372 def("obj_moveitem2", obj_moveitem2);
373
374 def("test", test);
375 def("test_not", test_not);
376
377 def("test_attr", test_attr);
378 def("test_objattr", test_objattr);
379 def("test_not_attr", test_not_attr);
380 def("test_not_objattr", test_not_objattr);
381
382 def("test_item", test_item);
383 def("test_not_item", test_not_item);
384
385 def("test_call", test_call);
386 def("check_binary_operators", check_binary_operators);
387 def("check_inplace", check_inplace);
388 def("check_string_slice", check_string_slice);
389 ;
390 }
391
392 #include "module_tail.cpp"
393