You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
176 lines
5.3 KiB
176 lines
5.3 KiB
// 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 TO_PYTHON_VALUE_DWA200221_HPP |
|
# define TO_PYTHON_VALUE_DWA200221_HPP |
|
|
|
# include <boost/python/detail/prefix.hpp> |
|
|
|
# include <boost/python/refcount.hpp> |
|
# include <boost/python/tag.hpp> |
|
# include <boost/python/handle.hpp> |
|
|
|
# include <boost/python/converter/registry.hpp> |
|
# include <boost/python/converter/registered.hpp> |
|
# include <boost/python/converter/builtin_converters.hpp> |
|
# include <boost/python/converter/object_manager.hpp> |
|
# include <boost/python/converter/shared_ptr_to_python.hpp> |
|
|
|
# include <boost/python/detail/value_is_shared_ptr.hpp> |
|
# include <boost/python/detail/value_arg.hpp> |
|
|
|
# include <boost/type_traits/transform_traits.hpp> |
|
|
|
# include <boost/mpl/if.hpp> |
|
# include <boost/mpl/or.hpp> |
|
# include <boost/type_traits/is_const.hpp> |
|
|
|
namespace boost { namespace python { |
|
|
|
namespace detail |
|
{ |
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES |
|
|
|
template <bool is_const_ref> |
|
struct object_manager_get_pytype |
|
{ |
|
template <class U> |
|
static PyTypeObject const* get( U& (*)() =0) |
|
{ |
|
return converter::object_manager_traits<U>::get_pytype(); |
|
} |
|
}; |
|
|
|
template <> |
|
struct object_manager_get_pytype<true> |
|
{ |
|
template <class U> |
|
static PyTypeObject const* get( U const& (*)() =0) |
|
{ |
|
return converter::object_manager_traits<U>::get_pytype(); |
|
} |
|
}; |
|
|
|
#endif |
|
|
|
template <class T> |
|
struct object_manager_to_python_value |
|
{ |
|
typedef typename value_arg<T>::type argument_type; |
|
|
|
PyObject* operator()(argument_type) const; |
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES |
|
typedef boost::mpl::bool_<is_handle<T>::value> is_t_handle; |
|
typedef boost::detail::indirect_traits::is_reference_to_const<T> is_t_const; |
|
PyTypeObject const* get_pytype() const { |
|
return get_pytype_aux((is_t_handle*)0); |
|
} |
|
|
|
inline static PyTypeObject const* get_pytype_aux(mpl::true_*) {return converter::object_manager_traits<T>::get_pytype();} |
|
|
|
inline static PyTypeObject const* get_pytype_aux(mpl::false_* ) |
|
{ |
|
return object_manager_get_pytype<is_t_const::value>::get((T(*)())0); |
|
} |
|
|
|
#endif |
|
|
|
// This information helps make_getter() decide whether to try to |
|
// return an internal reference or not. I don't like it much, |
|
// but it will have to serve for now. |
|
BOOST_STATIC_CONSTANT(bool, uses_registry = false); |
|
}; |
|
|
|
|
|
template <class T> |
|
struct registry_to_python_value |
|
{ |
|
typedef typename value_arg<T>::type argument_type; |
|
|
|
PyObject* operator()(argument_type) const; |
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES |
|
PyTypeObject const* get_pytype() const {return converter::registered<T>::converters.to_python_target_type();} |
|
#endif |
|
|
|
// This information helps make_getter() decide whether to try to |
|
// return an internal reference or not. I don't like it much, |
|
// but it will have to serve for now. |
|
BOOST_STATIC_CONSTANT(bool, uses_registry = true); |
|
}; |
|
|
|
template <class T> |
|
struct shared_ptr_to_python_value |
|
{ |
|
typedef typename value_arg<T>::type argument_type; |
|
|
|
PyObject* operator()(argument_type) const; |
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES |
|
PyTypeObject const* get_pytype() const {return get_pytype((boost::type<argument_type>*)0);} |
|
#endif |
|
// This information helps make_getter() decide whether to try to |
|
// return an internal reference or not. I don't like it much, |
|
// but it will have to serve for now. |
|
BOOST_STATIC_CONSTANT(bool, uses_registry = false); |
|
private: |
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES |
|
template <class U> |
|
PyTypeObject const* get_pytype(boost::type<shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();} |
|
template <class U> |
|
PyTypeObject const* get_pytype(boost::type<const shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();} |
|
#endif |
|
}; |
|
} |
|
|
|
template <class T> |
|
struct to_python_value |
|
: mpl::if_< |
|
detail::value_is_shared_ptr<T> |
|
, detail::shared_ptr_to_python_value<T> |
|
, typename mpl::if_< |
|
mpl::or_< |
|
converter::is_object_manager<T> |
|
, converter::is_reference_to_object_manager<T> |
|
> |
|
, detail::object_manager_to_python_value<T> |
|
, detail::registry_to_python_value<T> |
|
>::type |
|
>::type |
|
{ |
|
}; |
|
|
|
// |
|
// implementation |
|
// |
|
namespace detail |
|
{ |
|
template <class T> |
|
inline PyObject* registry_to_python_value<T>::operator()(argument_type x) const |
|
{ |
|
typedef converter::registered<argument_type> r; |
|
# if BOOST_WORKAROUND(__GNUC__, < 3) |
|
// suppresses an ICE, somehow |
|
(void)r::converters; |
|
# endif |
|
return converter::registered<argument_type>::converters.to_python(&x); |
|
} |
|
|
|
template <class T> |
|
inline PyObject* object_manager_to_python_value<T>::operator()(argument_type x) const |
|
{ |
|
return python::upcast<PyObject>( |
|
python::xincref( |
|
get_managed_object(x, tag)) |
|
); |
|
} |
|
|
|
template <class T> |
|
inline PyObject* shared_ptr_to_python_value<T>::operator()(argument_type x) const |
|
{ |
|
return converter::shared_ptr_to_python(x); |
|
} |
|
} |
|
|
|
}} // namespace boost::python |
|
|
|
#endif // TO_PYTHON_VALUE_DWA200221_HPP
|
|
|