|
||||
File indexing completed on 2025-01-18 09:50:37
0001 // Copyright David Abrahams 2002. 0002 // Distributed under the Boost Software License, Version 1.0. (See 0003 // accompanying file LICENSE_1_0.txt or copy at 0004 // http://www.boost.org/LICENSE_1_0.txt) 0005 #ifndef OBJECT_MANAGER_DWA2002614_HPP 0006 # define OBJECT_MANAGER_DWA2002614_HPP 0007 0008 # include <boost/python/handle.hpp> 0009 # include <boost/python/cast.hpp> 0010 # include <boost/python/converter/pyobject_traits.hpp> 0011 # include <boost/python/detail/type_traits.hpp> 0012 # include <boost/mpl/if.hpp> 0013 # include <boost/python/detail/indirect_traits.hpp> 0014 # include <boost/mpl/bool.hpp> 0015 0016 // Facilities for dealing with types which always manage Python 0017 // objects. Some examples are object, list, str, et. al. Different 0018 // to_python/from_python conversion rules apply here because in 0019 // contrast to other types which are typically embedded inside a 0020 // Python object, these are wrapped around a Python object. For most 0021 // object managers T, a C++ non-const T reference argument does not 0022 // imply the existence of a T lvalue embedded in the corresponding 0023 // Python argument, since mutating member functions on T actually only 0024 // modify the held Python object. 0025 // 0026 // handle<T> is an object manager, though strictly speaking it should 0027 // not be. In other words, even though mutating member functions of 0028 // hanlde<T> actually modify the handle<T> and not the T object, 0029 // handle<T>& arguments of wrapped functions will bind to "rvalues" 0030 // wrapping the actual Python argument, just as with other object 0031 // manager classes. Making an exception for handle<T> is simply not 0032 // worth the trouble. 0033 // 0034 // borrowed<T> cv* is an object manager so that we can use the general 0035 // to_python mechanisms to convert raw Python object pointers to 0036 // python, without the usual semantic problems of using raw pointers. 0037 0038 0039 // Object Manager Concept requirements: 0040 // 0041 // T is an Object Manager 0042 // p is a PyObject* 0043 // x is a T 0044 // 0045 // * object_manager_traits<T>::is_specialized == true 0046 // 0047 // * T(detail::borrowed_reference(p)) 0048 // Manages p without checking its type 0049 // 0050 // * get_managed_object(x, boost::python::tag) 0051 // Convertible to PyObject* 0052 // 0053 // Additional requirements if T can be converted from_python: 0054 // 0055 // * T(object_manager_traits<T>::adopt(p)) 0056 // steals a reference to p, or throws a TypeError exception if 0057 // p doesn't have an appropriate type. May assume p is non-null 0058 // 0059 // * X::check(p) 0060 // convertible to bool. True iff T(X::construct(p)) will not 0061 // throw. 0062 0063 // Forward declarations 0064 // 0065 namespace boost { namespace python 0066 { 0067 namespace api 0068 { 0069 class object; 0070 } 0071 }} 0072 0073 namespace boost { namespace python { namespace converter { 0074 0075 0076 // Specializations for handle<T> 0077 template <class T> 0078 struct handle_object_manager_traits 0079 : pyobject_traits<typename T::element_type> 0080 { 0081 private: 0082 typedef pyobject_traits<typename T::element_type> base; 0083 0084 public: 0085 BOOST_STATIC_CONSTANT(bool, is_specialized = true); 0086 0087 // Initialize with a null_ok pointer for efficiency, bypassing the 0088 // null check since the source is always non-null. 0089 static null_ok<typename T::element_type>* adopt(PyObject* p) 0090 { 0091 return python::allow_null(base::checked_downcast(p)); 0092 } 0093 }; 0094 0095 template <class T> 0096 struct default_object_manager_traits 0097 { 0098 BOOST_STATIC_CONSTANT( 0099 bool, is_specialized = python::detail::is_borrowed_ptr<T>::value 0100 ); 0101 }; 0102 0103 template <class T> 0104 struct object_manager_traits 0105 : mpl::if_c< 0106 is_handle<T>::value 0107 , handle_object_manager_traits<T> 0108 , default_object_manager_traits<T> 0109 >::type 0110 { 0111 }; 0112 0113 // 0114 // Traits for detecting whether a type is an object manager or a 0115 // (cv-qualified) reference to an object manager. 0116 // 0117 0118 template <class T> 0119 struct is_object_manager 0120 : mpl::bool_<object_manager_traits<T>::is_specialized> 0121 { 0122 }; 0123 0124 template <class T> 0125 struct is_reference_to_object_manager 0126 : mpl::false_ 0127 { 0128 }; 0129 0130 template <class T> 0131 struct is_reference_to_object_manager<T&> 0132 : is_object_manager<T> 0133 { 0134 }; 0135 0136 template <class T> 0137 struct is_reference_to_object_manager<T const&> 0138 : is_object_manager<T> 0139 { 0140 }; 0141 0142 template <class T> 0143 struct is_reference_to_object_manager<T volatile&> 0144 : is_object_manager<T> 0145 { 0146 }; 0147 0148 template <class T> 0149 struct is_reference_to_object_manager<T const volatile&> 0150 : is_object_manager<T> 0151 { 0152 }; 0153 0154 }}} // namespace boost::python::converter 0155 0156 #endif // OBJECT_MANAGER_DWA2002614_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |