117 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| // 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 <boost/python/detail/prefix.hpp>
 | |
| #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
 | |
| # include <boost/python/converter/pytype_function.hpp>
 | |
| #endif
 | |
| 
 | |
| # include <boost/python/type_id.hpp>
 | |
| # include <boost/python/converter/registry.hpp>
 | |
| # include <boost/python/detail/void_ptr.hpp>
 | |
| 
 | |
| 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 <class T, class U>
 | |
|   inline type_info extractor_type_id(T&(*)(U))
 | |
|   {
 | |
|       return type_id<T>();
 | |
|   }
 | |
| 
 | |
|   // 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 <class Extractor, class U>
 | |
|   struct normalized_extractor
 | |
|   {
 | |
|       static inline void* execute(PyObject* op)
 | |
|       {
 | |
|           typedef typename boost::add_reference<U>::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>(&Extractor::execute)
 | |
|   template <class Extractor, class T, class U>
 | |
|   inline normalized_extractor<Extractor,U>
 | |
|   normalize(T(*)(U), Extractor* = 0)
 | |
|   {
 | |
|       return normalized_extractor<Extractor, U>();
 | |
|   }
 | |
| }
 | |
| 
 | |
| // An Extractor which extracts the given member from a Python object
 | |
| // whose instances are stored as InstanceType.
 | |
| template <class InstanceType, class MemberType, MemberType (InstanceType::*member)>
 | |
| 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 <class InstanceType>
 | |
| 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 <class Extractor, PyTypeObject const* python_type>
 | |
| 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<PyTypeObject*>(python_type))
 | |
|             ? const_cast<void*>(
 | |
|                 static_cast<void const volatile*>(
 | |
|                     detail::normalize<Extractor>(&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
 | 
