shared_ptr_from_python.hpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // Copyright David Abrahams 2002.
  2. // Copyright Stefan Seefeld 2016.
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef boost_python_converter_shared_ptr_from_python_hpp_
  7. #define boost_python_converter_shared_ptr_from_python_hpp_
  8. #include <boost/python/handle.hpp>
  9. #include <boost/python/converter/shared_ptr_deleter.hpp>
  10. #include <boost/python/converter/from_python.hpp>
  11. #include <boost/python/converter/rvalue_from_python_data.hpp>
  12. #include <boost/python/converter/registered.hpp>
  13. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  14. # include <boost/python/converter/pytype_function.hpp>
  15. #endif
  16. #include <boost/shared_ptr.hpp>
  17. #include <memory>
  18. namespace boost { namespace python { namespace converter {
  19. template <class T, template <typename> class SP>
  20. struct shared_ptr_from_python
  21. {
  22. shared_ptr_from_python()
  23. {
  24. converter::registry::insert(&convertible, &construct, type_id<SP<T> >()
  25. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  26. , &converter::expected_from_python_type_direct<T>::get_pytype
  27. #endif
  28. );
  29. }
  30. private:
  31. static void* convertible(PyObject* p)
  32. {
  33. if (p == Py_None)
  34. return p;
  35. return converter::get_lvalue_from_python(p, registered<T>::converters);
  36. }
  37. static void construct(PyObject* source, rvalue_from_python_stage1_data* data)
  38. {
  39. void* const storage = ((converter::rvalue_from_python_storage<SP<T> >*)data)->storage.bytes;
  40. // Deal with the "None" case.
  41. if (data->convertible == source)
  42. new (storage) SP<T>();
  43. else
  44. {
  45. SP<void> hold_convertible_ref_count(
  46. (void*)0, shared_ptr_deleter(handle<>(borrowed(source))) );
  47. // use aliasing constructor
  48. new (storage) SP<T>(hold_convertible_ref_count,
  49. static_cast<T*>(data->convertible));
  50. }
  51. data->convertible = storage;
  52. }
  53. };
  54. }}} // namespace boost::python::converter
  55. #endif