| // Copyright David Abrahams 2002. |
| // 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 OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP |
| # define OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP |
| |
| # include <boost/python/detail/prefix.hpp> |
| # include <boost/python/detail/referent_storage.hpp> |
| # include <boost/python/detail/destroy.hpp> |
| # include <boost/python/detail/construct.hpp> |
| # include <boost/python/converter/object_manager.hpp> |
| # include <boost/python/detail/raw_pyobject.hpp> |
| # include <boost/python/tag.hpp> |
| |
| // |
| // arg_from_python converters for Python type wrappers, to be used as |
| // base classes for specializations. |
| // |
| namespace boost { namespace python { namespace converter { |
| |
| template <class T> |
| struct object_manager_value_arg_from_python |
| { |
| typedef T result_type; |
| |
| object_manager_value_arg_from_python(PyObject*); |
| bool convertible() const; |
| T operator()() const; |
| private: |
| PyObject* m_source; |
| }; |
| |
| // Used for converting reference-to-object-manager arguments from |
| // python. The process used here is a little bit odd. Upon |
| // construction, we build the object manager object in the m_result |
| // object, *forcing* it to accept the source Python object by casting |
| // its pointer to detail::borrowed_reference. This is supposed to |
| // bypass any type checking of the source object. The convertible |
| // check then extracts the owned object and checks it. If the check |
| // fails, nothing else in the program ever gets to touch this strange |
| // "forced" object. |
| template <class Ref> |
| struct object_manager_ref_arg_from_python |
| { |
| typedef Ref result_type; |
| |
| object_manager_ref_arg_from_python(PyObject*); |
| bool convertible() const; |
| Ref operator()() const; |
| ~object_manager_ref_arg_from_python(); |
| private: |
| typename python::detail::referent_storage<Ref>::type m_result; |
| }; |
| |
| // |
| // implementations |
| // |
| |
| template <class T> |
| inline object_manager_value_arg_from_python<T>::object_manager_value_arg_from_python(PyObject* x) |
| : m_source(x) |
| { |
| } |
| |
| template <class T> |
| inline bool object_manager_value_arg_from_python<T>::convertible() const |
| { |
| return object_manager_traits<T>::check(m_source); |
| } |
| |
| template <class T> |
| inline T object_manager_value_arg_from_python<T>::operator()() const |
| { |
| return T(python::detail::borrowed_reference(m_source)); |
| } |
| |
| template <class Ref> |
| inline object_manager_ref_arg_from_python<Ref>::object_manager_ref_arg_from_python(PyObject* x) |
| { |
| # if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243 |
| // needed for warning suppression |
| python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x); |
| python::detail::construct_referent<Ref>(&m_result.bytes, x_); |
| # else |
| python::detail::construct_referent<Ref>(&m_result.bytes, (python::detail::borrowed_reference)x); |
| # endif |
| } |
| |
| template <class Ref> |
| inline object_manager_ref_arg_from_python<Ref>::~object_manager_ref_arg_from_python() |
| { |
| python::detail::destroy_referent<Ref>(this->m_result.bytes); |
| } |
| |
| namespace detail |
| { |
| template <class T> |
| inline bool object_manager_ref_check(T const& x) |
| { |
| return object_manager_traits<T>::check(get_managed_object(x, tag)); |
| } |
| } |
| |
| template <class Ref> |
| inline bool object_manager_ref_arg_from_python<Ref>::convertible() const |
| { |
| return detail::object_manager_ref_check( |
| python::detail::void_ptr_to_reference(this->m_result.bytes, (Ref(*)())0)); |
| } |
| |
| template <class Ref> |
| inline Ref object_manager_ref_arg_from_python<Ref>::operator()() const |
| { |
| return python::detail::void_ptr_to_reference( |
| this->m_result.bytes, (Ref(*)())0); |
| } |
| |
| }}} // namespace boost::python::converter |
| |
| #endif // OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP |