Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/python/converter/object_manager.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/python/converter/object_manager.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,230 @@ +// 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> +{ +}; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +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> +{ +}; +# else + +namespace detail +{ + typedef char (&yes_reference_to_object_manager)[1]; + typedef char (&no_reference_to_object_manager)[2]; + + // A number of nastinesses go on here in order to work around MSVC6 + // bugs. + template <class T> + struct is_object_manager_help + { + typedef typename mpl::if_< + is_object_manager<T> + , yes_reference_to_object_manager + , no_reference_to_object_manager + >::type type; + + // If we just use the type instead of the result of calling this + // function, VC6 will ICE. + static type call(); + }; + + // A set of overloads for each cv-qualification. The same argument + // is passed twice: the first one is used to unwind the cv*, and the + // second one is used to avoid relying on partial ordering for + // overload resolution. + template <class U> + typename is_object_manager_help<U> + is_object_manager_helper(U*, void*); + + template <class U> + typename is_object_manager_help<U> + is_object_manager_helper(U const*, void const*); + + template <class U> + typename is_object_manager_help<U> + is_object_manager_helper(U volatile*, void volatile*); + + template <class U> + typename is_object_manager_help<U> + is_object_manager_helper(U const volatile*, void const volatile*); + + template <class T> + struct is_reference_to_object_manager_nonref + : mpl::false_ + { + }; + + template <class T> + struct is_reference_to_object_manager_ref + { + static T sample_object; + BOOST_STATIC_CONSTANT( + bool, value + = (sizeof(is_object_manager_helper(&sample_object, &sample_object).call()) + == sizeof(detail::yes_reference_to_object_manager) + ) + ); + typedef mpl::bool_<value> type; + }; +} + +template <class T> +struct is_reference_to_object_manager + : mpl::if_< + is_reference<T> + , detail::is_reference_to_object_manager_ref<T> + , detail::is_reference_to_object_manager_nonref<T> + >::type +{ +}; +# endif + +}}} // namespace boost::python::converter + +#endif // OBJECT_MANAGER_DWA2002614_HPP