// 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 OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
# define OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP

# include <boost/python/detail/prefix.hpp>
# include <boost/python/detail/referent_storage.hpp>
# include <boost/python/detail/destroy.hpp>
# include <boost/python/detail/construct.hpp>
# include <boost/python/converter/object_manager.hpp>
# include <boost/python/detail/raw_pyobject.hpp>
# include <boost/python/tag.hpp>

//
// arg_from_python converters for Python type wrappers, to be used as
// base classes for specializations.
//
namespace boost { namespace python { namespace converter { 

template <class T>
struct object_manager_value_arg_from_python
{
    typedef T result_type;
    
    object_manager_value_arg_from_python(PyObject*);
    bool convertible() const;
    T operator()() const;
 private:
    PyObject* m_source;
};

// Used for converting reference-to-object-manager arguments from
// python. The process used here is a little bit odd. Upon
// construction, we build the object manager object in the m_result
// object, *forcing* it to accept the source Python object by casting
// its pointer to detail::borrowed_reference. This is supposed to
// bypass any type checking of the source object. The convertible
// check then extracts the owned object and checks it. If the check
// fails, nothing else in the program ever gets to touch this strange
// "forced" object.
template <class Ref>
struct object_manager_ref_arg_from_python
{
    typedef Ref result_type;
    
    object_manager_ref_arg_from_python(PyObject*);
    bool convertible() const;
    Ref operator()() const;
    ~object_manager_ref_arg_from_python();
 private:
    typename python::detail::referent_storage<Ref>::type m_result;
};

//
// implementations
//

template <class T>
inline object_manager_value_arg_from_python<T>::object_manager_value_arg_from_python(PyObject* x)
    : m_source(x)
{
}
    
template <class T>
inline bool object_manager_value_arg_from_python<T>::convertible() const
{
    return object_manager_traits<T>::check(m_source);
}

template <class T>
inline T object_manager_value_arg_from_python<T>::operator()() const
{
    return T(python::detail::borrowed_reference(m_source));
}

template <class Ref>
inline object_manager_ref_arg_from_python<Ref>::object_manager_ref_arg_from_python(PyObject* x)
{
# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243
    // needed for warning suppression
    python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x);
    python::detail::construct_referent<Ref>(&m_result.bytes, x_);
# else 
    python::detail::construct_referent<Ref>(&m_result.bytes, (python::detail::borrowed_reference)x);
# endif 
}

template <class Ref>
inline object_manager_ref_arg_from_python<Ref>::~object_manager_ref_arg_from_python()
{
    python::detail::destroy_referent<Ref>(this->m_result.bytes);
}

namespace detail
{
  template <class T>
  inline bool object_manager_ref_check(T const& x)
  {
      return object_manager_traits<T>::check(get_managed_object(x, tag));
  }
}

template <class Ref>
inline bool object_manager_ref_arg_from_python<Ref>::convertible() const
{
    return detail::object_manager_ref_check(
        python::detail::void_ptr_to_reference(this->m_result.bytes, (Ref(*)())0));
}

template <class Ref>
inline Ref object_manager_ref_arg_from_python<Ref>::operator()() const
{
    return python::detail::void_ptr_to_reference(
        this->m_result.bytes, (Ref(*)())0);
}

}}} // namespace boost::python::converter

#endif // OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
