Skip to content

Commit

Permalink
Add support for std::shared_ptr.
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanseefeld committed Sep 27, 2016
1 parent 5029273 commit 97e4b34
Show file tree
Hide file tree
Showing 13 changed files with 568 additions and 351 deletions.
37 changes: 24 additions & 13 deletions include/boost/python/converter/registered.hpp
@@ -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>
Expand Down Expand Up @@ -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*)
Expand Down Expand Up @@ -112,4 +123,4 @@ namespace detail

}}} // namespace boost::python::converter

#endif // REGISTERED_DWA2002710_HPP
#endif
80 changes: 41 additions & 39 deletions include/boost/python/converter/shared_ptr_from_python.hpp
@@ -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
29 changes: 22 additions & 7 deletions include/boost/python/converter/shared_ptr_to_python.hpp
@@ -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 {

Expand All @@ -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
18 changes: 12 additions & 6 deletions include/boost/python/detail/is_shared_ptr.hpp
@@ -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
23 changes: 17 additions & 6 deletions include/boost/python/detail/value_is_shared_ptr.hpp
@@ -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

0 comments on commit 97e4b34

Please sign in to comment.