// 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_CORE_DWA2002615_HPP
# define OBJECT_CORE_DWA2002615_HPP

# define BOOST_PYTHON_OBJECT_HAS_IS_NONE // added 2010-03-15 by rwgk

# include <boost/python/detail/prefix.hpp>

# include <boost/type.hpp>

# include <boost/python/call.hpp>
# include <boost/python/handle_fwd.hpp>
# include <boost/python/errors.hpp>
# include <boost/python/refcount.hpp>
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/tag.hpp>
# include <boost/python/def_visitor.hpp>

# include <boost/python/detail/raw_pyobject.hpp>
# include <boost/python/detail/dependent.hpp>

# include <boost/python/object/forward.hpp>
# include <boost/python/object/add_to_namespace.hpp>

# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/debug/line.hpp>

# include <boost/python/detail/is_xxx.hpp>
# include <boost/python/detail/string_literal.hpp>
# include <boost/python/detail/def_helper_fwd.hpp>

# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/remove_reference.hpp>

# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
#  include <boost/type_traits/add_pointer.hpp>
# endif

# include <boost/mpl/if.hpp>

namespace boost { namespace python { 

namespace detail
{
  class kwds_proxy; 
  class args_proxy; 
} 

namespace converter
{
  template <class T> struct arg_to_python;
}

// Put this in an inner namespace so that the generalized operators won't take over
namespace api
{
  
// This file contains the definition of the object class and enough to
// construct/copy it, but not enough to do operations like
// attribute/item access or addition.

  template <class Policies> class proxy;
  
  struct const_attribute_policies;
  struct attribute_policies;
  struct const_objattribute_policies;
  struct objattribute_policies;
  struct const_item_policies;
  struct item_policies;
  struct const_slice_policies;
  struct slice_policies;
  class slice_nil;

  typedef proxy<const_attribute_policies> const_object_attribute;
  typedef proxy<attribute_policies> object_attribute;
  typedef proxy<const_objattribute_policies> const_object_objattribute;
  typedef proxy<objattribute_policies> object_objattribute;
  typedef proxy<const_item_policies> const_object_item;
  typedef proxy<item_policies> object_item;
  typedef proxy<const_slice_policies> const_object_slice;
  typedef proxy<slice_policies> object_slice;

  //
  // is_proxy -- proxy type detection
  //
  BOOST_PYTHON_IS_XXX_DEF(proxy, boost::python::api::proxy, 1)

  template <class T> struct object_initializer;
  
  class object;
  typedef PyObject* (object::*bool_type)() const;
  
  template <class U>
  class object_operators : public def_visitor<U>
  {
   protected:
# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
      typedef object const& object_cref;
# else 
      typedef object object_cref;
# endif
   public:
      // function call
      //
      object operator()() const;

# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, <boost/python/object_call.hpp>))
# include BOOST_PP_ITERATE()
    
      detail::args_proxy operator* () const; 
      object operator()(detail::args_proxy const &args) const; 
      object operator()(detail::args_proxy const &args, 
                        detail::kwds_proxy const &kwds) const; 

      // truth value testing
      //
      operator bool_type() const;
      bool operator!() const; // needed for vc6

      // Attribute access
      //
      const_object_attribute attr(char const*) const;
      object_attribute attr(char const*);
      const_object_objattribute attr(object const&) const;
      object_objattribute attr(object const&);

      // Wrap 'in' operator (aka. __contains__)
      template <class T>
      object contains(T const& key) const;
      
      // item access
      //
      const_object_item operator[](object_cref) const;
      object_item operator[](object_cref);
    
      template <class T>
      const_object_item
      operator[](T const& key) const
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
          ;
# else 
      {
          return (*this)[object(key)];
      }
# endif 
    
      template <class T>
      object_item
      operator[](T const& key)
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
          ;
# else 
      {
          return (*this)[object(key)];
      }
# endif

      // slicing
      //
      const_object_slice slice(object_cref, object_cref) const;
      object_slice slice(object_cref, object_cref);

      const_object_slice slice(slice_nil, object_cref) const;
      object_slice slice(slice_nil, object_cref);
                             
      const_object_slice slice(object_cref, slice_nil) const;
      object_slice slice(object_cref, slice_nil);

      const_object_slice slice(slice_nil, slice_nil) const;
      object_slice slice(slice_nil, slice_nil);

      template <class T, class V>
      const_object_slice
      slice(T const& start, V const& end) const
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
          ;
# else
      {
          return this->slice(
               slice_bound<T>::type(start)
              ,  slice_bound<V>::type(end));
      }
# endif
    
      template <class T, class V>
      object_slice
      slice(T const& start, V const& end)
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
          ;
# else
      {
          return this->slice(
              slice_bound<T>::type(start)
              , slice_bound<V>::type(end));
      }
# endif
      
