Chris@16: // Copyright David Abrahams 2002. Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: #ifndef EXTRACT_DWA200265_HPP Chris@16: # define EXTRACT_DWA200265_HPP Chris@16: Chris@16: # include Chris@16: Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: # include Chris@16: # include Chris@16: Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 900) Chris@16: // workaround for VC++ 6.x or 7.0 Chris@16: # define BOOST_EXTRACT_WORKAROUND () Chris@16: #else Chris@16: # define BOOST_EXTRACT_WORKAROUND Chris@16: #endif Chris@16: Chris@16: namespace boost { namespace python { Chris@16: Chris@16: namespace api Chris@16: { Chris@16: class object; Chris@16: } Chris@16: Chris@16: namespace converter Chris@16: { Chris@16: template Chris@16: struct extract_pointer Chris@16: { Chris@16: typedef Ptr result_type; Chris@16: extract_pointer(PyObject*); Chris@16: Chris@16: bool check() const; Chris@16: Ptr operator()() const; Chris@16: Chris@16: private: Chris@16: PyObject* m_source; Chris@16: void* m_result; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct extract_reference Chris@16: { Chris@16: typedef Ref result_type; Chris@16: extract_reference(PyObject*); Chris@16: Chris@16: bool check() const; Chris@16: Ref operator()() const; Chris@16: Chris@16: private: Chris@16: PyObject* m_source; Chris@16: void* m_result; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct extract_rvalue : private noncopyable Chris@16: { Chris@16: typedef typename mpl::if_< Chris@16: python::detail::copy_ctor_mutates_rhs Chris@16: , T& Chris@16: , typename call_traits::param_type Chris@16: >::type result_type; Chris@16: Chris@16: extract_rvalue(PyObject*); Chris@16: Chris@16: bool check() const; Chris@16: result_type operator()() const; Chris@16: private: Chris@16: PyObject* m_source; Chris@16: mutable rvalue_from_python_data m_data; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct extract_object_manager Chris@16: { Chris@16: typedef T result_type; Chris@16: extract_object_manager(PyObject*); Chris@16: Chris@16: bool check() const; Chris@16: result_type operator()() const; Chris@16: private: Chris@16: PyObject* m_source; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct select_extract Chris@16: { Chris@16: BOOST_STATIC_CONSTANT( Chris@16: bool, obj_mgr = is_object_manager::value); Chris@16: Chris@16: BOOST_STATIC_CONSTANT( Chris@16: bool, ptr = is_pointer::value); Chris@16: Chris@16: BOOST_STATIC_CONSTANT( Chris@16: bool, ref = is_reference::value); Chris@16: Chris@16: typedef typename mpl::if_c< Chris@16: obj_mgr Chris@16: , extract_object_manager Chris@16: , typename mpl::if_c< Chris@16: ptr Chris@16: , extract_pointer Chris@16: , typename mpl::if_c< Chris@16: ref Chris@16: , extract_reference Chris@16: , extract_rvalue Chris@16: >::type Chris@16: >::type Chris@16: >::type type; Chris@16: }; Chris@16: } Chris@16: Chris@16: template Chris@16: struct extract Chris@16: : converter::select_extract::type Chris@16: { Chris@16: private: Chris@16: typedef typename converter::select_extract::type base; Chris@16: public: Chris@16: typedef typename base::result_type result_type; Chris@16: Chris@16: operator result_type() const Chris@16: { Chris@16: return (*this)(); Chris@16: } Chris@16: Chris@16: extract(PyObject*); Chris@16: extract(api::object const&); Chris@16: }; Chris@16: Chris@16: // Chris@16: // Implementations Chris@16: // Chris@16: template Chris@16: inline extract::extract(PyObject* o) Chris@16: : base(o) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: inline extract::extract(api::object const& o) Chris@16: : base(o.ptr()) Chris@16: { Chris@16: } Chris@16: Chris@16: namespace converter Chris@16: { Chris@16: template Chris@16: inline extract_rvalue::extract_rvalue(PyObject* x) Chris@16: : m_source(x) Chris@16: , m_data( Chris@16: (rvalue_from_python_stage1)(x, registered::converters) Chris@16: ) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: inline bool Chris@16: extract_rvalue::check() const Chris@16: { Chris@16: return m_data.stage1.convertible; Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename extract_rvalue::result_type Chris@16: extract_rvalue::operator()() const Chris@16: { Chris@16: return *(T*)( Chris@16: // Only do the stage2 conversion once Chris@16: m_data.stage1.convertible == m_data.storage.bytes Chris@16: ? m_data.storage.bytes Chris@16: : (rvalue_from_python_stage2)(m_source, m_data.stage1, registered::converters) Chris@16: ); Chris@16: } Chris@16: Chris@16: template Chris@16: inline extract_reference::extract_reference(PyObject* obj) Chris@16: : m_source(obj) Chris@16: , m_result( Chris@16: (get_lvalue_from_python)(obj, registered::converters) Chris@16: ) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: inline bool extract_reference::check() const Chris@16: { Chris@16: return m_result != 0; Chris@16: } Chris@16: Chris@16: template Chris@16: inline Ref extract_reference::operator()() const Chris@16: { Chris@16: if (m_result == 0) Chris@16: (throw_no_reference_from_python)(m_source, registered::converters); Chris@16: Chris@16: return python::detail::void_ptr_to_reference(m_result, (Ref(*)())0); Chris@16: } Chris@16: Chris@16: template Chris@16: inline extract_pointer::extract_pointer(PyObject* obj) Chris@16: : m_source(obj) Chris@16: , m_result( Chris@16: obj == Py_None ? 0 : (get_lvalue_from_python)(obj, registered_pointee::converters) Chris@16: ) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: inline bool extract_pointer::check() const Chris@16: { Chris@16: return m_source == Py_None || m_result != 0; Chris@16: } Chris@16: Chris@16: template Chris@16: inline Ptr extract_pointer::operator()() const Chris@16: { Chris@16: if (m_result == 0 && m_source != Py_None) Chris@16: (throw_no_pointer_from_python)(m_source, registered_pointee::converters); Chris@16: Chris@16: return Ptr(m_result); Chris@16: } Chris@16: Chris@16: template Chris@16: inline extract_object_manager::extract_object_manager(PyObject* obj) Chris@16: : m_source(obj) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: inline bool extract_object_manager::check() const Chris@16: { Chris@16: return object_manager_traits::check(m_source); Chris@16: } Chris@16: Chris@16: template Chris@16: inline T extract_object_manager::operator()() const Chris@16: { Chris@16: return T( Chris@16: object_manager_traits::adopt(python::incref(m_source)) Chris@16: ); Chris@16: } Chris@16: } Chris@16: Chris@16: }} // namespace boost::python::converter Chris@16: Chris@16: #endif // EXTRACT_DWA200265_HPP