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 | |
---|
6 | #include <boost/python/extract.hpp> |
---|
7 | #include <boost/python/list.hpp> |
---|
8 | #include <boost/python/module.hpp> |
---|
9 | #include <boost/python/def.hpp> |
---|
10 | #include <boost/python/class.hpp> |
---|
11 | #include <boost/python/reference_existing_object.hpp> |
---|
12 | #include <boost/python/return_value_policy.hpp> |
---|
13 | #include <boost/python/implicit.hpp> |
---|
14 | #include <string> |
---|
15 | #include <boost/lexical_cast.hpp> |
---|
16 | #define BOOST_ENABLE_ASSERT_HANDLER |
---|
17 | #include <boost/assert.hpp> |
---|
18 | #include "test_class.hpp" |
---|
19 | |
---|
20 | using namespace boost::python; |
---|
21 | |
---|
22 | typedef test_class<> X; |
---|
23 | |
---|
24 | bool extract_bool(object x) { return extract<bool>(x); } |
---|
25 | |
---|
26 | boost::python::list extract_list(object x) |
---|
27 | { |
---|
28 | extract<list> get_list((x)); |
---|
29 | |
---|
30 | // Make sure we always have the right idea about whether it's a list |
---|
31 | bool is_list_1 = get_list.check(); |
---|
32 | bool is_list_2 = PyObject_IsInstance(x.ptr(), (PyObject*)&PyList_Type); |
---|
33 | if (is_list_1 != is_list_2) { |
---|
34 | throw std::runtime_error("is_list_1 == is_list_2 failure."); |
---|
35 | } |
---|
36 | return get_list(); |
---|
37 | } |
---|
38 | |
---|
39 | char const* extract_cstring(object x) |
---|
40 | { |
---|
41 | return extract<char const*>(x); |
---|
42 | } |
---|
43 | |
---|
44 | std::string extract_string(object x) |
---|
45 | { |
---|
46 | std::string s = extract<std::string>(x); |
---|
47 | return s; |
---|
48 | } |
---|
49 | |
---|
50 | std::string const& extract_string_cref(object x) |
---|
51 | { |
---|
52 | #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 |
---|
53 | # pragma warning(push) |
---|
54 | # pragma warning(disable:4172) // msvc lies about returning a reference to temporary |
---|
55 | #elif defined(_MSC_VER) && defined(__ICL) && __ICL <= 900 |
---|
56 | # pragma warning(push) |
---|
57 | # pragma warning(disable:473) // intel/win32 does too |
---|
58 | #endif |
---|
59 | |
---|
60 | return extract<std::string const&>(x); |
---|
61 | |
---|
62 | #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 800 |
---|
63 | # pragma warning(pop) |
---|
64 | #endif |
---|
65 | } |
---|
66 | |
---|
67 | X extract_X(object x) |
---|
68 | { |
---|
69 | return extract<X>(x); |
---|
70 | } |
---|
71 | |
---|
72 | X* extract_X_ptr(object x) { return extract<X*>(x); } |
---|
73 | |
---|
74 | X& extract_X_ref(object x) |
---|
75 | { |
---|
76 | extract<X&> get_x(x); |
---|
77 | return get_x; |
---|
78 | } |
---|
79 | |
---|
80 | int double_X(object n) |
---|
81 | { |
---|
82 | extract<X> x(n); |
---|
83 | return x().value() + x().value(); |
---|
84 | } |
---|
85 | |
---|
86 | bool check_bool(object x) { return extract<bool>(x).check(); } |
---|
87 | bool check_list(object x) { return extract<list>(x).check(); } |
---|
88 | bool check_cstring(object x) { return extract<char const*>(x).check(); } |
---|
89 | bool check_string(object x) { return extract<std::string>(x).check(); } |
---|
90 | bool check_string_cref(object x) { return extract<std::string const&>(x).check(); } |
---|
91 | bool check_X(object x) { return extract<X>(x).check(); } |
---|
92 | bool check_X_ptr(object x) { return extract<X*>(x).check(); } |
---|
93 | bool check_X_ref(object x) { return extract<X&>(x).check(); } |
---|
94 | |
---|
95 | std::string x_rep(X const& x) |
---|
96 | { |
---|
97 | return "X(" + boost::lexical_cast<std::string>(x.value()) + ")"; |
---|
98 | } |
---|
99 | |
---|
100 | BOOST_PYTHON_MODULE(extract_ext) |
---|
101 | { |
---|
102 | implicitly_convertible<int, X>(); |
---|
103 | |
---|
104 | def("extract_bool", extract_bool); |
---|
105 | def("extract_list", extract_list); |
---|
106 | def("extract_cstring", extract_cstring); |
---|
107 | def("extract_string", extract_string); |
---|
108 | def("extract_string_cref", extract_string_cref, return_value_policy<reference_existing_object>()); |
---|
109 | def("extract_X", extract_X); |
---|
110 | def("extract_X_ptr", extract_X_ptr, return_value_policy<reference_existing_object>()); |
---|
111 | def("extract_X_ref", extract_X_ref, return_value_policy<reference_existing_object>()); |
---|
112 | |
---|
113 | def("check_bool", check_bool); |
---|
114 | def("check_list", check_list); |
---|
115 | def("check_cstring", check_cstring); |
---|
116 | def("check_string", check_string); |
---|
117 | def("check_string_cref", check_string_cref); |
---|
118 | def("check_X", check_X); |
---|
119 | def("check_X_ptr", check_X_ptr); |
---|
120 | def("check_X_ref", check_X_ref); |
---|
121 | |
---|
122 | def("double_X", double_X); |
---|
123 | |
---|
124 | def("count_Xs", &X::count); |
---|
125 | ; |
---|
126 | |
---|
127 | object x_class( |
---|
128 | class_<X>("X", init<int>()) |
---|
129 | .def( "__repr__", x_rep)); |
---|
130 | |
---|
131 | // Instantiate an X object through the Python interface |
---|
132 | object x_obj = x_class(3); |
---|
133 | |
---|
134 | // Get the C++ object out of the Python object |
---|
135 | X const& x = extract<X&>(x_obj); |
---|
136 | if (x.value() != 3) { |
---|
137 | throw std::runtime_error("x.value() == 3 failure."); |
---|
138 | } |
---|
139 | } |
---|
140 | |
---|
141 | |
---|
142 | #include "module_tail.cpp" |
---|
143 | |
---|