shared_ptr_from_python.hpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. void *const storage = ((converter::rvalue_from_python_storage<SP<T> >*)data)->storage.bytes;
  46. // Deal with the "None" case.
  47. if (data->convertible == source)
  48. new (storage) SP<T>();
  49. else
  50. {
  51. SP<void> hold_convertible_ref_count((void*)0, shared_ptr_deleter(handle<>(borrowed(source))) );
  52. // use aliasing constructor
  53. new (storage) SP<T>(hold_convertible_ref_count, static_cast<T*>(data->convertible));
  54. }
  55. }
  56. data->convertible = storage;
  57. }
  58. };
  59. }}} // namespace boost::python::converter
  60. #endif