157 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			157 lines
		
	
	
		
			4.4 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 OBJECT_MANAGER_DWA2002614_HPP
							 | 
						||
| 
								 | 
							
								# define OBJECT_MANAGER_DWA2002614_HPP
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# include <boost/python/handle.hpp>
							 | 
						||
| 
								 | 
							
								# include <boost/python/cast.hpp>
							 | 
						||
| 
								 | 
							
								# include <boost/python/converter/pyobject_traits.hpp>
							 | 
						||
| 
								 | 
							
								# include <boost/type_traits/object_traits.hpp>
							 | 
						||
| 
								 | 
							
								# include <boost/mpl/if.hpp>
							 | 
						||
| 
								 | 
							
								# include <boost/python/detail/indirect_traits.hpp>
							 | 
						||
| 
								 | 
							
								# include <boost/mpl/bool.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Facilities for dealing with types which always manage Python
							 | 
						||
| 
								 | 
							
								// objects. Some examples are object, list, str, et. al. Different
							 | 
						||
| 
								 | 
							
								// to_python/from_python conversion rules apply here because in
							 | 
						||
| 
								 | 
							
								// contrast to other types which are typically embedded inside a
							 | 
						||
| 
								 | 
							
								// Python object, these are wrapped around a Python object. For most
							 | 
						||
| 
								 | 
							
								// object managers T, a C++ non-const T reference argument does not
							 | 
						||
| 
								 | 
							
								// imply the existence of a T lvalue embedded in the corresponding
							 | 
						||
| 
								 | 
							
								// Python argument, since mutating member functions on T actually only
							 | 
						||
| 
								 | 
							
								// modify the held Python object.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// handle<T> is an object manager, though strictly speaking it should
							 | 
						||
| 
								 | 
							
								// not be. In other words, even though mutating member functions of
							 | 
						||
| 
								 | 
							
								// hanlde<T> actually modify the handle<T> and not the T object,
							 | 
						||
| 
								 | 
							
								// handle<T>& arguments of wrapped functions will bind to "rvalues"
							 | 
						||
| 
								 | 
							
								// wrapping the actual Python argument, just as with other object
							 | 
						||
| 
								 | 
							
								// manager classes. Making an exception for handle<T> is simply not
							 | 
						||
| 
								 | 
							
								// worth the trouble.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// borrowed<T> cv* is an object manager so that we can use the general
							 | 
						||
| 
								 | 
							
								// to_python mechanisms to convert raw Python object pointers to
							 | 
						||
| 
								 | 
							
								// python, without the usual semantic problems of using raw pointers.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Object Manager Concept requirements:
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//    T is an Object Manager
							 | 
						||
| 
								 | 
							
								//    p is a PyObject*
							 | 
						||
| 
								 | 
							
								//    x is a T
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//    * object_manager_traits<T>::is_specialized == true
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//    * T(detail::borrowed_reference(p))
							 | 
						||
| 
								 | 
							
								//        Manages p without checking its type
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//    * get_managed_object(x, boost::python::tag)
							 | 
						||
| 
								 | 
							
								//        Convertible to PyObject*
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Additional requirements if T can be converted from_python:
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//    * T(object_manager_traits<T>::adopt(p))
							 | 
						||
| 
								 | 
							
								//        steals a reference to p, or throws a TypeError exception if
							 | 
						||
| 
								 | 
							
								//        p doesn't have an appropriate type. May assume p is non-null
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//    * X::check(p)
							 | 
						||
| 
								 | 
							
								//        convertible to bool. True iff T(X::construct(p)) will not
							 | 
						||
| 
								 | 
							
								//        throw.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Forward declarations
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								namespace boost { namespace python
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  namespace api
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    class object; 
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost { namespace python { namespace converter { 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Specializations for handle<T>
							 | 
						||
| 
								 | 
							
								template <class T>
							 | 
						||
| 
								 | 
							
								struct handle_object_manager_traits
							 | 
						||
| 
								 | 
							
								    : pyobject_traits<typename T::element_type>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								 private:
							 | 
						||
| 
								 | 
							
								  typedef pyobject_traits<typename T::element_type> base;
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								 public:
							 | 
						||
| 
								 | 
							
								  BOOST_STATIC_CONSTANT(bool, is_specialized = true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Initialize with a null_ok pointer for efficiency, bypassing the
							 | 
						||
| 
								 | 
							
								  // null check since the source is always non-null.
							 | 
						||
| 
								 | 
							
								  static null_ok<typename T::element_type>* adopt(PyObject* p)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								      return python::allow_null(base::checked_downcast(p));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class T>
							 | 
						||
| 
								 | 
							
								struct default_object_manager_traits
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    BOOST_STATIC_CONSTANT(
							 | 
						||
| 
								 | 
							
								        bool, is_specialized = python::detail::is_borrowed_ptr<T>::value
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class T>
							 | 
						||
| 
								 | 
							
								struct object_manager_traits
							 | 
						||
| 
								 | 
							
								    : mpl::if_c<
							 | 
						||
| 
								 | 
							
								         is_handle<T>::value
							 | 
						||
| 
								 | 
							
								       , handle_object_manager_traits<T>
							 | 
						||
| 
								 | 
							
								       , default_object_manager_traits<T>
							 | 
						||
| 
								 | 
							
								    >::type
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Traits for detecting whether a type is an object manager or a
							 | 
						||
| 
								 | 
							
								// (cv-qualified) reference to an object manager.
							 | 
						||
| 
								 | 
							
								// 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class T>
							 | 
						||
| 
								 | 
							
								struct is_object_manager
							 | 
						||
| 
								 | 
							
								    : mpl::bool_<object_manager_traits<T>::is_specialized>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class T>
							 | 
						||
| 
								 | 
							
								struct is_reference_to_object_manager
							 | 
						||
| 
								 | 
							
								    : mpl::false_
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class T>
							 | 
						||
| 
								 | 
							
								struct is_reference_to_object_manager<T&>
							 | 
						||
| 
								 | 
							
								    : is_object_manager<T>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class T>
							 | 
						||
| 
								 | 
							
								struct is_reference_to_object_manager<T const&>
							 | 
						||
| 
								 | 
							
								    : is_object_manager<T>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class T>
							 | 
						||
| 
								 | 
							
								struct is_reference_to_object_manager<T volatile&>
							 | 
						||
| 
								 | 
							
								    : is_object_manager<T>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class T>
							 | 
						||
| 
								 | 
							
								struct is_reference_to_object_manager<T const volatile&>
							 | 
						||
| 
								 | 
							
								    : is_object_manager<T>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}}} // namespace boost::python::converter
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // OBJECT_MANAGER_DWA2002614_HPP
							 |