mirror of
https://github.com/boostorg/python.git
synced 2026-01-31 20:32:16 +00:00
implicit conversions
[SVN r13277]
This commit is contained in:
@@ -21,6 +21,9 @@ BOOST_PYTHON_DECL void* find(
|
||||
BOOST_PYTHON_DECL rvalue_stage1_data find(
|
||||
PyObject* source, rvalue_from_python_registration const*);
|
||||
|
||||
BOOST_PYTHON_DECL rvalue_from_python_registration const* find_chain(
|
||||
PyObject* source, rvalue_from_python_registration const*);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FIND_FROM_PYTHON_DWA2002223_HPP
|
||||
|
||||
50
include/boost/python/converter/implicit.hpp
Normal file
50
include/boost/python/converter/implicit.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// 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.
|
||||
#ifndef IMPLICIT_DWA2002326_HPP
|
||||
# define IMPLICIT_DWA2002326_HPP
|
||||
# include <boost/python/converter/from_python_data.hpp>
|
||||
# include <boost/python/converter/from_python_stage1_data.hpp>
|
||||
# include <boost/python/converter/registrations.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class Source, class Target>
|
||||
struct implicit
|
||||
{
|
||||
static void* convertible(PyObject* obj)
|
||||
{
|
||||
// Find a converter registration which can produce a Source
|
||||
// instance from obj
|
||||
return const_cast<rvalue_from_python_registration*>(
|
||||
find_chain(obj, rvalue_from_python_chain<Source>::value));
|
||||
}
|
||||
|
||||
static void construct(PyObject* obj, rvalue_stage1_data* data)
|
||||
{
|
||||
// This is the registration we got from the convertible step
|
||||
rvalue_from_python_registration const* registration
|
||||
= static_cast<rvalue_from_python_registration*>(data->convertible);
|
||||
|
||||
// Call the convertible function again
|
||||
rvalue_data<Source> intermediate_data(registration->convertible(obj));
|
||||
|
||||
// Use the result to construct the source type if the first
|
||||
// converter was an rvalue converter.
|
||||
if (registration->construct != 0)
|
||||
registration->construct(obj, &intermediate_data.stage1);
|
||||
|
||||
void* storage = ((rvalue_base_data<Target>*)data)->storage.bytes;
|
||||
new (storage) Target(*(Source*)intermediate_data.storage.bytes);
|
||||
|
||||
// record successful construction
|
||||
data->convertible = storage;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // IMPLICIT_DWA2002326_HPP
|
||||
28
include/boost/python/implicit.hpp
Normal file
28
include/boost/python/implicit.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
// 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.
|
||||
#ifndef IMPLICIT_DWA2002325_HPP
|
||||
# define IMPLICIT_DWA2002325_HPP
|
||||
# include <boost/type.hpp>
|
||||
# include <boost/python/converter/implicit.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class Source, class Target>
|
||||
void implicitly_convertible(boost::type<Source>* = 0, boost::type<Target>* = 0)
|
||||
{
|
||||
typedef converter::implicit<Source,Target> functions;
|
||||
|
||||
converter::registry::insert(
|
||||
&functions::convertible
|
||||
, &functions::construct
|
||||
, converter::undecorated_type_id<Target>());
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // IMPLICIT_DWA2002325_HPP
|
||||
@@ -22,7 +22,7 @@ namespace detail
|
||||
}
|
||||
|
||||
// A function generator whose static execute() function is an lvalue
|
||||
// from_python converter using the given Extractor. U is exepcted to
|
||||
// from_python converter using the given Extractor. U is expected to
|
||||
// be the actual type of the PyObject instance from which the result
|
||||
// is being extracted.
|
||||
template <class Extractor, class U>
|
||||
|
||||
@@ -29,6 +29,18 @@ BOOST_PYTHON_DECL rvalue_stage1_data find(
|
||||
return data;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL rvalue_from_python_registration const* find_chain(
|
||||
PyObject* source
|
||||
, rvalue_from_python_registration const* chain)
|
||||
{
|
||||
for (;chain != 0; chain = chain->next)
|
||||
{
|
||||
if (chain->convertible(source))
|
||||
break;
|
||||
}
|
||||
return chain;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* find(
|
||||
PyObject* source
|
||||
, lvalue_from_python_registration const* chain)
|
||||
|
||||
@@ -57,6 +57,7 @@ bpl-test test_pointer_adoption ;
|
||||
bpl-test callbacks ;
|
||||
bpl-test virtual_functions ;
|
||||
bpl-test back_reference ;
|
||||
bpl-test implicit ;
|
||||
|
||||
# --- unit tests of library components ---
|
||||
unit-test indirect_traits_test
|
||||
|
||||
37
test/implicit.cpp
Normal file
37
test/implicit.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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/class.hpp>
|
||||
#include <boost/python/implicit.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
// This test shows that a class can be wrapped "as itself" but also
|
||||
// acquire a back-reference iff has_back_reference<> is appropriately
|
||||
// specialized.
|
||||
using namespace boost::python;
|
||||
|
||||
typedef test_class<> X;
|
||||
|
||||
int x_value(X const& x)
|
||||
{
|
||||
return x.value();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(implicit_ext)
|
||||
{
|
||||
implicitly_convertible<int,X>();
|
||||
module("implicit_ext")
|
||||
.def("x_value", x_value)
|
||||
.add(
|
||||
class_<X>("X")
|
||||
.def_init(args<int>())
|
||||
.def("value", &X::value)
|
||||
.def("set", &X::set)
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
20
test/implicit.py
Normal file
20
test/implicit.py
Normal file
@@ -0,0 +1,20 @@
|
||||
'''
|
||||
>>> from implicit_ext import *
|
||||
>>> x_value(X(42))
|
||||
42
|
||||
>>> x_value(42)
|
||||
42
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
31
test/test_class.hpp
Normal file
31
test/test_class.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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.
|
||||
#ifndef TEST_CLASS_DWA2002326_HPP
|
||||
# define TEST_CLASS_DWA2002326_HPP
|
||||
# include <cassert>
|
||||
|
||||
template <int n = 0>
|
||||
struct test_class
|
||||
{
|
||||
explicit test_class(int x) : x(x), magic(7654321 + n) { ++counter; }
|
||||
test_class(test_class const& rhs) : x(rhs.x), magic(7654321 + n) { ++counter; }
|
||||
virtual ~test_class() { assert(magic == 7654321 + n); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int x) { assert(magic == 7654321 + n); this->x = x; }
|
||||
int value() const { assert(magic == 7654321 + n); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
void operator=(test_class const&);
|
||||
private:
|
||||
int x;
|
||||
long magic;
|
||||
static int counter;
|
||||
};
|
||||
|
||||
template <int n>
|
||||
int test_class<n>::counter;
|
||||
|
||||
#endif // TEST_CLASS_DWA2002326_HPP
|
||||
Reference in New Issue
Block a user