2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-22 05:22:45 +00:00

Still further rationalized conversion registry

[SVN r14462]
This commit is contained in:
Dave Abrahams
2002-07-14 23:25:56 +00:00
parent 9795a27482
commit 149c60bd2e
8 changed files with 167 additions and 177 deletions

View File

@@ -0,0 +1,58 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/arg_to_python_base.hpp>
#include <boost/python/errors.hpp>
#include <boost/python/converter/registrations.hpp>
#include <boost/python/handle.hpp>
#include <boost/python/refcount.hpp>
namespace boost { namespace python { namespace converter {
namespace
{
inline PyObject* convert_to_python(void const volatile* source, registration const& converters)
{
if (converters.to_python == 0)
{
handle<> msg(
::PyString_FromFormat(
"No to_python (by-value) converter found for C++ type: %s"
, converters.target_type.name()));
PyErr_SetObject(PyExc_TypeError, msg.get());
throw_error_already_set();
}
return source == 0
? incref(Py_None)
: converters.to_python(const_cast<void*>(source));
}
}
namespace detail
{
arg_to_python_base::arg_to_python_base(
void const volatile* source, registration const& converters)
# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140
: handle<>(converter::convert_to_python(source, converters))
# else
: m_ptr(converter::convert_to_python(source, converters))
# endif
{
}
BOOST_PYTHON_DECL void throw_no_class_registered()
{
PyErr_SetString(
PyExc_TypeError
, const_cast<char*>("class not registered for to_python type"));
throw_error_already_set();
}
}
}}} // namespace boost::python::converter

View File

@@ -1,141 +0,0 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/arg_to_python_base.hpp>
#include <boost/python/errors.hpp>
#include <boost/python/converter/find_from_python.hpp>
#include <boost/python/converter/registrations.hpp>
#include <boost/python/handle.hpp>
#include <boost/python/detail/none.hpp>
#include <boost/python/object.hpp>
namespace boost { namespace python { namespace converter {
namespace detail
{
namespace
{
inline PyObject* convert_to_python(void const volatile* source, registration const& converters)
{
if (converters.to_python == 0)
{
handle<> msg(
::PyString_FromFormat(
"No to_python (by-value) converter found for C++ type: %s"
, converters.target_type.name()));
PyErr_SetObject(PyExc_TypeError, msg.get());
throw_error_already_set();
}
return source == 0
? python::detail::none()
: converters.to_python(const_cast<void*>(source));
}
}
arg_to_python_base::arg_to_python_base(
void const volatile* source, registration const& converters)
# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140
: handle<>(convert_to_python(source, converters))
# else
: m_ptr(convert_to_python(source, converters))
# endif
{
}
BOOST_PYTHON_DECL void* callback_convert_reference(
PyObject* source
, registration const& converters)
{
handle<> holder(source);
if (source->ob_refcnt <= 2)
{
handle<> msg(
::PyString_FromFormat(
"Attempt to return dangling pointer/reference to object of type: %s"
, converters.target_type.name()));
PyErr_SetObject(PyExc_ReferenceError, msg.get());
throw_error_already_set();
}
void* result = get_lvalue_from_python(source, converters);
if (!result)
{
handle<> msg(
::PyString_FromFormat(
"No registered converter was able to extract a a C++ lvalue of type %s from this Python object of type %s"
, converters.target_type.name()
, source->ob_type->tp_name
));
PyErr_SetObject(PyExc_TypeError, msg.get());
throw_error_already_set();
}
return result;
}
BOOST_PYTHON_DECL void* callback_convert_pointer(
PyObject* source
, registration const& converters)
{
if (source == Py_None)
{
Py_DECREF(source);
return 0;
}
return callback_convert_reference(source, converters);
}
BOOST_PYTHON_DECL void throw_no_class_registered()
{
PyErr_SetString(
PyExc_TypeError
, const_cast<char*>("class not registered for to_python type"));
throw_error_already_set();
}
BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_from_python_stage1_data& data, void* storage)
{
handle<> holder(src);
void const* converters_ = data.convertible;
registration const& converters = *static_cast<registration const*>(converters_);
data = rvalue_from_python_stage1(src, converters);
if (!data.convertible)
{
handle<> msg(
::PyString_FromFormat(
"No registered converter was able to produce a C++ lvalue of type %s from this Python object of type %s"
, converters.target_type.name()
, src->ob_type->tp_name
));
PyErr_SetObject(PyExc_TypeError, msg.get());
throw_error_already_set();
}
// If a construct function was registered (i.e. we found an
// rvalue conversion), call it now.
if (data.construct != 0)
data.construct(src, &data);
// Return the address of the resulting C++ object
return data.convertible;
}
BOOST_PYTHON_DECL void absorb_result(PyObject* o)
{
Py_DECREF(expect_non_null(o));
}
}
}}} // namespace boost::python::converter

View File

@@ -4,11 +4,10 @@
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/find_from_python.hpp>
#include <boost/python/converter/from_python.hpp>
#include <boost/python/converter/registrations.hpp>
#include <boost/python/converter/rvalue_from_python_data.hpp>
#include <boost/python/converter/registrations.hpp>
#include <boost/python/detail/wrap_python.hpp>
#include <boost/python/handle.hpp>
#include <vector>
#include <algorithm>
@@ -35,6 +34,37 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
return data;
}
BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
PyObject* src, rvalue_from_python_stage1_data& data, void* storage)
{
handle<> holder(src);
void const* converters_ = data.convertible;
registration const& converters = *static_cast<registration const*>(converters_);
data = rvalue_from_python_stage1(src, converters);
if (!data.convertible)
{
handle<> msg(
::PyString_FromFormat(
"No registered converter was able to produce a C++ lvalue of type %s from this Python object of type %s"
, converters.target_type.name()
, src->ob_type->tp_name
));
PyErr_SetObject(PyExc_TypeError, msg.get());
throw_error_already_set();
}
// If a construct function was registered (i.e. we found an
// rvalue conversion), call it now.
if (data.construct != 0)
data.construct(src, &data);
// Return the address of the resulting C++ object
return data.convertible;
}
BOOST_PYTHON_DECL void* get_lvalue_from_python(
PyObject* source
, registration const& converters)
@@ -100,4 +130,62 @@ BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain(
return chain;
}
BOOST_PYTHON_DECL void* reference_from_python(
PyObject* source
, registration const& converters)
{
handle<> holder(source);
if (source->ob_refcnt <= 2)
{
handle<> msg(
::PyString_FromFormat(
"Attempt to return dangling pointer/reference to object of type: %s"
, converters.target_type.name()));
PyErr_SetObject(PyExc_ReferenceError, msg.get());
throw_error_already_set();
}
void* result = get_lvalue_from_python(source, converters);
if (!result)
{
handle<> msg(
::PyString_FromFormat(
"No registered converter was able to extract a a C++ lvalue of type %s from this Python object of type %s"
, converters.target_type.name()
, source->ob_type->tp_name
));
PyErr_SetObject(PyExc_TypeError, msg.get());
throw_error_already_set();
}
return result;
}
BOOST_PYTHON_DECL void* pointer_from_python(
PyObject* source
, registration const& converters)
{
if (source == Py_None)
{
Py_DECREF(source);
return 0;
}
return reference_from_python(source, converters);
}
BOOST_PYTHON_DECL void throw_no_class_registered()
{
PyErr_SetString(
PyExc_TypeError
, const_cast<char*>("class not registered for to_python type"));
throw_error_already_set();
}
BOOST_PYTHON_DECL void void_from_python(PyObject* o)
{
Py_DECREF(expect_non_null(o));
}
}}} // namespace boost::python::converter