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