   private: // def visitation for adding callable objects as class methods
      
      template <class ClassT, class DocStringT>
      void visit(ClassT& cl, char const* name, python::detail::def_helper<DocStringT> const& helper) const
      {
          // It's too late to specify anything other than docstrings if
          // the callable object is already wrapped.
          BOOST_STATIC_ASSERT(
              (is_same<char const*,DocStringT>::value
               || detail::is_string_literal<DocStringT const>::value));
        
          objects::add_to_namespace(cl, name, this->derived_visitor(), helper.doc());
      }

      friend class python::def_visitor_access;
      
   private:
     // there is a confirmed CWPro8 codegen bug here. We prevent the
     // early destruction of a temporary by binding a named object
     // instead.
# if __MWERKS__ < 0x3000 || __MWERKS__ > 0x3003
    typedef object const& object_cref2;
# else
    typedef object const object_cref2;
# endif
  };

  
  // VC6 and VC7 require this base class in order to generate the
  // correct copy constructor for object. We can't define it there
  // explicitly or it will complain of ambiguity.
  struct object_base : object_operators<object>
  {
      // copy constructor without NULL checking, for efficiency. 
      inline object_base(object_base const&);
      inline object_base(PyObject* ptr);
      
      inline object_base& operator=(object_base const& rhs);
      inline ~object_base();
        
      // Underlying object access -- returns a borrowed reference
      inline PyObject* ptr() const;

      inline bool is_none() const;

   private:
      PyObject* m_ptr;
  };

# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <class T, class U>
  struct is_derived_impl
  {
      static T x;
      template <class X>
      static X* to_pointer(X const&);
      
      static char test(U const*);
      typedef char (&no)[2];
      static no test(...);

      BOOST_STATIC_CONSTANT(bool, value = sizeof(test(to_pointer(x))) == 1);
  };
  
  template <class T, class U>
  struct is_derived
    : mpl::bool_<is_derived_impl<T,U>::value>
  {};
# else
  template <class T, class U>
  struct is_derived
    : is_convertible<
          typename remove_reference<T>::type*
        , U const*
      >
  {};
# endif 

  template <class T>
  typename objects::unforward_cref<T>::type do_unforward_cref(T const& x)
  {
# if BOOST_WORKAROUND(__GNUC__, == 2)
      typedef typename objects::unforward_cref<T>::type ret;
      return ret(x);
# else
      return x;
# endif 
  }

# if BOOST_WORKAROUND(__GNUC__, == 2)
  // GCC 2.x has non-const string literals; this hacks around that problem.
  template <unsigned N>
  char const (& do_unforward_cref(char const(&x)[N]) )[N]
  {
      return x;
  }
# endif
  
  class object;
  
  template <class T>
  PyObject* object_base_initializer(T const& x)
  {
      typedef typename is_derived<
          BOOST_DEDUCED_TYPENAME objects::unforward_cref<T>::type
        , object
      >::type is_obj;

      return object_initializer<
          BOOST_DEDUCED_TYPENAME unwrap_reference<T>::type
      >::get(
            x
          , is_obj()
      );
  }
  
  class object : public object_base
  {
   public:
      // default constructor creates a None object
      object();
      
      // explicit conversion from any C++ object to Python
      template <class T>
      explicit object(
          T const& x
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
          // use some SFINAE to un-confuse MSVC about its
          // copy-initialization ambiguity claim.
        , typename mpl::if_<is_proxy<T>,int&,int>::type* = 0
# endif 
      )
        : object_base(object_base_initializer(x))
      {
      }

      // Throw error_already_set() if the handle is null.
      BOOST_PYTHON_DECL explicit object(handle<> const&);
   private:
      
   public: // implementation detail -- for internal use only
      explicit object(detail::borrowed_reference);
      explicit object(detail::new_reference);
      explicit object(detail::new_non_null_reference);
  };

  // Macros for forwarding constructors in classes derived from
  // object. Derived classes will usually want these as an
  // implementation detail
# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base)       \
    inline explicit derived(python::detail::borrowed_reference p)       \
        : base(p) {}                                                    \
    inline explicit derived(python::detail::new_reference p)            \
        : base(p) {}                                                    \
    inline explicit derived(python::detail::new_non_null_reference p)   \
        : base(p) {}

# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
#  define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_
# else
  // MSVC6 has a bug which causes an explicit template constructor to
  // be preferred over an appropriate implicit conversion operator
  // declared on the argument type. Normally, that would cause a
  // runtime failure when using extract<T> to extract a type with a
  // templated constructor. This additional constructor will turn that
  // runtime failure into an ambiguity error at compile-time due to
  // the lack of partial ordering, or at least a link-time error if no
  // generalized template constructor is declared.
#  define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived, base)       \
    BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base)            \
    template <class T>                                                  \
    explicit derived(extract<T> const&);
# endif

