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
							 |