From 4e54b4ad1c6c5c875845beef1acde2bbd06e0aea Mon Sep 17 00:00:00 2001 From: huangqinjin Date: Mon, 12 Dec 2022 22:52:12 +0800 Subject: [PATCH 1/2] Add builtin converter for None <-> std::nullptr_t --- .../python/converter/builtin_converters.hpp | 4 ++++ src/converter/builtin_converters.cpp | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index c2e01c03d3..ff638979d9 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -108,6 +108,10 @@ namespace detail : ::PyInt_FromLong(x), &PyInt_Type) #endif +#ifndef BOOST_NO_CXX11_NULLPTR +BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::nullptr_t, boost::python::detail::none(), Py_TYPE(Py_None)) +#endif + // Bool is not signed. #if PY_VERSION_HEX >= 0x02030000 BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x), &PyBool_Type) diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index ee2d5b4794..2286feb496 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -306,6 +306,26 @@ namespace }; #endif +#ifndef BOOST_NO_CXX11_NULLPTR + struct nullptr_rvalue_from_python + { + static unaryfunc* get_slot(PyObject* obj) + { + return obj == Py_None ? &py_object_identity : 0; + } + + static std::nullptr_t extract(PyObject*) + { + return nullptr; + } + + static PyTypeObject const* get_pytype() + { + return Py_TYPE(Py_None); + } + }; +#endif + // A SlotPolicy for extracting bool from a Python object struct bool_rvalue_from_python { @@ -549,6 +569,10 @@ BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject* x) void initialize_builtin_converters() { +#ifndef BOOST_NO_CXX11_NULLPTR + slot_rvalue_from_python(); +#endif + // booleans slot_rvalue_from_python(); From 1c1db3ad05208fbba8986e6037e84081bbe2864c Mon Sep 17 00:00:00 2001 From: huangqinjin Date: Tue, 13 Dec 2022 20:43:02 +0800 Subject: [PATCH 2/2] Add tests for None <-> nullptr_t conversion --- test/builtin_converters.cpp | 6 ++++++ test/test_builtin_converters.py | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/test/builtin_converters.cpp b/test/builtin_converters.cpp index f66e61bd82..2a489f50b9 100644 --- a/test/builtin_converters.cpp +++ b/test/builtin_converters.cpp @@ -76,6 +76,9 @@ BOOST_PYTHON_MODULE(builtin_converters_ext) def("long_long_size", by_value::size); #endif +#ifndef BOOST_NO_CXX11_NULLPTR + def("rewrap_value_nullptr_t", by_value::rewrap); +#endif def("rewrap_value_bool", by_value::rewrap); def("rewrap_value_char", by_value::rewrap); def("rewrap_value_signed_char", by_value::rewrap); @@ -121,6 +124,9 @@ BOOST_PYTHON_MODULE(builtin_converters_ext) def("rewrap_value_mutable_cstring", rewrap_value_mutable_cstring); +#ifndef BOOST_NO_CXX11_NULLPTR + def("rewrap_const_reference_nullptr_t", by_const_reference::rewrap); +#endif def("rewrap_const_reference_bool", by_const_reference::rewrap); def("rewrap_const_reference_char", by_const_reference::rewrap); def("rewrap_const_reference_signed_char", by_const_reference::rewrap); diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index 0f1b4ded75..26b3c236cc 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -32,6 +32,12 @@ ... def rewrap_const_reference_unsigned_long_long(x): return long(x) >>> if not 'long_long_size' in dir(): ... def long_long_size(): return long_size() +>>> if not 'rewrap_value_nullptr_t' in dir(): +... def rewrap_value_nullptr_t(x): return x +... def rewrap_const_reference_nullptr_t(x): return x + +>>> rewrap_value_nullptr_t(None) is None +True >>> try: bool_exists = bool ... except: pass @@ -156,6 +162,9 @@ >>> rewrap_value_mutable_cstring('hello, world') 'hello, world' +>>> rewrap_const_reference_nullptr_t(None) is None +True + >>> rewrap_const_reference_bool(None) 0 >>> rewrap_const_reference_bool(0)