  //
  // object_initializer -- get the handle to construct the object with,
  // based on whether T is a proxy or derived from object
  //
  template <bool is_proxy = false, bool is_object_manager = false>
  struct object_initializer_impl
  {
      static PyObject*
      get(object const& x, mpl::true_)
      {
          return python::incref(x.ptr());
      }
      
      template <class T>
      static PyObject*
      get(T const& x, mpl::false_)
      {
          return python::incref(converter::arg_to_python<T>(x).get());
      }
  };
      
  template <>
  struct object_initializer_impl<true, false>
  {
      template <class Policies>
      static PyObject* 
      get(proxy<Policies> const& x, mpl::false_)
      {
          return python::incref(x.operator object().ptr());
      }
  };

  template <>
  struct object_initializer_impl<false, true>
  {
      template <class T, class U>
      static PyObject*
      get(T const& x, U)
      {
          return python::incref(get_managed_object(x, boost::python::tag));
      }
  };

  template <>
  struct object_initializer_impl<true, true>
  {}; // empty implementation should cause an error

  template <class T>
  struct object_initializer : object_initializer_impl<
      is_proxy<T>::value
    , converter::is_object_manager<T>::value
  >
  {};

}
using api::object;
template <class T> struct extract;

//
// implementation
//

namespace detail 
{

class call_proxy 
{ 
public: 
  call_proxy(object target) : m_target(target) {} 
  operator object() const { return m_target;} 
 
 private: 
    object m_target; 
}; 
 
class kwds_proxy : public call_proxy 
{ 
public: 
  kwds_proxy(object o = object()) : call_proxy(o) {} 
}; 
class args_proxy : public call_proxy 
{ 
public: 
  args_proxy(object o) : call_proxy(o) {} 
  kwds_proxy operator* () const { return kwds_proxy(*this);} 
}; 
} 
 
template <typename U> 
detail::args_proxy api::object_operators<U>::operator* () const 
{ 
  object_cref2 x = *static_cast<U const*>(this); 
  return boost::python::detail::args_proxy(x); 
} 
 
template <typename U> 
object api::object_operators<U>::operator()(detail::args_proxy const &args) const 
{ 
  U const& self = *static_cast<U const*>(this); 
  PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag), 
                                   args.operator object().ptr(), 
                                   0); 
  return object(boost::python::detail::new_reference(result)); 
 
} 
 
template <typename U> 
object api::object_operators<U>::operator()(detail::args_proxy const &args, 
                                            detail::kwds_proxy const &kwds) const 
{ 
  U const& self = *static_cast<U const*>(this); 
  PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag), 
                                   args.operator object().ptr(), 
                                   kwds.operator object().ptr()); 
  return object(boost::python::detail::new_reference(result)); 
 
}  


template <typename U>
template <class T>
object api::object_operators<U>::contains(T const& key) const
{
    return this->attr("__contains__")(object(key));
}


inline object::object()
    : object_base(python::incref(Py_None))
{}

// copy constructor without NULL checking, for efficiency
inline api::object_base::object_base(object_base const& rhs)
    : m_ptr(python::incref(rhs.m_ptr))
{}

inline api::object_base::object_base(PyObject* p)
    : m_ptr(p)
{}

inline api::object_base& api::object_base::operator=(api::object_base const& rhs)
{
    Py_INCREF(rhs.m_ptr);
    Py_DECREF(this->m_ptr);
    this->m_ptr = rhs.m_ptr;
    return *this;
}

inline api::object_base::~object_base()
{
    Py_DECREF(m_ptr);
}

inline object::object(detail::borrowed_reference p)
    : object_base(python::incref((PyObject*)p))
{}

inline object::object(detail::new_reference p)
    : object_base(expect_non_null((PyObject*)p))
{}

inline object::object(detail::new_non_null_reference p)
    : object_base((PyObject*)p)
{}

inline PyObject* api::object_base::ptr() const
{
    return m_ptr;
}

inline bool api::object_base::is_none() const
{
    return (m_ptr == Py_None);
}

//
// Converter specialization implementations
//
namespace converter
{
  template <class T> struct object_manager_traits;
  
  template <>
  struct object_manager_traits<object>
  {
      BOOST_STATIC_CONSTANT(bool, is_specialized = true);
      static bool check(PyObject*) { return true; }
      
      static python::detail::new_non_null_reference adopt(PyObject* x)
      {
          return python::detail::new_non_null_reference(x);
      }
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
      static PyTypeObject const *get_pytype() {return 0;}
#endif
  };
}

inline PyObject* get_managed_object(object const& x, tag_t)
{
    return x.ptr();
}

}} // namespace boost::python

# include <boost/python/slice_nil.hpp>

#endif // OBJECT_CORE_DWA2002615_HPP
