1 // Copyright David Abrahams 2001.
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 // This module exercises the converters exposed in m1 at a low level
7 // by exposing raw Python extension functions that use wrap<> and
8 // unwrap<> objects.
9 #include <boost/python/module.hpp>
10 #include <boost/python/def.hpp>
11 #include <boost/python/copy_non_const_reference.hpp>
12 #include <boost/python/copy_const_reference.hpp>
13 #include <boost/python/return_value_policy.hpp>
14 #include "simple_type.hpp"
15 
16 #if PY_VERSION_HEX >= 0x03000000
17 # define PyString_FromString PyUnicode_FromString
18 # define PyInt_FromLong PyLong_FromLong
19 #endif
20 
21 // Get a simple (by value) from the argument, and return the
22 // string it holds.
unwrap_simple(simple x)23 PyObject* unwrap_simple(simple x)
24 {
25     return PyString_FromString(x.s);
26 }
27 
28 // Likewise, but demands that its possible to get a non-const
29 // reference to the simple.
unwrap_simple_ref(simple & x)30 PyObject* unwrap_simple_ref(simple& x)
31 {
32     return PyString_FromString(x.s);
33 }
34 
35 // Likewise, with a const reference to the simple object.
unwrap_simple_const_ref(simple const & x)36 PyObject* unwrap_simple_const_ref(simple const& x)
37 {
38     return PyString_FromString(x.s);
39 }
40 
41 // Get an int (by value) from the argument, and convert it to a
42 // Python Int.
unwrap_int(int x)43 PyObject* unwrap_int(int x)
44 {
45     return PyInt_FromLong(x);
46 }
47 
48 // Get a non-const reference to an int from the argument
unwrap_int_ref(int & x)49 PyObject* unwrap_int_ref(int& x)
50 {
51     return PyInt_FromLong(x);
52 }
53 
54 // Get a const reference to an  int from the argument.
unwrap_int_const_ref(int const & x)55 PyObject* unwrap_int_const_ref(int const& x)
56 {
57     return PyInt_FromLong(x);
58 }
59 
60 #if PY_VERSION_HEX >= 0x03000000
61 # undef PyString_FromString
62 # undef PyInt_FromLong
63 #endif
64 
65 // rewrap<T> extracts a T from the argument, then converts the T back
66 // to a PyObject* and returns it.
67 template <class T>
68 struct rewrap
69 {
frewrap70     static T f(T x) { return x; }
71 };
72 
BOOST_PYTHON_MODULE(m2)73 BOOST_PYTHON_MODULE(m2)
74 {
75     using boost::python::return_value_policy;
76     using boost::python::copy_const_reference;
77     using boost::python::copy_non_const_reference;
78     using boost::python::def;
79 
80     def("unwrap_int", unwrap_int);
81     def("unwrap_int_ref", unwrap_int_ref);
82     def("unwrap_int_const_ref", unwrap_int_const_ref);
83     def("unwrap_simple", unwrap_simple);
84     def("unwrap_simple_ref", unwrap_simple_ref);
85     def("unwrap_simple_const_ref", unwrap_simple_const_ref);
86 
87     def("wrap_int", &rewrap<int>::f);
88 
89     def("wrap_int_ref", &rewrap<int&>::f
90         , return_value_policy<copy_non_const_reference>()
91         );
92 
93     def("wrap_int_const_ref", &rewrap<int const&>::f
94         , return_value_policy<copy_const_reference>()
95         );
96 
97     def("wrap_simple", &rewrap<simple>::f);
98 
99     def("wrap_simple_ref", &rewrap<simple&>::f
100         , return_value_policy<copy_non_const_reference>()
101         );
102 
103     def("wrap_simple_const_ref", &rewrap<simple const&>::f
104         , return_value_policy<copy_const_reference>()
105             );
106 }
107 
108 #include "module_tail.cpp"
109