// 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 |