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