Skip to content

Commit 25c5616

Browse files
committed
Last rewrite of the type conversion mechanism, I hope
[SVN r12631]
1 parent 12988b8 commit 25c5616

29 files changed

+304
-915
lines changed

Jamfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ PYTHON_PROPERTIES
1515
dll bpl
1616
:
1717
src/converter/from_python.cpp
18-
src/converter/to_python.cpp
1918
src/converter/registry.cpp
2019
src/converter/type_id.cpp
2120
src/object/class.cpp

example/rwgk2.cpp

Lines changed: 0 additions & 50 deletions
This file was deleted.

example/rwgk3.cpp

Lines changed: 0 additions & 101 deletions
This file was deleted.

include/boost/python/converter/builtin_to_python_converters.hpp

Lines changed: 39 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,68 +8,55 @@
88
# include <string>
99
# include <boost/python/detail/wrap_python.hpp>
1010

11-
namespace boost { namespace python { namespace converter {
11+
namespace boost { namespace python {
1212

13-
template <class T> struct to_python_lookup;
13+
// Provide specializations of to_python_value
14+
template <class T> struct to_python_value;
1415

15-
template <class T>
16-
struct to_python_int
16+
namespace detail
1717
{
18-
bool convertible() const { return true; }
19-
PyObject* operator()(T x) const { return PyInt_FromLong(long(x)); }
20-
};
21-
22-
# define BOOST_PYTHON_TO_INT(T) \
23-
template <> struct to_python_lookup<signed T const&> : to_python_int<signed T const&> {}; \
24-
template <> struct to_python_lookup<unsigned T const&> : to_python_int<unsigned T const&> {};
18+
struct builtin_to_python
19+
{
20+
static bool convertible() { return true; }
21+
};
22+
}
23+
24+
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
25+
template <> struct to_python_value<T&> \
26+
: detail::builtin_to_python \
27+
{ \
28+
PyObject* operator()(T const& x) const \
29+
{ \
30+
return (expr); \
31+
} \
32+
}; \
33+
template <> struct to_python_value<T const&> \
34+
: detail::builtin_to_python \
35+
{ \
36+
PyObject* operator()(T const& x) const \
37+
{ \
38+
return (expr); \
39+
} \
40+
};
41+
42+
43+
# define BOOST_PYTHON_TO_INT(T) \
44+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \
45+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x))
2546

2647
BOOST_PYTHON_TO_INT(char)
2748
BOOST_PYTHON_TO_INT(short)
2849
BOOST_PYTHON_TO_INT(int)
2950
BOOST_PYTHON_TO_INT(long)
3051
# undef BOOST_TO_PYTHON_INT
3152

32-
template <>
33-
struct to_python_lookup<char const*const&>
34-
{
35-
bool convertible() const { return true; }
36-
PyObject* operator()(char const* x) const { return PyString_FromString(x); }
37-
};
38-
39-
template <>
40-
struct to_python_lookup<std::string const&>
41-
{
42-
bool convertible() const { return true; }
43-
PyObject* operator()(std::string const& x) const
44-
{
45-
return PyString_FromString(x.c_str());
46-
}
47-
};
53+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, PyString_FromString(x))
54+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str()))
55+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x))
56+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x))
57+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x))
58+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x)
4859

49-
template <>
50-
struct to_python_lookup<float const&>
51-
{
52-
bool convertible() const { return true; }
53-
PyObject* operator()(float x) const { return PyFloat_FromDouble(x); }
54-
};
55-
56-
template <>
57-
struct to_python_lookup<double const&>
58-
{
59-
bool convertible() const { return true; }
60-
PyObject* operator()(double x) const { return PyFloat_FromDouble(x); }
61-
};
62-
63-
template <>
64-
struct to_python_lookup<long double const&>
65-
{
66-
bool convertible() const { return true; }
67-
PyObject* operator()(long double x) const
68-
{
69-
return PyFloat_FromDouble(x);
70-
}
71-
};
72-
73-
}}} // namespace boost::python::converter
60+
}} // namespace boost::python::converter
7461

7562
#endif // BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP

