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 
extract_bool(object x)24 bool extract_bool(object x) { return extract<bool>(x); }
25 
extract_list(object x)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 
extract_cstring(object x)39 char const* extract_cstring(object x)
40 {
41     return extract<char const*>(x);
42 }
43 
extract_string(object x)44 std::string extract_string(object x)
45 {
46     std::string s = extract<std::string>(x);
47     return s;
48 }
49 
extract_string_cref(object x)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 
extract_X(object x)67 X extract_X(object x)
68 {
69     return extract<X>(x);
70 }
71 
extract_X_ptr(object x)72 X* extract_X_ptr(object x) { return extract<X*>(x); }
73 
extract_X_ref(object x)74 X& extract_X_ref(object x)
75 {
76     extract<X&> get_x(x);
77     return get_x;
78 }
79 
double_X(object n)80 int double_X(object n)
81 {
82     extract<X> x(n);
83     return x().value() + x().value();
84 }
85 
check_bool(object x)86 bool check_bool(object x) { return extract<bool>(x).check(); }
check_list(object x)87 bool check_list(object x) { return extract<list>(x).check(); }
check_cstring(object x)88 bool check_cstring(object x) { return extract<char const*>(x).check(); }
check_string(object x)89 bool check_string(object x) { return extract<std::string>(x).check(); }
check_string_cref(object x)90 bool check_string_cref(object x) { return extract<std::string const&>(x).check(); }
check_X(object x)91 bool check_X(object x) { return extract<X>(x).check(); }
check_X_ptr(object x)92 bool check_X_ptr(object x) { return extract<X*>(x).check(); }
check_X_ref(object x)93 bool check_X_ref(object x) { return extract<X&>(x).check(); }
94 
x_rep(X const & x)95 std::string x_rep(X const& x)
96 {
97     return "X("  + boost::lexical_cast<std::string>(x.value()) + ")";
98 }
99 
BOOST_PYTHON_MODULE(extract_ext)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 
144