mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 04:22:16 +00:00
Add support for std::shared_ptr.
This commit is contained in:
@@ -1,19 +1,21 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Copyright Stefan Seefeld 2016.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef REGISTERED_DWA2002710_HPP
|
||||
# define REGISTERED_DWA2002710_HPP
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/registrations.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/type_traits/is_void.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/type.hpp>
|
||||
|
||||
#ifndef boost_python_converter_registered_hpp_
|
||||
#define boost_python_converter_registered_hpp_
|
||||
|
||||
#include <boost/python/type_id.hpp>
|
||||
#include <boost/python/converter/registry.hpp>
|
||||
#include <boost/python/converter/registrations.hpp>
|
||||
#include <boost/type_traits/transform_traits.hpp>
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/type.hpp>
|
||||
#include <memory>
|
||||
#if defined(BOOST_PYTHON_TRACE_REGISTRY) \
|
||||
|| defined(BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND)
|
||||
# include <iostream>
|
||||
@@ -75,7 +77,16 @@ namespace detail
|
||||
{
|
||||
registry::lookup_shared_ptr(type_id<shared_ptr<T> >());
|
||||
}
|
||||
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template <class T>
|
||||
inline void
|
||||
register_shared_ptr0(std::shared_ptr<T>*)
|
||||
{
|
||||
registry::lookup_shared_ptr(type_id<std::shared_ptr<T> >());
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline void
|
||||
register_shared_ptr1(T const volatile*)
|
||||
@@ -112,4 +123,4 @@ namespace detail
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // REGISTERED_DWA2002710_HPP
|
||||
#endif
|
||||
|
||||
@@ -1,63 +1,65 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Copyright Stefan Seefeld 2016.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
|
||||
# define SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
|
||||
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <boost/python/converter/shared_ptr_deleter.hpp>
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
# include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
# include <boost/python/converter/registered.hpp>
|
||||
#ifndef boost_python_converter_shared_ptr_from_python_hpp_
|
||||
#define boost_python_converter_shared_ptr_from_python_hpp_
|
||||
|
||||
#include <boost/python/handle.hpp>
|
||||
#include <boost/python/converter/shared_ptr_deleter.hpp>
|
||||
#include <boost/python/converter/from_python.hpp>
|
||||
#include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
#include <boost/python/converter/registered.hpp>
|
||||
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||
# include <boost/python/converter/pytype_function.hpp>
|
||||
#endif
|
||||
# include <boost/shared_ptr.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T>
|
||||
template <class T, template <typename> class SP>
|
||||
struct shared_ptr_from_python
|
||||
{
|
||||
shared_ptr_from_python()
|
||||
{
|
||||
converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >()
|
||||
shared_ptr_from_python()
|
||||
{
|
||||
converter::registry::insert(&convertible, &construct, type_id<SP<T> >()
|
||||
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||
, &converter::expected_from_python_type_direct<T>::get_pytype
|
||||
, &converter::expected_from_python_type_direct<T>::get_pytype
|
||||
#endif
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
static void* convertible(PyObject* p)
|
||||
{
|
||||
if (p == Py_None)
|
||||
return p;
|
||||
static void* convertible(PyObject* p)
|
||||
{
|
||||
if (p == Py_None)
|
||||
return p;
|
||||
|
||||
return converter::get_lvalue_from_python(p, registered<T>::converters);
|
||||
}
|
||||
return converter::get_lvalue_from_python(p, registered<T>::converters);
|
||||
}
|
||||
|
||||
static void construct(PyObject* source, rvalue_from_python_stage1_data* data)
|
||||
static void construct(PyObject* source, rvalue_from_python_stage1_data* data)
|
||||
{
|
||||
void* const storage = ((converter::rvalue_from_python_storage<SP<T> >*)data)->storage.bytes;
|
||||
// Deal with the "None" case.
|
||||
if (data->convertible == source)
|
||||
new (storage) SP<T>();
|
||||
else
|
||||
{
|
||||
void* const storage = ((converter::rvalue_from_python_storage<shared_ptr<T> >*)data)->storage.bytes;
|
||||
// Deal with the "None" case.
|
||||
if (data->convertible == source)
|
||||
new (storage) shared_ptr<T>();
|
||||
else
|
||||
{
|
||||
boost::shared_ptr<void> hold_convertible_ref_count(
|
||||
(void*)0, shared_ptr_deleter(handle<>(borrowed(source))) );
|
||||
// use aliasing constructor
|
||||
new (storage) shared_ptr<T>(
|
||||
hold_convertible_ref_count,
|
||||
static_cast<T*>(data->convertible));
|
||||
}
|
||||
|
||||
data->convertible = storage;
|
||||
SP<void> hold_convertible_ref_count(
|
||||
(void*)0, shared_ptr_deleter(handle<>(borrowed(source))) );
|
||||
// use aliasing constructor
|
||||
new (storage) SP<T>(hold_convertible_ref_count,
|
||||
static_cast<T*>(data->convertible));
|
||||
}
|
||||
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
// Copyright David Abrahams 2003.
|
||||
// Copyright Stefan Seefeld 2016.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef SHARED_PTR_TO_PYTHON_DWA2003224_HPP
|
||||
# define SHARED_PTR_TO_PYTHON_DWA2003224_HPP
|
||||
|
||||
# include <boost/python/refcount.hpp>
|
||||
# include <boost/python/converter/shared_ptr_deleter.hpp>
|
||||
# include <boost/shared_ptr.hpp>
|
||||
# include <boost/get_pointer.hpp>
|
||||
#ifndef boost_python_converter_shared_ptr_to_python_hpp_
|
||||
#define boost_python_converter_shared_ptr_to_python_hpp_
|
||||
|
||||
#include <boost/python/refcount.hpp>
|
||||
#include <boost/python/converter/shared_ptr_deleter.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/get_pointer.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
@@ -23,6 +25,19 @@ PyObject* shared_ptr_to_python(shared_ptr<T> const& x)
|
||||
return converter::registered<shared_ptr<T> const&>::converters.to_python(&x);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template <class T>
|
||||
PyObject* shared_ptr_to_python(std::shared_ptr<T> const& x)
|
||||
{
|
||||
if (!x)
|
||||
return python::detail::none();
|
||||
else if (shared_ptr_deleter* d = std::get_deleter<shared_ptr_deleter>(x))
|
||||
return incref(get_pointer(d->owner));
|
||||
else
|
||||
return converter::registered<std::shared_ptr<T> const&>::converters.to_python(&x);
|
||||
}
|
||||
#endif
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // SHARED_PTR_TO_PYTHON_DWA2003224_HPP
|
||||
#endif
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
// Copyright David Abrahams 2003.
|
||||
// Copyright Stefan Seefeld 2016.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef IS_SHARED_PTR_DWA2003224_HPP
|
||||
# define IS_SHARED_PTR_DWA2003224_HPP
|
||||
|
||||
# include <boost/python/detail/is_xxx.hpp>
|
||||
# include <boost/shared_ptr.hpp>
|
||||
#ifndef boost_python_detail_is_shared_ptr_hpp_
|
||||
#define boost_python_detail_is_shared_ptr_hpp_
|
||||
|
||||
#include <boost/python/detail/is_xxx.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
BOOST_PYTHON_IS_XXX_DEF(shared_ptr, shared_ptr, 1)
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template <typename T>
|
||||
struct is_shared_ptr<std::shared_ptr<T> > : std::true_type {};
|
||||
#endif
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // IS_SHARED_PTR_DWA2003224_HPP
|
||||
#endif
|
||||
|
||||
@@ -1,17 +1,28 @@
|
||||
// Copyright David Abrahams 2003.
|
||||
// Copyright Stefan Seefeld 2016.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef VALUE_IS_SHARED_PTR_DWA2003224_HPP
|
||||
# define VALUE_IS_SHARED_PTR_DWA2003224_HPP
|
||||
|
||||
# include <boost/python/detail/value_is_xxx.hpp>
|
||||
# include <boost/shared_ptr.hpp>
|
||||
#ifndef boost_python_detail_value_is_shared_ptr_hpp_
|
||||
#define boost_python_detail_value_is_shared_ptr_hpp_
|
||||
|
||||
#include <boost/python/detail/value_is_xxx.hpp>
|
||||
#include <boost/python/detail/is_shared_ptr.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
BOOST_PYTHON_VALUE_IS_XXX_DEF(shared_ptr, shared_ptr, 1)
|
||||
|
||||
template <class X_>
|
||||
struct value_is_shared_ptr
|
||||
{
|
||||
static bool const value = is_shared_ptr<typename remove_cv<
|
||||
typename remove_reference<X_>
|
||||
::type>
|
||||
::type>
|
||||
::value;
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // VALUE_IS_SHARED_PTR_DWA2003224_HPP
|
||||
|
||||
@@ -1,43 +1,46 @@
|
||||
// Copyright David Abrahams 2004. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef CLASS_METADATA_DWA2004719_HPP
|
||||
# define CLASS_METADATA_DWA2004719_HPP
|
||||
# include <boost/python/converter/shared_ptr_from_python.hpp>
|
||||
// Copyright David Abrahams 2004.
|
||||
// Copyright Stefan Seefeld 2016.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# include <boost/python/object/inheritance.hpp>
|
||||
# include <boost/python/object/class_wrapper.hpp>
|
||||
# include <boost/python/object/make_instance.hpp>
|
||||
# include <boost/python/object/value_holder.hpp>
|
||||
# include <boost/python/object/pointer_holder.hpp>
|
||||
# include <boost/python/object/make_ptr_instance.hpp>
|
||||
#ifndef boost_python_object_class_metadata_hpp_
|
||||
#define boost_python_object_class_metadata_hpp_
|
||||
|
||||
# include <boost/python/detail/force_instantiate.hpp>
|
||||
# include <boost/python/detail/not_specified.hpp>
|
||||
#include <boost/python/converter/shared_ptr_from_python.hpp>
|
||||
#include <boost/python/object/inheritance.hpp>
|
||||
#include <boost/python/object/class_wrapper.hpp>
|
||||
#include <boost/python/object/make_instance.hpp>
|
||||
#include <boost/python/object/value_holder.hpp>
|
||||
#include <boost/python/object/pointer_holder.hpp>
|
||||
#include <boost/python/object/make_ptr_instance.hpp>
|
||||
|
||||
# include <boost/python/has_back_reference.hpp>
|
||||
# include <boost/python/bases.hpp>
|
||||
#include <boost/python/detail/force_instantiate.hpp>
|
||||
#include <boost/python/detail/not_specified.hpp>
|
||||
|
||||
# include <boost/type_traits/add_pointer.hpp>
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
# include <boost/type_traits/is_polymorphic.hpp>
|
||||
#include <boost/python/has_back_reference.hpp>
|
||||
#include <boost/python/bases.hpp>
|
||||
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/eval_if.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/mpl/placeholders.hpp>
|
||||
# include <boost/mpl/single_view.hpp>
|
||||
#include <boost/type_traits/add_pointer.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_polymorphic.hpp>
|
||||
|
||||
# include <boost/mpl/assert.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/mpl/single_view.hpp>
|
||||
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# include <boost/noncopyable.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
@@ -80,18 +83,22 @@ struct register_base_of
|
||||
// Preamble of register_class. Also used for callback classes, which
|
||||
// need some registration of their own.
|
||||
//
|
||||
|
||||
template <class T, class Bases>
|
||||
inline void register_shared_ptr_from_python_and_casts(T*, Bases)
|
||||
{
|
||||
// Constructor performs registration
|
||||
python::detail::force_instantiate(converter::shared_ptr_from_python<T>());
|
||||
// Constructor performs registration
|
||||
python::detail::force_instantiate(converter::shared_ptr_from_python<T, boost::shared_ptr>());
|
||||
#if __cplusplus >= 201103L
|
||||
python::detail::force_instantiate(converter::shared_ptr_from_python<T, std::shared_ptr>());
|
||||
#endif
|
||||
|
||||
//
|
||||
// register all up/downcasts here. We're using the alternate
|
||||
// interface to mpl::for_each to avoid an MSVC 6 bug.
|
||||
//
|
||||
register_dynamic_id<T>();
|
||||
mpl::for_each(register_base_of<T>(), (Bases*)0, (add_pointer<mpl::_>*)0);
|
||||
//
|
||||
// register all up/downcasts here. We're using the alternate
|
||||
// interface to mpl::for_each to avoid an MSVC 6 bug.
|
||||
//
|
||||
register_dynamic_id<T>();
|
||||
mpl::for_each(register_base_of<T>(), (Bases*)0, (add_pointer<mpl::_>*)0);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -220,8 +227,7 @@ struct class_metadata
|
||||
template <class T2, class Callback>
|
||||
inline static void register_aux2(T2*, Callback)
|
||||
{
|
||||
objects::register_shared_ptr_from_python_and_casts((T2*)0, bases());
|
||||
|
||||
objects::register_shared_ptr_from_python_and_casts((T2*)0, bases());
|
||||
class_metadata::maybe_register_callback_class((T2*)0, Callback());
|
||||
|
||||
class_metadata::maybe_register_class_to_python((T2*)0, is_noncopyable());
|
||||
@@ -282,9 +288,8 @@ struct class_metadata
|
||||
template <class T2>
|
||||
inline static void maybe_register_callback_class(T2*, mpl::true_)
|
||||
{
|
||||
objects::register_shared_ptr_from_python_and_casts(
|
||||
objects::register_shared_ptr_from_python_and_casts(
|
||||
(wrapped*)0, mpl::single_view<T2>());
|
||||
|
||||
// explicit qualification of type_id makes msvc6 happy
|
||||
objects::copy_class_object(python::type_id<T2>(), python::type_id<wrapped>());
|
||||
}
|
||||
@@ -292,4 +297,4 @@ struct class_metadata
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
#endif // CLASS_METADATA_DWA2004719_HPP
|
||||
#endif
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Copyright Stefan Seefeld 2016.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef TO_PYTHON_VALUE_DWA200221_HPP
|
||||
# define TO_PYTHON_VALUE_DWA200221_HPP
|
||||
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
#ifndef boost_python_to_python_value_hpp_
|
||||
#define boost_python_to_python_value_hpp_
|
||||
|
||||
# include <boost/python/refcount.hpp>
|
||||
# include <boost/python/tag.hpp>
|
||||
# include <boost/python/handle.hpp>
|
||||
#include <boost/python/detail/prefix.hpp>
|
||||
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/registered.hpp>
|
||||
# include <boost/python/converter/builtin_converters.hpp>
|
||||
# include <boost/python/converter/object_manager.hpp>
|
||||
# include <boost/python/converter/shared_ptr_to_python.hpp>
|
||||
#include <boost/python/refcount.hpp>
|
||||
#include <boost/python/tag.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
|
||||
# include <boost/python/detail/value_is_shared_ptr.hpp>
|
||||
# include <boost/python/detail/value_arg.hpp>
|
||||
#include <boost/python/converter/registry.hpp>
|
||||
#include <boost/python/converter/registered.hpp>
|
||||
#include <boost/python/converter/builtin_converters.hpp>
|
||||
#include <boost/python/converter/object_manager.hpp>
|
||||
#include <boost/python/converter/shared_ptr_to_python.hpp>
|
||||
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
#include <boost/python/detail/value_is_shared_ptr.hpp>
|
||||
#include <boost/python/detail/value_arg.hpp>
|
||||
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
# include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/transform_traits.hpp>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
@@ -114,10 +116,16 @@ struct object_manager_get_pytype<true>
|
||||
BOOST_STATIC_CONSTANT(bool, uses_registry = false);
|
||||
private:
|
||||
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||
template <class U>
|
||||
PyTypeObject const* get_pytype(boost::type<shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
|
||||
template <class U>
|
||||
PyTypeObject const* get_pytype(boost::type<const shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
|
||||
template <class U>
|
||||
PyTypeObject const* get_pytype(boost::type<shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
|
||||
template <class U>
|
||||
PyTypeObject const* get_pytype(boost::type<const shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
|
||||
# if __cplusplus >= 201103L
|
||||
template <class U>
|
||||
PyTypeObject const* get_pytype(boost::type<std::shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
|
||||
template <class U>
|
||||
PyTypeObject const* get_pytype(boost::type<const std::shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
}
|
||||
@@ -168,4 +176,4 @@ namespace detail
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // TO_PYTHON_VALUE_DWA200221_HPP
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,7 @@ for test in [('injected',),
|
||||
('properties',),
|
||||
('return_arg',),
|
||||
('staticmethod',),
|
||||
('shared_ptr',),
|
||||
('boost_shared_ptr',),
|
||||
('enable_shared_from_this',),
|
||||
('andreas_beyer',),
|
||||
('polymorphism',),
|
||||
@@ -94,6 +94,7 @@ for test in [('injected',),
|
||||
|
||||
if env['CXX11']:
|
||||
for test in [
|
||||
('shared_ptr',),
|
||||
]:
|
||||
tests+=env.BPLTest(*test)
|
||||
else:
|
||||
|
||||
20
test/boost_shared_ptr.cpp
Normal file
20
test/boost_shared_ptr.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Copyright Stefan Seefeld 2016.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/call_method.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
using boost::shared_ptr;
|
||||
#define MODULE boost_shared_ptr_ext
|
||||
|
||||
#include "shared_ptr.hpp"
|
||||
#include "module_tail.cpp"
|
||||
|
||||
130
test/boost_shared_ptr.py
Normal file
130
test/boost_shared_ptr.py
Normal file
@@ -0,0 +1,130 @@
|
||||
# Copyright David Abrahams 2004. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
'''
|
||||
>>> from boost_shared_ptr_ext import *
|
||||
|
||||
Test that shared_ptr<Derived> can be converted to shared_ptr<Base>
|
||||
|
||||
>>> Y.store(YYY(42))
|
||||
|
||||
>>> x = X(17)
|
||||
>>> null_x = null(x)
|
||||
>>> null_x # should be None
|
||||
>>> identity(null_x) # should also be None
|
||||
|
||||
>>> a = New(1)
|
||||
>>> A.call_f(a)
|
||||
1
|
||||
>>> New(0)
|
||||
|
||||
>>> type(factory(3))
|
||||
<class 'boost_shared_ptr_ext.Y'>
|
||||
>>> type(factory(42))
|
||||
<class 'boost_shared_ptr_ext.YY'>
|
||||
|
||||
>>> class P(Z):
|
||||
... def v(self):
|
||||
... return -Z.v(self);
|
||||
... def __del__(self):
|
||||
... print('bye')
|
||||
...
|
||||
>>> p = P(12)
|
||||
>>> p.value()
|
||||
12
|
||||
>>> p.v()
|
||||
-12
|
||||
>>> look(p)
|
||||
12
|
||||
>>> try: modify(p)
|
||||
... except TypeError: pass
|
||||
... else: 'print(expected a TypeError)'
|
||||
>>> look(None)
|
||||
-1
|
||||
>>> store(p)
|
||||
>>> del p
|
||||
>>> Z.get().v()
|
||||
-12
|
||||
>>> Z.count()
|
||||
1
|
||||
>>> Z.look_store()
|
||||
12
|
||||
>>> Z.release()
|
||||
bye
|
||||
>>> Z.count()
|
||||
0
|
||||
|
||||
>>> z = Z(13)
|
||||
>>> z.value()
|
||||
13
|
||||
>>> z.v()
|
||||
13
|
||||
>>> try: modify(z)
|
||||
... except TypeError: pass
|
||||
... else: 'print(expected a TypeError)'
|
||||
|
||||
>>> Z.get() # should be None
|
||||
>>> store(z)
|
||||
>>> assert Z.get() is z # show that deleter introspection works
|
||||
>>> del z
|
||||
>>> Z.get().value()
|
||||
13
|
||||
>>> Z.count()
|
||||
1
|
||||
>>> Z.look_store()
|
||||
13
|
||||
>>> Z.release()
|
||||
>>> Z.count()
|
||||
0
|
||||
|
||||
>>> x = X(17)
|
||||
>>> x.value()
|
||||
17
|
||||
>>> look(x)
|
||||
17
|
||||
>>> try: modify(x)
|
||||
... except TypeError: pass
|
||||
... else: 'print(expected a TypeError)'
|
||||
>>> look(None)
|
||||
-1
|
||||
>>> store(x)
|
||||
>>> del x
|
||||
>>> X.count()
|
||||
1
|
||||
>>> X.look_store()
|
||||
17
|
||||
>>> X.release()
|
||||
>>> X.count()
|
||||
0
|
||||
|
||||
|
||||
>>> y = Y(19)
|
||||
>>> y.value()
|
||||
19
|
||||
>>> modify(y)
|
||||
>>> look(y)
|
||||
-1
|
||||
>>> store(Y(23))
|
||||
>>> Y.count()
|
||||
1
|
||||
>>> Y.look_store()
|
||||
23
|
||||
>>> Y.release()
|
||||
>>> Y.count()
|
||||
0
|
||||
'''
|
||||
|
||||
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
|
||||
status = run()[0]
|
||||
if (status == 0): print("Done.")
|
||||
sys.exit(status)
|
||||
@@ -1,4 +1,5 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Copyright Stefan Seefeld 2016.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -8,210 +9,11 @@
|
||||
#include <boost/python/call_method.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace boost::python;
|
||||
using boost::shared_ptr;
|
||||
|
||||
typedef test_class<> X;
|
||||
typedef test_class<1> Y;
|
||||
|
||||
template <class T>
|
||||
struct functions
|
||||
{
|
||||
static int look(shared_ptr<T> const& x)
|
||||
{
|
||||
return (x.get()) ? x->value() : -1;
|
||||
}
|
||||
|
||||
static void store(shared_ptr<T> x)
|
||||
{
|
||||
storage = x;
|
||||
}
|
||||
|
||||
static void release_store()
|
||||
{
|
||||
store(shared_ptr<T>());
|
||||
}
|
||||
|
||||
static void modify(shared_ptr<T>& x)
|
||||
{
|
||||
x.reset();
|
||||
}
|
||||
|
||||
static shared_ptr<T> get() { return storage; }
|
||||
static shared_ptr<T> &get1() { return storage; }
|
||||
|
||||
static int look_store()
|
||||
{
|
||||
return look(get());
|
||||
}
|
||||
|
||||
template <class C>
|
||||
static void expose(C const& c)
|
||||
{
|
||||
def("look", &look);
|
||||
def("store", &store);
|
||||
def("modify", &modify);
|
||||
def("identity", &identity);
|
||||
def("null", &null);
|
||||
|
||||
const_cast<C&>(c)
|
||||
.def("look", &look)
|
||||
.staticmethod("look")
|
||||
.def("store", &store)
|
||||
.staticmethod("store")
|
||||
.def("modify", &modify)
|
||||
.staticmethod("modify")
|
||||
.def("look_store", &look_store)
|
||||
.staticmethod("look_store")
|
||||
.def("identity", &identity)
|
||||
.staticmethod("identity")
|
||||
.def("null", &null)
|
||||
.staticmethod("null")
|
||||
.def("get1", &get1, return_internal_reference<>())
|
||||
.staticmethod("get1")
|
||||
.def("get", &get)
|
||||
.staticmethod("get")
|
||||
.def("count", &T::count)
|
||||
.staticmethod("count")
|
||||
.def("release", &release_store)
|
||||
.staticmethod("release")
|
||||
;
|
||||
}
|
||||
|
||||
static shared_ptr<T> identity(shared_ptr<T> x) { return x; }
|
||||
static shared_ptr<T> null(T const&) { return shared_ptr<T>(); }
|
||||
|
||||
|
||||
static shared_ptr<T> storage;
|
||||
};
|
||||
|
||||
template <class T> shared_ptr<T> functions<T>::storage;
|
||||
|
||||
struct Z : test_class<2>
|
||||
{
|
||||
Z(int x) : test_class<2>(x) {}
|
||||
virtual int v() { return this->value(); }
|
||||
};
|
||||
|
||||
struct ZWrap : Z
|
||||
{
|
||||
ZWrap(PyObject* self, int x)
|
||||
: Z(x), m_self(self) {}
|
||||
|
||||
|
||||
virtual int v() { return call_method<int>(m_self, "v"); }
|
||||
int default_v() { return Z::v(); }
|
||||
|
||||
|
||||
PyObject* m_self;
|
||||
};
|
||||
|
||||
struct YY : Y
|
||||
{
|
||||
YY(int n) : Y(n) {}
|
||||
};
|
||||
|
||||
struct YYY : Y
|
||||
{
|
||||
YYY(int n) : Y(n) {}
|
||||
};
|
||||
|
||||
shared_ptr<Y> factory(int n)
|
||||
{
|
||||
return shared_ptr<Y>(n < 42 ? new Y(n) : new YY(n));
|
||||
}
|
||||
|
||||
// regressions from Nicodemus
|
||||
struct A
|
||||
{
|
||||
virtual ~A() {}; // silence compiler warnings
|
||||
virtual int f() = 0;
|
||||
static int call_f(shared_ptr<A>& a) { return a->f(); }
|
||||
};
|
||||
|
||||
struct B: A
|
||||
{
|
||||
int f() { return 1; }
|
||||
};
|
||||
|
||||
boost::shared_ptr<A> New(bool make)
|
||||
{
|
||||
return boost::shared_ptr<A>( make ? new B() : 0 );
|
||||
}
|
||||
|
||||
struct A_Wrapper: A
|
||||
{
|
||||
A_Wrapper(PyObject* self_):
|
||||
A(), self(self_) {}
|
||||
|
||||
int f() {
|
||||
return call_method< int >(self, "f");
|
||||
}
|
||||
|
||||
PyObject* self;
|
||||
};
|
||||
|
||||
// ------
|
||||
|
||||
// from Neal Becker
|
||||
|
||||
struct Test {
|
||||
boost::shared_ptr<X> x;
|
||||
};
|
||||
// ------
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(shared_ptr_ext)
|
||||
{
|
||||
class_<A, boost::shared_ptr<A_Wrapper>, boost::noncopyable>("A")
|
||||
.def("call_f", &A::call_f)
|
||||
.staticmethod("call_f")
|
||||
;
|
||||
|
||||
// This is the ugliness required to register a to-python converter
|
||||
// for shared_ptr<A>.
|
||||
objects::class_value_wrapper<
|
||||
shared_ptr<A>
|
||||
, objects::make_ptr_instance<A, objects::pointer_holder<shared_ptr<A>,A> >
|
||||
>();
|
||||
|
||||
def("New", &New);
|
||||
|
||||
def("factory", factory);
|
||||
|
||||
functions<X>::expose(
|
||||
class_<X, boost::noncopyable>("X", init<int>())
|
||||
.def("value", &X::value)
|
||||
);
|
||||
|
||||
functions<Y>::expose(
|
||||
class_<Y, boost::shared_ptr<Y> >("Y", init<int>())
|
||||
.def("value", &Y::value)
|
||||
);
|
||||
|
||||
class_<YY, bases<Y>, boost::noncopyable>("YY", init<int>())
|
||||
;
|
||||
|
||||
class_<YYY, shared_ptr<YYY>, bases<Y> >("YYY", init<int>())
|
||||
;
|
||||
|
||||
functions<Z>::expose(
|
||||
class_<Z, ZWrap>("Z", init<int>())
|
||||
.def("value", &Z::value)
|
||||
.def("v", &Z::v, &ZWrap::default_v)
|
||||
);
|
||||
|
||||
// from Neal Becker
|
||||
class_<Test> ("Test")
|
||||
.def_readonly ("x", &Test::x, "x")
|
||||
;
|
||||
// ------
|
||||
}
|
||||
using std::shared_ptr;
|
||||
#define MODULE shared_ptr_ext
|
||||
|
||||
#include "shared_ptr.hpp"
|
||||
#include "module_tail.cpp"
|
||||
|
||||
|
||||
206
test/shared_ptr.hpp
Normal file
206
test/shared_ptr.hpp
Normal file
@@ -0,0 +1,206 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Copyright Stefan Seefeld 2016.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "test_class.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
typedef test_class<> X;
|
||||
typedef test_class<1> Y;
|
||||
|
||||
template <class T>
|
||||
struct functions
|
||||
{
|
||||
static int look(shared_ptr<T> const& x)
|
||||
{
|
||||
return (x.get()) ? x->value() : -1;
|
||||
}
|
||||
|
||||
static void store(shared_ptr<T> x)
|
||||
{
|
||||
storage = x;
|
||||
}
|
||||
|
||||
static void release_store()
|
||||
{
|
||||
store(shared_ptr<T>());
|
||||
}
|
||||
|
||||
static void modify(shared_ptr<T>& x)
|
||||
{
|
||||
x.reset();
|
||||
}
|
||||
|
||||
static shared_ptr<T> get() { return storage; }
|
||||
static shared_ptr<T> &get1() { return storage; }
|
||||
|
||||
static int look_store()
|
||||
{
|
||||
return look(get());
|
||||
}
|
||||
|
||||
template <class C>
|
||||
static void expose(C const& c)
|
||||
{
|
||||
def("look", &look);
|
||||
def("store", &store);
|
||||
def("modify", &modify);
|
||||
def("identity", &identity);
|
||||
def("null", &null);
|
||||
|
||||
const_cast<C&>(c)
|
||||
.def("look", &look)
|
||||
.staticmethod("look")
|
||||
.def("store", &store)
|
||||
.staticmethod("store")
|
||||
.def("modify", &modify)
|
||||
.staticmethod("modify")
|
||||
.def("look_store", &look_store)
|
||||
.staticmethod("look_store")
|
||||
.def("identity", &identity)
|
||||
.staticmethod("identity")
|
||||
.def("null", &null)
|
||||
.staticmethod("null")
|
||||
.def("get1", &get1, return_internal_reference<>())
|
||||
.staticmethod("get1")
|
||||
.def("get", &get)
|
||||
.staticmethod("get")
|
||||
.def("count", &T::count)
|
||||
.staticmethod("count")
|
||||
.def("release", &release_store)
|
||||
.staticmethod("release")
|
||||
;
|
||||
}
|
||||
|
||||
static shared_ptr<T> identity(shared_ptr<T> x) { return x; }
|
||||
static shared_ptr<T> null(T const&) { return shared_ptr<T>(); }
|
||||
|
||||
|
||||
static shared_ptr<T> storage;
|
||||
};
|
||||
|
||||
template <class T> shared_ptr<T> functions<T>::storage;
|
||||
|
||||
struct Z : test_class<2>
|
||||
{
|
||||
Z(int x) : test_class<2>(x) {}
|
||||
virtual int v() { return this->value(); }
|
||||
};
|
||||
|
||||
struct ZWrap : Z
|
||||
{
|
||||
ZWrap(PyObject* self, int x)
|
||||
: Z(x), m_self(self) {}
|
||||
|
||||
|
||||
virtual int v() { return call_method<int>(m_self, "v"); }
|
||||
int default_v() { return Z::v(); }
|
||||
|
||||
|
||||
PyObject* m_self;
|
||||
};
|
||||
|
||||
struct YY : Y
|
||||
{
|
||||
YY(int n) : Y(n) {}
|
||||
};
|
||||
|
||||
struct YYY : Y
|
||||
{
|
||||
YYY(int n) : Y(n) {}
|
||||
};
|
||||
|
||||
shared_ptr<Y> factory(int n)
|
||||
{
|
||||
return shared_ptr<Y>(n < 42 ? new Y(n) : new YY(n));
|
||||
}
|
||||
|
||||
// regressions from Nicodemus
|
||||
struct A
|
||||
{
|
||||
virtual ~A() {}; // silence compiler warnings
|
||||
virtual int f() = 0;
|
||||
static int call_f(shared_ptr<A>& a) { return a->f(); }
|
||||
};
|
||||
|
||||
struct B: A
|
||||
{
|
||||
int f() { return 1; }
|
||||
};
|
||||
|
||||
shared_ptr<A> New(bool make)
|
||||
{
|
||||
return shared_ptr<A>( make ? new B() : 0 );
|
||||
}
|
||||
|
||||
struct A_Wrapper: A
|
||||
{
|
||||
A_Wrapper(PyObject* self_):
|
||||
A(), self(self_) {}
|
||||
|
||||
int f() {
|
||||
return call_method< int >(self, "f");
|
||||
}
|
||||
|
||||
PyObject* self;
|
||||
};
|
||||
|
||||
// ------
|
||||
|
||||
// from Neal Becker
|
||||
|
||||
struct Test {
|
||||
shared_ptr<X> x;
|
||||
};
|
||||
// ------
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(MODULE)
|
||||
{
|
||||
class_<A, shared_ptr<A_Wrapper>, boost::noncopyable>("A")
|
||||
.def("call_f", &A::call_f)
|
||||
.staticmethod("call_f")
|
||||
;
|
||||
|
||||
// This is the ugliness required to register a to-python converter
|
||||
// for shared_ptr<A>.
|
||||
objects::class_value_wrapper<
|
||||
shared_ptr<A>
|
||||
, objects::make_ptr_instance<A, objects::pointer_holder<shared_ptr<A>,A> >
|
||||
>();
|
||||
|
||||
def("New", &New);
|
||||
|
||||
def("factory", factory);
|
||||
|
||||
functions<X>::expose(
|
||||
class_<X, boost::noncopyable>("X", init<int>())
|
||||
.def("value", &X::value)
|
||||
);
|
||||
|
||||
functions<Y>::expose(
|
||||
class_<Y, shared_ptr<Y> >("Y", init<int>())
|
||||
.def("value", &Y::value)
|
||||
);
|
||||
|
||||
class_<YY, bases<Y>, boost::noncopyable>("YY", init<int>())
|
||||
;
|
||||
|
||||
class_<YYY, shared_ptr<YYY>, bases<Y> >("YYY", init<int>())
|
||||
;
|
||||
|
||||
functions<Z>::expose(
|
||||
class_<Z, ZWrap>("Z", init<int>())
|
||||
.def("value", &Z::value)
|
||||
.def("v", &Z::v, &ZWrap::default_v)
|
||||
);
|
||||
|
||||
// from Neal Becker
|
||||
class_<Test> ("Test")
|
||||
.def_readonly ("x", &Test::x, "x")
|
||||
;
|
||||
// ------
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
>>> from shared_ptr_ext import *
|
||||
|
||||
Test that shared_ptr<Derived> can be converted to shared_ptr<Base>
|
||||
|
||||
|
||||
>>> Y.store(YYY(42))
|
||||
|
||||
>>> x = X(17)
|
||||
@@ -121,7 +121,7 @@ def run(args = None):
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("running...")
|
||||
import sys
|
||||
|
||||
Reference in New Issue
Block a user