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