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 #ifndef BUILTIN_CONVERTERS_DWA2002124_HPP
6 # define BUILTIN_CONVERTERS_DWA2002124_HPP
7 # include <boost/python/detail/prefix.hpp>
8 # include <boost/python/detail/none.hpp>
9 # include <boost/python/handle.hpp>
10 # include <boost/implicit_cast.hpp>
11 # include <string>
12 # include <complex>
13 # include <boost/limits.hpp>
14 
15 // Since all we can use to decide how to convert an object to_python
16 // is its C++ type, there can be only one such converter for each
17 // type. Therefore, for built-in conversions we can bypass registry
18 // lookups using explicit specializations of arg_to_python and
19 // result_to_python.
20 
21 namespace boost { namespace python {
22 
23 namespace converter
24 {
25   template <class T> struct arg_to_python;
26   BOOST_PYTHON_DECL PyObject* do_return_to_python(char);
27   BOOST_PYTHON_DECL PyObject* do_return_to_python(char const*);
28   BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject*);
29   BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject*);
30 }
31 
32 // Provide specializations of to_python_value
33 template <class T> struct to_python_value;
34 
35 namespace detail
36 {
37   // Since there's no registry lookup, always report the existence of
38   // a converter.
39   struct builtin_to_python
40   {
41       // This information helps make_getter() decide whether to try to
42       // return an internal reference or not. I don't like it much,
43       // but it will have to serve for now.
44       BOOST_STATIC_CONSTANT(bool, uses_registry = false);
45   };
46 }
47 
48 // Use expr to create the PyObject corresponding to x
49 # define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr)        \
50     template <> struct to_python_value<T&>                      \
51         : detail::builtin_to_python                             \
52     {                                                           \
53         inline PyObject* operator()(T const& x) const           \
54         {                                                       \
55             return (expr);                                      \
56         }                                                       \
57     };                                                          \
58     template <> struct to_python_value<T const&>                \
59         : detail::builtin_to_python                             \
60     {                                                           \
61         inline PyObject* operator()(T const& x) const           \
62         {                                                       \
63             return (expr);                                      \
64         }                                                       \
65     };
66 
67 # define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr)   \
68     namespace converter                                 \
69     {                                                   \
70       template <> struct arg_to_python< T >             \
71         : handle<>                                      \
72       {                                                 \
73           arg_to_python(T const& x)                     \
74             : python::handle<>(expr) {}                 \
75       };                                                \
76     }
77 
78 // Specialize argument and return value converters for T using expr
79 # define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr)       \
80         BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr)  \
81         BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
82 
83 // Specialize converters for signed and unsigned T to Python Int
84 # define BOOST_PYTHON_TO_INT(T)                                         \
85     BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x))      \
86     BOOST_PYTHON_TO_PYTHON_BY_VALUE(                                    \
87         unsigned T                                                      \
88         , static_cast<unsigned long>(x) > static_cast<unsigned long>(   \
89                 (std::numeric_limits<long>::max)())                     \
90         ? ::PyLong_FromUnsignedLong(x)                                  \
91         : ::PyInt_FromLong(x))
92 
93 // Bool is not signed.
94 #if PY_VERSION_HEX >= 0x02030000
95 BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x))
96 #else
97 BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x))
98 #endif
99 
100 // note: handles signed char and unsigned char, but not char (see below)
101 BOOST_PYTHON_TO_INT(char)
102 
103 BOOST_PYTHON_TO_INT(short)
104 BOOST_PYTHON_TO_INT(int)
105 BOOST_PYTHON_TO_INT(long)
106 
107 // using Python's macro instead of Boost's - we don't seem to get the
108 // config right all the time.
109 # ifdef HAVE_LONG_LONG
110 BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x))
111 BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x))
112 # endif
113 
114 # undef BOOST_TO_PYTHON_INT
115 
116 BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x))
117 BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x))
118 BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<int>(x.size())))
119 # ifndef BOOST_NO_STD_WSTRING
120 BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<int>(x.size())))
121 # endif
122 BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x))
123 BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x))
124 BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x))
125 BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x))
126 BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()))
127 BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
128 BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
129 
130 # undef BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE
131 # undef BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE
132 # undef BOOST_PYTHON_TO_PYTHON_BY_VALUE
133 # undef BOOST_PYTHON_TO_INT
134 
135 namespace converter
136 {
137 
138   void initialize_builtin_converters();
139 
140 }
141 
142 }} // namespace boost::python::converter
143 
144 #endif // BUILTIN_CONVERTERS_DWA2002124_HPP
145