include/boost/python/converter/from_python.hpp

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# include <boost/python/converter/from_python_function.hpp>
1212
# include <boost/python/converter/from_python_data.hpp>
1313
# include <boost/python/converter/type_id.hpp>
14-
# include <boost/python/converter/registration.hpp>
14+
# include <boost/python/converter/registry.hpp>
1515
# include <boost/python/detail/wrap_python.hpp>
1616

1717
namespace boost { namespace python { namespace converter {
@@ -29,16 +29,21 @@ template <class T> struct from_python_lookup;
2929
struct BOOST_PYTHON_DECL from_python_converter_base : body
3030
{
3131
from_python_converter_base(type_id_t, from_python_check); // registers
32-
~from_python_converter_base(); // unregisters
3332

3433
// Must return non-null iff the conversion will be successful. Any
3534
// non-null pointer is acceptable, and will be passed on to the
3635
// convert() function, so useful data can be stored there.
3736
inline void* convertible(PyObject*) const;
38-
// inline type_id_t key() const;
37+
38+
// Given the head of a from_python converter chain, find the
39+
// converter which can convert p, leaving its intermediate data in
40+
// data.
41+
inline static from_python_converter_base const*
42+
find(from_python_converter_base const*chain, PyObject* p, void*& data);
43+
3944
private:
40-
// type_id_t m_key;
4145
from_python_check m_convertible;
46+
from_python_converter_base* m_next;
4247
};
4348

4449

@@ -52,17 +57,24 @@ struct from_python_converter : from_python_converter_base
5257
from_python_converter(from_python_check, conversion_function, from_python_destructor = 0);
5358
T convert(PyObject*, from_python_data&) const;
5459
void destroy(from_python_data&) const;
60+
61+
// Find a converter for converting p to a T.
62+
static from_python_converter<T> const* find(PyObject* p, void*& data);
5563

5664
private: // data members
5765
conversion_function m_convert;
5866
from_python_destructor m_destroy;
67+
68+
// Keeps the chain of converters which convert from PyObject* to T
69+
static from_python_converter_base*const& chain;
5970
};
6071

61-
// -------------------------------------------------------------------------
72+
// Initialized to refer to a common place in the registry.
73+
template <class T>
74+
from_python_converter_base*const&
75+
from_python_converter<T>::chain = registry::from_python_chain(type_id<T>());
6276

63-
//struct from_python_base
64-
//{
65-
//};
77+
// -------------------------------------------------------------------------
6678

6779
// A class which implements from_python with a registry lookup.
6880
template <class T>
@@ -95,12 +107,21 @@ inline void* from_python_converter_base::convertible(PyObject* o) const
95107
return m_convertible(o);
96108
}
97109

98-
# if 0
99-
inline type_id_t from_python_converter_base::key() const
110+
inline from_python_converter_base const*
111+
from_python_converter_base::find(
112+
from_python_converter_base const* chain, PyObject* p, void*& data)
100113
{
101-
return m_key;
114+
for (from_python_converter_base const* q = chain; q != 0 ; q = q->m_next)
115+
{
116+
void* d = q->convertible(p);
117+
if (d != 0)
118+
{
119+
data = d;
120+
return q;
121+
}
122+
}
123+
return 0;
102124
}
103-
# endif
104125

105126
template <class T>
106127
inline from_python_converter<T>::from_python_converter(
@@ -115,6 +136,14 @@ inline from_python_converter<T>::from_python_converter(
115136

116137
}
117138

139+
template <class T>
140+
inline from_python_converter<T> const*
141+
from_python_converter<T>::find(PyObject* p, void*& data)
142+
{
143+
return static_cast<from_python_converter<T> const*>(
144+
from_python_converter_base::find(chain, p, data));
145+
}
146+
118147
template <class T>
119148
inline T from_python_converter<T>::convert(PyObject* src, from_python_data& data) const
120149
{
@@ -133,7 +162,7 @@ inline void from_python_converter<T>::destroy(from_python_data& data) const
133162
template <class T>
134163
inline from_python_lookup<T>::from_python_lookup(PyObject* src)
135164
: m_converter(
136-
registration<T>::get_from_python(
165+
from_python_converter<T>::find(
137166
src, m_intermediate_data.stage1))
138167
{
139168
}

0 commit comments

Comments
 (0)