//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009.
// (C) Copyright Gennaro Prota 2003 - 2004.
//
// 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)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////

#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
#define BOOST_CONTAINERS_DETAIL_ITERATORS_HPP

#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#  pragma once
#endif

#include "config_begin.hpp"
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
#include INCLUDE_BOOST_CONTAINER_MOVE_HPP

#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#include INCLUDE_BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#include INCLUDE_BOOST_CONTAINER_DETAIL_STORED_REF_HPP
#else
#include INCLUDE_BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
#endif

#include <iterator>

namespace boost {
namespace container { 

template <class T, class Difference = std::ptrdiff_t>
class constant_iterator
  : public std::iterator
      <std::random_access_iterator_tag, T, Difference, const T*, const T &>
{
   typedef  constant_iterator<T, Difference> this_type;

   public:
   explicit constant_iterator(const T &ref, Difference range_size)
      :  m_ptr(&ref), m_num(range_size){}

   //Constructors
   constant_iterator()
      :  m_ptr(0), m_num(0){}

   constant_iterator& operator++() 
   { increment();   return *this;   }
   
   constant_iterator operator++(int)
   {
      constant_iterator result (*this);
      increment();
      return result;
   }

   constant_iterator& operator--() 
   { decrement();   return *this;   }
   
   constant_iterator operator--(int)
   {
      constant_iterator result (*this);
      decrement();
      return result;
   }

   friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
   { return i.equal(i2); }

   friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
   { return !(i == i2); }

   friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
   { return i.less(i2); }

   friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
   { return i2 < i; }

   friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
   { return !(i > i2); }

   friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
   { return !(i < i2); }

   friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
   { return i2.distance_to(i); }

   //Arithmetic
   constant_iterator& operator+=(Difference off)
   {  this->advance(off); return *this;   }

   constant_iterator operator+(Difference off) const
   {
      constant_iterator other(*this);
      other.advance(off);
      return other;
   }

   friend constant_iterator operator+(Difference off, const constant_iterator& right)
   {  return right + off; }

   constant_iterator& operator-=(Difference off)
   {  this->advance(-off); return *this;   }

   constant_iterator operator-(Difference off) const
   {  return *this + (-off);  }

   const T& operator*() const
   { return dereference(); }

   const T& operator[] (Difference n) const
   { return dereference(); }

   const T* operator->() const
   { return &(dereference()); }

   private:
   const T *   m_ptr;
   Difference  m_num;

   void increment()
   { --m_num; }

   void decrement()
   { ++m_num; }

   bool equal(const this_type &other) const
   {  return m_num == other.m_num;   }

   bool less(const this_type &other) const
   {  return other.m_num < m_num;   }

   const T & dereference() const
   { return *m_ptr; }

   void advance(Difference n)
   {  m_num -= n; }

   Difference distance_to(const this_type &other)const
   {  return m_num - other.m_num;   }
};

template <class T, class Difference = std::ptrdiff_t>
class default_construct_iterator
  : public std::iterator
      <std::random_access_iterator_tag, T, Difference, const T*, const T &>
{
   typedef  default_construct_iterator<T, Difference> this_type;

   public:
   explicit default_construct_iterator(Difference range_size)
      :  m_num(range_size){}

   //Constructors
   default_construct_iterator()
      :  m_num(0){}

   default_construct_iterator& operator++() 
   { increment();   return *this;   }
   
   default_construct_iterator operator++(int)
   {
      default_construct_iterator result (*this);
      increment();
      return result;
   }

   default_construct_iterator& operator--() 
   { decrement();   return *this;   }
   
   default_construct_iterator operator--(int)
   {
      default_construct_iterator result (*this);
      decrement();
      return result;
   }

   friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2)
   { return i.equal(i2); }

   friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2)
   { return !(i == i2); }

   friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2)
   { return i.less(i2); }

   friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2)
   { return i2 < i; }

   friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2)
   { return !(i > i2); }

   friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2)
   { return !(i < i2); }

   friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2)
   { return i2.distance_to(i); }

   //Arithmetic
   default_construct_iterator& operator+=(Difference off)
   {  this->advance(off); return *this;   }

   default_construct_iterator operator+(Difference off) const
   {
      default_construct_iterator other(*this);
      other.advance(off);
      return other;
   }

   friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right)
   {  return right + off; }

   default_construct_iterator& operator-=(Difference off)
   {  this->advance(-off); return *this;   }

   default_construct_iterator operator-(Difference off) const
   {  return *this + (-off);  }

   const T& operator*() const
   { return dereference(); }

   const T* operator->() const
   { return &(dereference()); }

   const T& operator[] (Difference n) const
   { return dereference(); }

   private:
   Difference  m_num;

   void increment()
   { --m_num; }

   void decrement()
   { ++m_num; }

   bool equal(const this_type &other) const
   {  return m_num == other.m_num;   }

   bool less(const this_type &other) const
   {  return other.m_num < m_num;   }

   const T & dereference() const
   { 
      static T dummy;
      return dummy;
   }

   void advance(Difference n)
   {  m_num -= n; }

   Difference distance_to(const this_type &other)const
   {  return m_num - other.m_num;   }
};

template <class T, class Difference = std::ptrdiff_t>
class repeat_iterator
  : public std::iterator
      <std::random_access_iterator_tag, T, Difference>
{
   typedef repeat_iterator<T, Difference> this_type;
   public:
   explicit repeat_iterator(T &ref, Difference range_size)
      :  m_ptr(&ref), m_num(range_size){}

   //Constructors
   repeat_iterator()
      :  m_ptr(0), m_num(0){}

   this_type& operator++() 
   { increment();   return *this;   }
   
   this_type operator++(int)
   {
      this_type result (*this);
      increment();
      return result;
   }

   this_type& operator--() 
   { increment();   return *this;   }
   
   this_type operator--(int)
   {
      this_type result (*this);
      increment();
      return result;
   }

   friend bool operator== (const this_type& i, const this_type& i2)
   { return i.equal(i2); }

   friend bool operator!= (const this_type& i, const this_type& i2)
   { return !(i == i2); }

   friend bool operator< (const this_type& i, const this_type& i2)
   { return i.less(i2); }

   friend bool operator> (const this_type& i, const this_type& i2)
   { return i2 < i; }

   friend bool operator<= (const this_type& i, const this_type& i2)
   { return !(i > i2); }

   friend bool operator>= (const this_type& i, const this_type& i2)
   { return !(i < i2); }

   friend Difference operator- (const this_type& i, const this_type& i2)
   { return i2.distance_to(i); }

   //Arithmetic
   this_type& operator+=(Difference off)
   {  this->advance(off); return *this;   }

   this_type operator+(Difference off) const
   {
      this_type other(*this);
      other.advance(off);
      return other;
   }

   friend this_type operator+(Difference off, const this_type& right)
   {  return right + off; }

   this_type& operator-=(Difference off)
   {  this->advance(-off); return *this;   }

   this_type operator-(Difference off) const
   {  return *this + (-off);  }

   T& operator*() const
   { return dereference(); }

   T& operator[] (Difference n) const
   { return dereference(); }

   T *operator->() const
   { return &(dereference()); }

   private:
   T *         m_ptr;
   Difference  m_num;

   void increment()
   { --m_num; }

   void decrement()
   { ++m_num; }

   bool equal(const this_type &other) const
   {  return m_num == other.m_num;   }

   bool less(const this_type &other) const
   {  return other.m_num < m_num;   }

   T & dereference() const
   { return *m_ptr; }

   void advance(Difference n)
   {  m_num -= n; }

   Difference distance_to(const this_type &other)const
   {  return m_num - other.m_num;   }
};

