// 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 LVALUE_FROM_PYTYPE_DWA2002130_HPP # define LVALUE_FROM_PYTYPE_DWA2002130_HPP # include #ifndef BOOST_PYTHON_NO_PY_SIGNATURES # include #endif # include # include # include # include namespace boost { namespace python { namespace detail { // Given a pointer-to-function of 1 parameter returning a reference // type, return the type_id of the function's return type. template inline type_info extractor_type_id(T&(*)(U)) { return type_id(); } // A function generator whose static execute() function is an lvalue // from_python converter using the given Extractor. U is expected to // be the actual type of the PyObject instance from which the result // is being extracted. template struct normalized_extractor { static inline void* execute(PyObject* op) { typedef typename add_lvalue_reference::type param; return &Extractor::execute( boost::python::detail::void_ptr_to_reference( op, (param(*)())0 ) ); } }; // Given an Extractor type and a pointer to its execute function, // return a new object whose static execute function does the same // job but is a conforming lvalue from_python conversion function. // // usage: normalize(&Extractor::execute) template inline normalized_extractor normalize(T(*)(U), Extractor* = 0) { return normalized_extractor(); } } // An Extractor which extracts the given member from a Python object // whose instances are stored as InstanceType. template struct extract_member { static MemberType& execute(InstanceType& c) { (void)Py_TYPE(&c); // static assertion return c.*member; } }; // An Extractor which simply extracts the entire python object // instance of InstanceType. template struct extract_identity { static InstanceType& execute(InstanceType& c) { (void)Py_TYPE(&c); // static assertion return c; } }; // Registers a from_python conversion which extracts lvalues using // Extractor's static execute function from Python objects whose type // object is python_type. template struct lvalue_from_pytype { lvalue_from_pytype() { converter::registry::insert ( &extract , detail::extractor_type_id(&Extractor::execute) #ifndef BOOST_PYTHON_NO_PY_SIGNATURES , &get_pytype #endif ); } private: static void* extract(PyObject* op) { return PyObject_TypeCheck(op, const_cast(python_type)) ? const_cast( static_cast( detail::normalize(&Extractor::execute).execute(op))) : 0 ; } #ifndef BOOST_PYTHON_NO_PY_SIGNATURES static PyTypeObject const*get_pytype() { return python_type; } #endif }; }} // namespace boost::python #endif // LVALUE_FROM_PYTYPE_DWA2002130_HPP