/* -----------------------------------------------------------------------------
 * See the LICENSE file for information on copyright, usage and redistribution
 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
 *
 * rubyiterators.swg
 *
 * Implement a C++ 'output' iterator for Ruby.
 *
 * Users can derive form the Iterator to implemet their
 * own iterators. As an example (real one since we use it for STL/STD
 * containers), the template Iterator_T does the
 * implementation for generic C++ iterators.
 * ----------------------------------------------------------------------------- */

%include <std_common.i>


%fragment("ConstIterator","header") {  
namespace swig {
  struct stop_iteration {
  };

  /** 
   * Abstract base class used to represent all iterators of STL containers.
   */
  struct ConstIterator {
  public:
    typedef ConstIterator self_type;

  protected:
    GC_VALUE _seq;

  protected:
    ConstIterator(VALUE seq) : _seq(seq)
    {
    }

    // Random access iterator methods, but not required in Ruby
    virtual ptrdiff_t distance(const ConstIterator &x) const
    {
      throw std::invalid_argument("distance not supported");
    }

    virtual bool equal (const ConstIterator &x) const
    {
      throw std::invalid_argument("equal not supported");
    }

    virtual self_type* advance(ptrdiff_t n)
    {
      throw std::invalid_argument("advance not supported");
    }
      
  public:
    virtual ~ConstIterator() {}

    // Access iterator method, required by Ruby
    virtual VALUE value() const {
      throw std::invalid_argument("value not supported");
      return Qnil;
    };

    virtual VALUE setValue( const VALUE& v ) {
      throw std::invalid_argument("value= not supported");
      return Qnil;
    }

    virtual self_type* next( size_t n = 1 )
    {
      return this->advance( n );
    }

    virtual self_type* previous( size_t n = 1 )
    {
      ptrdiff_t nn = n;
      return this->advance( -nn );
    }

    virtual VALUE to_s() const {
      throw std::invalid_argument("to_s not supported");
      return Qnil;
    }

    virtual VALUE inspect() const {
      throw std::invalid_argument("inspect not supported");
      return Qnil;
    }
    
    virtual ConstIterator *dup() const
    {
      throw std::invalid_argument("dup not supported");
      return NULL;
    }

    //
    // C++ common/needed methods.  We emulate a bidirectional
    // operator, to be compatible with all the STL.
    // The iterator traits will then tell the STL what type of
    // iterator we really are.
    //
    ConstIterator() : _seq( Qnil )
    {
    }

    ConstIterator( const self_type& b ) : _seq( b._seq )
    {
    }

    self_type& operator=( const self_type& b )
    {
      _seq = b._seq;
      return *this;
    }

    bool operator == (const ConstIterator& x)  const
    {
      return equal(x);
    }
      
    bool operator != (const ConstIterator& x) const
    {
      return ! operator==(x);
    }
      
    // Pre-decrement operator
    self_type& operator--()
    {
      return *previous();
    }

    // Pre-increment operator
    self_type& operator++()
    {
      return *next();
    }

    // Post-decrement operator
    self_type operator--(int)
    {
      self_type r = *this;
      previous();
      return r;
    }

    // Post-increment operator
    self_type operator++(int)
    {
      self_type r = *this;
      next();
      return r;
    }

    ConstIterator& operator += (ptrdiff_t n)
    {
      return *advance(n);
    }

    ConstIterator& operator -= (ptrdiff_t n)
    {
      return *advance(-n);
    }

    ConstIterator* operator + (ptrdiff_t n) const
    {
      return dup()->advance(n);
    }

    ConstIterator* operator - (ptrdiff_t n) const
    {
      return dup()->advance(-n);
    }
      
    ptrdiff_t operator - (const ConstIterator& x) const
    {
      return x.distance(*this);
    }
      
    static swig_type_info* descriptor() {
      static int init = 0;
      static swig_type_info* desc = 0;
      if (!init) {
	desc = SWIG_TypeQuery("swig::ConstIterator *");
	init = 1;
      }	
      return desc;
    }
  };


  /**
   * Abstract base class used to represent all non-const iterators of STL containers.
   * 
   */
  struct Iterator : public ConstIterator {
  public:
    typedef Iterator self_type;

  protected:
    Iterator(VALUE seq) : ConstIterator(seq)
    {
    }

    virtual self_type* advance(ptrdiff_t n)
    {
      throw std::invalid_argument("operation not supported");
    }

  public:
    static swig_type_info* descriptor() {
      static int init = 0;
      static swig_type_info* desc = 0;
      if (!init) {
	desc = SWIG_TypeQuery("swig::Iterator *");
	init = 1;
      }	
      return desc;
    }
    
    virtual Iterator *dup() const
    {
      throw std::invalid_argument("dup not supported");
      return NULL;
    }
      
    virtual self_type* next( size_t n = 1 )
    {
      return this->advance( n );
    }

    virtual self_type* previous( size_t n = 1 )
    {
      ptrdiff_t nn = n;
      return this->advance( -nn );
    }

    bool operator == (const ConstIterator& x)  const
    {
      return equal(x);
    }
      
    bool operator != (const Iterator& x) const
    {
      return ! operator==(x);
    }
      
    Iterator& operator += (ptrdiff_t n)
    {
      return *advance(n);
    }

    Iterator& operator -= (ptrdiff_t n)
    {
      return *advance(-n);
    }
      
    Iterator* operator + (ptrdiff_t n) const
    {
      return dup()->advance(n);
    }

    Iterator* operator - (ptrdiff_t n) const
    {
      return dup()->advance(-n);
    }
      
    ptrdiff_t operator - (const Iterator& x) const
    {
      return x.distance(*this);
    }
  };

}
}


%fragment("ConstIterator_T","header",fragment="ConstIterator",fragment="StdTraits",fragment="StdIteratorTraits") {
namespace swig {

  /** 
   * Templated base classes for all custom const_iterators.
   *
   */
  template<typename OutConstIterator>
  class ConstIterator_T :  public ConstIterator
  {
  public:
    typedef OutConstIterator const_iter;
    typedef typename std::iterator_traits<const_iter>::value_type value_type;    
    typedef ConstIterator_T<const_iter> self_type;

  protected:

    
    virtual bool equal (const ConstIterator &iter) const
    {
      const self_type *iters = dynamic_cast<const self_type *>(&iter);
      if (iters) {
	return (current == iters->get_current());
      } else {
	throw std::invalid_argument("bad iterator type");
      }
    }
    
    virtual ptrdiff_t distance(const ConstIterator &iter) const
    {
      const self_type *iters = dynamic_cast<const self_type *>(&iter);
      if (iters) {
	return std::distance(current, iters->get_current());
      } else {
	throw std::invalid_argument("bad iterator type");
      }
    }

    virtual ConstIterator* advance(ptrdiff_t n)
    {
      std::advance( current, n );
      return this;
    }

  public:
    ConstIterator_T() : ConstIterator(Qnil)
    {
    }

    ConstIterator_T(const_iter curr, VALUE seq = Qnil)
      : ConstIterator(seq), current(curr)
    {
    }

    const const_iter& get_current() const
    {
      return current;
    }

    const value_type& operator*() const
    {
      return *current;
    }

    virtual VALUE inspect() const
    {
      VALUE ret = rb_str_new2("#<");
      ret = rb_str_cat2( ret, rb_obj_classname(_seq) );
      ret = rb_str_cat2( ret, "::const_iterator " );
      VALUE cur = value();
      ret = rb_str_concat( ret, rb_inspect(cur) );
      ret = rb_str_cat2( ret, ">" );
      return ret;
    }

    virtual VALUE to_s()    const
    {
      VALUE ret = rb_str_new2( rb_obj_classname(_seq) );
      ret = rb_str_cat2( ret, "::const_iterator " );
      VALUE cur = value();
      ret = rb_str_concat( ret, rb_obj_as_string(cur) );
      return ret;
    }

  protected:
    const_iter current;
  };


  /** 
   * Templated base classes for all custom non-const iterators.
   *
   */
  template<typename InOutIterator>
  class Iterator_T :  public Iterator
  {
  public:
    typedef InOutIterator nonconst_iter;

    // Make this class iterator STL compatible, by using iterator_traits
    typedef typename std::iterator_traits<nonconst_iter >::iterator_category iterator_category;
    typedef typename std::iterator_traits<nonconst_iter >::value_type        value_type;
    typedef typename std::iterator_traits<nonconst_iter >::difference_type   difference_type;
    typedef typename std::iterator_traits<nonconst_iter >::pointer           pointer;
    typedef typename std::iterator_traits<nonconst_iter >::reference         reference;

    typedef Iterator                         base;
    typedef Iterator_T< nonconst_iter > self_type;

  protected:

    virtual bool equal (const ConstIterator &iter) const
    {
      const self_type *iters = dynamic_cast<const self_type *>(&iter);
      if (iters) {
	return (current == iters->get_current());
      } else {
	throw std::invalid_argument("bad iterator type");
      }
    }
    
    virtual ptrdiff_t distance(const ConstIterator &iter) const
    {
      const self_type *iters = dynamic_cast<const self_type *>(&iter);
      if (iters) {
	return std::distance(current, iters->get_current());
      } else {
	throw std::invalid_argument("bad iterator type");
      }
    }

    virtual Iterator* advance(ptrdiff_t n)
    {
      std::advance( current, n );
      return this;
    }

  public:

    Iterator_T(nonconst_iter curr, VALUE seq = Qnil)
      : Iterator(seq), current(curr)
    {
    }

    const nonconst_iter& get_current() const
    {
      return current;
    }

    self_type& operator=( const self_type& b )
    {
      base::operator=( b );
      return *this;
    }
    
    self_type& operator=( const value_type& b )
    {
      *current = b;
      return *this;
    }

    const value_type& operator*() const
    {
      return *current;
    }

    value_type& operator*()
    {
      return *current;
    }
    
    virtual VALUE inspect() const
    {
      VALUE ret = rb_str_new2("#<");
      ret = rb_str_cat2( ret, rb_obj_classname(_seq) );
      ret = rb_str_cat2( ret, "::iterator " );
      VALUE cur = value();
      ret = rb_str_concat( ret, rb_inspect(cur) );
      ret = rb_str_cat2( ret, ">" );
      return ret;
    }

    virtual VALUE to_s()    const
    {
      VALUE ret = rb_str_new2( rb_obj_classname(_seq) );
      ret = rb_str_cat2( ret, "::iterator " );
      VALUE cur = value();
      ret = rb_str_concat( ret, rb_obj_as_string(cur) );
      return ret;
    }

  protected:
    nonconst_iter current;
  };


  /**
   * Auxiliary functor to store the value of a ruby object inside
   * a reference of a compatible C++ type.  ie: Ruby -> C++
   * 
   */
  template <class ValueType>
  struct asval_oper 
  {
    typedef ValueType    value_type;
    typedef bool        result_type;
    bool operator()(VALUE obj, value_type& v) const
    {
      return ( swig::asval< value_type >(obj, &v) == SWIG_OK );
    }
  };

  /**
   * Auxiliary functor to return a ruby object from a C++ type. 
   * ie: C++ -> Ruby
   * 
   */
  template <class ValueType>
  struct from_oper 
  {
    typedef const ValueType& argument_type;
    typedef VALUE result_type;
    result_type operator()(argument_type v) const
    {
      return swig::from(v);
    }
  };


  /** 
   * ConstIterator class for a const_iterator with no end() boundaries.
   *
   */
  template<typename OutConstIterator, 
	   typename ValueType = typename std::iterator_traits<OutConstIterator>::value_type,
	   typename FromOper = from_oper<ValueType> >
  class ConstIteratorOpen_T :  public ConstIterator_T<OutConstIterator>
  {
  public:
    FromOper from;
    typedef OutConstIterator const_iter;
    typedef ValueType value_type;
    typedef ConstIterator_T<const_iter>  base;
    typedef ConstIteratorOpen_T<OutConstIterator, ValueType, FromOper> self_type;
    
    ConstIteratorOpen_T(const_iter curr, VALUE seq = Qnil)
      : ConstIterator_T<OutConstIterator>(curr, seq)
    {
    }
    
    virtual VALUE value() const {
      return from(static_cast<const value_type&>(*(base::current)));
    }
    
    ConstIterator *dup() const
    {
      return new self_type(*this);
    }
  };

  /** 
   * Iterator class for an iterator with no end() boundaries.
   *
   */
  template<typename InOutIterator, 
	   typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
	   typename FromOper = from_oper<ValueType>,
	   typename AsvalOper = asval_oper<ValueType> >
  class IteratorOpen_T :  public Iterator_T<InOutIterator>
  {
  public:
    FromOper  from;
    AsvalOper asval;
    typedef InOutIterator nonconst_iter;
    typedef ValueType value_type;
    typedef Iterator_T<nonconst_iter>  base;
    typedef IteratorOpen_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;

  public:
    IteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil)
      : Iterator_T<InOutIterator>(curr, seq)
    {
    }
    
    virtual VALUE value() const {
      return from(static_cast<const value_type&>(*(base::current)));
    }

    virtual VALUE setValue( const VALUE& v )
    {
      value_type& dst = *base::current;
      if ( asval(v, dst) ) return v;
      return Qnil;
    }
    
    Iterator *dup() const
    {
      return new self_type(*this);
    }
  };

  /** 
   * ConstIterator class for a const_iterator where begin() and end() boundaries are known.
   *
   */
  template<typename OutConstIterator, 
	   typename ValueType = typename std::iterator_traits<OutConstIterator>::value_type,
	   typename FromOper = from_oper<ValueType> >
  class ConstIteratorClosed_T :  public ConstIterator_T<OutConstIterator>
  {
  public:
    FromOper from;
    typedef OutConstIterator const_iter;
    typedef ValueType value_type;
    typedef ConstIterator_T<const_iter>  base;    
    typedef ConstIteratorClosed_T<OutConstIterator, ValueType, FromOper> self_type;
    
  protected:
    virtual ConstIterator* advance(ptrdiff_t n)
    {
      std::advance( base::current, n );
      if ( base::current == end )
	throw stop_iteration();
      return this;
    }

  public:
    ConstIteratorClosed_T(const_iter curr, const_iter first, 
			  const_iter last, VALUE seq = Qnil)
      : ConstIterator_T<OutConstIterator>(curr, seq), begin(first), end(last)
    {
    }
    
    virtual VALUE value() const {
      if (base::current == end) {
	throw stop_iteration();
      } else {
	return from(static_cast<const value_type&>(*(base::current)));
      }
    }
    
    ConstIterator *dup() const
    {
      return new self_type(*this);
    }


  private:
    const_iter begin;
    const_iter end;
  };

  /** 
   * Iterator class for a iterator where begin() and end() boundaries are known.
   *
   */
  template<typename InOutIterator, 
	   typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
	   typename FromOper = from_oper<ValueType>,
	   typename AsvalOper = asval_oper<ValueType> >
  class IteratorClosed_T :  public Iterator_T<InOutIterator>
  {
  public:
    FromOper   from;
    AsvalOper asval;
    typedef InOutIterator nonconst_iter;
    typedef ValueType value_type;
    typedef Iterator_T<nonconst_iter>  base;
    typedef IteratorClosed_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
    
  protected:
    virtual Iterator* advance(ptrdiff_t n)
    {
      std::advance( base::current, n );
      if ( base::current == end )
	throw stop_iteration();
      return this;
    }

  public:
    IteratorClosed_T(nonconst_iter curr, nonconst_iter first, 
		     nonconst_iter last, VALUE seq = Qnil)
      : Iterator_T<InOutIterator>(curr, seq), begin(first), end(last)
    {
    }
    
    virtual VALUE value() const {
      if (base::current == end) {
	throw stop_iteration();
      } else {
	return from(static_cast<const value_type&>(*(base::current)));
      }
    }
    
    // Iterator setter method, required by Ruby
    virtual VALUE setValue( const VALUE& v )
    {
      if (base::current == end)
	throw stop_iteration();

      value_type& dst = *base::current;
      if ( asval( v, dst ) ) return v;
      return Qnil;
    }
    
    Iterator *dup() const
    {
      return new self_type(*this);
    }

  private:
    nonconst_iter begin;
    nonconst_iter end;
  };

  /* Partial specialization for bools which don't allow de-referencing */
  template< typename InOutIterator, typename FromOper, typename AsvalOper >
  class IteratorOpen_T< InOutIterator, bool, FromOper, AsvalOper > : 
    public Iterator_T<InOutIterator>
  {
  public:
    FromOper   from;
    AsvalOper asval;
    typedef InOutIterator nonconst_iter;
    typedef bool value_type;
    typedef Iterator_T<nonconst_iter>  base;
    typedef IteratorOpen_T<InOutIterator, bool, FromOper, AsvalOper> self_type;

    IteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil)
      : Iterator_T<InOutIterator>(curr, seq)
    {
    }

    virtual VALUE value() const {
      return from(static_cast<const value_type&>(*(base::current)));
    }
    
    virtual VALUE setValue( const VALUE& v )
    {
      bool tmp = *base::current;
      if ( asval( v, tmp ) )
	{
	  *base::current = tmp;
	  return v;
	}
      return Qnil;
    }    
    
    Iterator *dup() const
    {
      return new self_type(*this);
    }
    
  };

  /* Partial specialization for bools which don't allow de-referencing */
  template< typename InOutIterator, typename FromOper, typename AsvalOper >
  class IteratorClosed_T< InOutIterator, bool, FromOper, AsvalOper > : 
    public Iterator_T<InOutIterator>
  {
  public:
    FromOper   from;
    AsvalOper asval;
    typedef InOutIterator nonconst_iter;
    typedef bool value_type;
    typedef Iterator_T<nonconst_iter>  base;
    typedef IteratorClosed_T<InOutIterator, bool, FromOper, AsvalOper> self_type;
    
  protected:
    virtual Iterator* advance(ptrdiff_t n)
    {
      std::advance( base::current, n );
      if ( base::current == end )
	throw stop_iteration();
      return this;
    }

  public:
    IteratorClosed_T(nonconst_iter curr, nonconst_iter first, 
		     nonconst_iter last, VALUE seq = Qnil)
      : Iterator_T<InOutIterator>(curr, seq), begin(first), end(last)
    {
    }

    virtual VALUE value() const {
      if (base::current == end) {
	throw stop_iteration();
      } else {
	return from(static_cast<const value_type&>(*(base::current)));
      }
    }

    virtual VALUE setValue( const VALUE& v )
    {
      if (base::current == end)
	throw stop_iteration();

      bool tmp = *base::current;
      if ( asval( v, tmp ) )
	{
	  *base::current = tmp;
	  return v;
	}
      return Qnil;
    }
    
    Iterator *dup() const
    {
      return new self_type(*this);
    }

  private:
    nonconst_iter begin;
    nonconst_iter end;
  };


  /** 
   * Helper function used to wrap a bounded const_iterator.  This is to be used in
   * a %typemap(out), for example.
   *
   */
  template<typename InOutIter>
  inline Iterator*
  make_nonconst_iterator(const InOutIter& current, const InOutIter& begin,
			 const InOutIter& end, VALUE seq = Qnil)
  {
    return new IteratorClosed_T<InOutIter>(current, begin, end, seq);
  }

  /** 
   * Helper function used to wrap an unbounded const_iterator.  This is to be used in
   * a %typemap(out), for example.
   *
   */
  template<typename InOutIter>
  inline Iterator*
  make_nonconst_iterator(const InOutIter& current, VALUE seq = Qnil)
  {
    return new IteratorOpen_T<InOutIter>(current, seq);
  }

  /** 
   * Helper function used to wrap a bounded const_iterator.  This is to be used in
   * a %typemap(out), for example.
   *
   */
  template<typename OutIter>
  inline ConstIterator*
  make_const_iterator(const OutIter& current, const OutIter& begin,
                       const OutIter& end, VALUE seq = Qnil)
  {
    return new ConstIteratorClosed_T<OutIter>(current, begin, end, seq);
  }

  /** 
   * Helper function used to wrap an unbounded const_iterator.  This is to be used in
   * a %typemap(out), for example.
   *
   */
  template<typename OutIter>
  inline ConstIterator*
  make_const_iterator(const OutIter& current, VALUE seq = Qnil)
  {
    return new ConstIteratorOpen_T<OutIter>(current, seq);
  }
}
}


%fragment("ConstIterator");


//
// This part is just so SWIG is aware of the base abstract iterator class.
//
namespace swig 
{
  /*
    Throw a StopIteration exception
  */
  %ignore stop_iteration;
  struct stop_iteration {};
  
  %typemap(throws) stop_iteration {
    (void)$1;
    SWIG_Ruby_ExceptionType(NULL, Qnil);
    SWIG_fail;
  }

  /* 
     Mark methods that return new objects
  */
  %newobject ConstIterator::dup;
  %newobject ConstIterator::operator + (ptrdiff_t n) const;
  %newobject ConstIterator::operator - (ptrdiff_t n) const;

  %nodirector ConstIterator;

  %catches(swig::stop_iteration)  ConstIterator::value() const;
  %catches(swig::stop_iteration)  ConstIterator::incr(size_t n = 1);
  %catches(swig::stop_iteration)  ConstIterator::decr(size_t n = 1);
  %catches(std::invalid_argument) ConstIterator::distance(const ConstIterator &x) const;
  %catches(std::invalid_argument) ConstIterator::equal (const ConstIterator &x) const;
  %catches(swig::stop_iteration)  ConstIterator::next();
  %catches(swig::stop_iteration)  ConstIterator::previous();
  %catches(swig::stop_iteration)  ConstIterator::advance(ptrdiff_t n);
  %catches(swig::stop_iteration)  ConstIterator::operator += (ptrdiff_t n);
  %catches(swig::stop_iteration)  ConstIterator::operator -= (ptrdiff_t n);
  %catches(swig::stop_iteration)  ConstIterator::operator + (ptrdiff_t n) const;
  %catches(swig::stop_iteration)  ConstIterator::operator - (ptrdiff_t n) const;


  struct ConstIterator
  {
  protected:
    ConstIterator(VALUE seq);

  public:
    virtual ~ConstIterator();

    // Access iterator method, required by Ruby
    virtual VALUE value() const;
    
    // C++ common/needed methods
    virtual ConstIterator *dup() const;

    virtual VALUE inspect()    const;
    virtual VALUE to_s()    const;

    virtual ConstIterator* next(size_t n = 1);
    virtual ConstIterator* previous(size_t n = 1);

    bool operator == (const ConstIterator& x)  const;
    ConstIterator* operator + (ptrdiff_t n) const;
    ConstIterator* operator - (ptrdiff_t n) const;
    ptrdiff_t operator - (const ConstIterator& x) const;
  };

  struct Iterator : public ConstIterator
  {
    %rename("value=") setValue( const VALUE& v );
    virtual VALUE setValue( const VALUE& v );

    virtual Iterator *dup() const;

    virtual Iterator* next(size_t n = 1);
    virtual Iterator* previous(size_t n = 1);

    virtual VALUE inspect()    const;
    virtual VALUE to_s()    const;

    bool operator == (const Iterator& x)  const;
    Iterator* operator + (ptrdiff_t n) const;
    Iterator* operator - (ptrdiff_t n) const;
    ptrdiff_t operator - (const Iterator& x) const;
  };

}