template <class T, class E>
class emplace_iterator
  : public std::iterator
      <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &>
{
   typedef emplace_iterator this_type;

   public:
   explicit emplace_iterator(E&e)
      :  m_num(1), m_pe(&e){}

   emplace_iterator()
      :  m_num(0), m_pe(0){}

   this_type& operator++() 
   { increment();   return *this;   }
   
   this_type operator++(int)
   {
      this_type result (*this);
      increment();
      return result;
   }

   this_type& operator--() 
   { decrement();   return *this;   }
   
   this_type operator--(int)
   {
      this_type result (*this);
      decrement();
      return result;
   }

   friend bool operator== (const this_type& i, const this_type& i2)
   { return i.equal(i2); }

   friend bool operator!= (const this_type& i, const this_type& i2)
   { return !(i == i2); }

   friend bool operator< (const this_type& i, const this_type& i2)
   { return i.less(i2); }

   friend bool operator> (const this_type& i, const this_type& i2)
   { return i2 < i; }

   friend bool operator<= (const this_type& i, const this_type& i2)
   { return !(i > i2); }

   friend bool operator>= (const this_type& i, const this_type& i2)
   { return !(i < i2); }

   friend std::ptrdiff_t operator- (const this_type& i, const this_type& i2)
   { return i2.distance_to(i); }

   //Arithmetic
   this_type& operator+=(std::ptrdiff_t off)
   {  this->advance(off); return *this;   }

   this_type operator+(std::ptrdiff_t off) const
   {
      this_type other(*this);
      other.advance(off);
      return other;
   }

   friend this_type operator+(std::ptrdiff_t off, const this_type& right)
   {  return right + off; }

   this_type& operator-=(std::ptrdiff_t off)
   {  this->advance(-off); return *this;   }

   this_type operator-(std::ptrdiff_t off) const
   {  return *this + (-off);  }

   const T& operator*() const
   { return dereference(); }

   const T& operator[](std::ptrdiff_t) const
   { return dereference(); }

   const T* operator->() const
   { return &(dereference()); }

   void construct_in_place(T* ptr)
   {  (*m_pe)(ptr);  }

   private:
   std::ptrdiff_t m_num;
   E *            m_pe;

   void increment()
   { --m_num; }

   void decrement()
   { ++m_num; }

   bool equal(const this_type &other) const
   {  return m_num == other.m_num;   }

   bool less(const this_type &other) const
   {  return other.m_num < m_num;   }

   const T & dereference() const
   { 
      static T dummy;
      return dummy;
   }

   void advance(std::ptrdiff_t n)
   {  m_num -= n; }

   std::ptrdiff_t distance_to(const this_type &other)const
   {  return m_num - other.m_num;   }
};

#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING

template<class T, class ...Args>
struct emplace_functor
{
   typedef typename containers_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;

   emplace_functor(Args&&... args)
      : args_(args...)
   {}

   void operator()(T *ptr)
   {  emplace_functor::inplace_impl(ptr, index_tuple_t());  }

   template<int ...IdxPack>
   void inplace_impl(T* ptr, const containers_detail::index_tuple<IdxPack...>&)
   {  ::new(ptr) T(containers_detail::stored_ref<Args>::forward(containers_detail::get<IdxPack>(args_))...); }

   containers_detail::tuple<Args&...> args_;
};

#else

template<class T>
struct emplace_functor
{
   emplace_functor()
   {}
   void operator()(T *ptr)
   {  new(ptr) T();  }
};

#define BOOST_PP_LOCAL_MACRO(n)                                                        \
   template <class T, BOOST_PP_ENUM_PARAMS(n, class P) >                               \
   struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                          \
   {                                                                                   \
      BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                              \
         ( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) )                       \
      :  BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {}                       \
                                                                                       \
      void operator()(T *ptr)                                                          \
      {                                                                                \
         new(ptr)T (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _));          \
      }                                                                                \
      BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _)                         \
   };                                                                                  \
   //!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()

#endif

}  //namespace container { 
}  //namespace boost {

#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP

#endif   //#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP

