/* -----------------------------------------------------------------------------
 * sciiterators.swg
 *
 * Users can derive form the SciSwigIterator to implemet their
 * own iterators. As an example (real one since we use it for STL/STD
 * containers), the template SwigSciIterator_T does the
 * implementation for generic C++ iterators.
 * ----------------------------------------------------------------------------- */

%include <std_common.i>

%fragment("SciSwigIterator","header",fragment="<stddef.h>") {
namespace swig {
  struct stop_iteration {
  };

  struct SciSwigIterator {
  private:
    SwigSciObject _seq;

  protected:
    SciSwigIterator(SwigSciObject seq) : _seq(seq)
    {
    }

  public:
    virtual ~SciSwigIterator() {}

    virtual SwigSciObject value() const = 0;

    virtual SciSwigIterator *incr(size_t n = 1) = 0;

    virtual SciSwigIterator *decr(size_t n = 1)
    {
      throw stop_iteration();
    }

    virtual ptrdiff_t distance(const SciSwigIterator &x) const
    {
      throw std::invalid_argument("operation not supported");
    }

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

    virtual SciSwigIterator *copy() const = 0;

    SwigSciObject next()
    {
      SwigSciObject obj = value();
      incr();
      return obj;
    }

    SwigSciObject previous()
    {
      decr();
      return value();
    }

    SciSwigIterator *advance(ptrdiff_t n)
    {
      return  (n > 0) ?  incr(n) : decr(-n);
    }

    bool operator == (const SciSwigIterator& x)  const
    {
      return equal(x);
    }

    bool operator != (const SciSwigIterator& x) const
    {
      return ! operator==(x);
    }

    SciSwigIterator* operator ++ () {
      incr();
      return this;
    }

    SciSwigIterator* operator -- () {
      decr();
      return this;
    }

    SciSwigIterator* operator + (ptrdiff_t n) const
    {
      return copy()->advance(n);
    }

    SciSwigIterator* operator - (ptrdiff_t n) const
    {
      return copy()->advance(-n);
    }

    ptrdiff_t operator - (const SciSwigIterator& 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::SciSwigIterator *");
	init = 1;
      }
      return desc;
    }
  };
}
}

%fragment("SwigSciIterator_T","header",fragment="<stddef.h>",fragment="SciSwigIterator",fragment="StdTraits",fragment="StdIteratorTraits") {
namespace swig {
  template<typename OutIterator>
  class SwigSciIterator_T :  public SciSwigIterator
  {
  public:
    typedef OutIterator out_iterator;
    typedef typename std::iterator_traits<out_iterator>::value_type value_type;
    typedef SwigSciIterator_T<out_iterator> self_type;

    SwigSciIterator_T(out_iterator curr, SwigSciObject seq)
      : SciSwigIterator(seq), current(curr)
    {
    }

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


    bool equal (const SciSwigIterator &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");
      }
    }

    ptrdiff_t distance(const SciSwigIterator &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");
      }
    }

  protected:
    out_iterator current;
  };

  template <class ValueType>
  struct from_oper
  {
    typedef const ValueType& argument_type;
    typedef SwigSciObject result_type;
    result_type operator()(argument_type v) const
    {
      return swig::from(v);
    }
  };

  template<typename OutIterator,
	   typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
	   typename FromOper = from_oper<ValueType> >
  class SciSwigIteratorOpen_T :  public SwigSciIterator_T<OutIterator>
  {
  public:
    FromOper from;
    typedef OutIterator out_iterator;
    typedef ValueType value_type;
    typedef SwigSciIterator_T<out_iterator>  base;
    typedef SciSwigIteratorOpen_T<OutIterator, ValueType, FromOper> self_type;

    SciSwigIteratorOpen_T(out_iterator curr, SwigSciObject seq)
      : SwigSciIterator_T<OutIterator>(curr, seq)
    {
    }

    SwigSciObject value() const {
      return from(static_cast<const value_type&>(*(base::current)));
    }

    SciSwigIterator *copy() const
    {
      return new self_type(*this);
    }

    SciSwigIterator *incr(size_t n = 1)
    {
      while (n--) {
	++base::current;
      }
      return this;
    }

    SciSwigIterator *decr(size_t n = 1)
    {
      while (n--) {
	--base::current;
      }
      return this;
    }
  };

  template<typename OutIterator,
	   typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
	   typename FromOper = from_oper<ValueType> >
  class SciSwigIteratorClosed_T :  public SwigSciIterator_T<OutIterator>
  {
  public:
    FromOper from;
    typedef OutIterator out_iterator;
    typedef ValueType value_type;
    typedef SwigSciIterator_T<out_iterator>  base;
    typedef SciSwigIteratorClosed_T<OutIterator, ValueType, FromOper> self_type;

    SciSwigIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, SwigSciObject seq)
      : SwigSciIterator_T<OutIterator>(curr, seq), begin(first), end(last)
    {
    }

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

    SciSwigIterator *copy() const
    {
      return new self_type(*this);
    }

    SciSwigIterator *incr(size_t n = 1)
    {
      while (n--) {
	if (base::current == end) {
	  throw stop_iteration();
	} else {
	  ++base::current;
	}
      }
      return this;
    }

    SciSwigIterator *decr(size_t n = 1)
    {
      while (n--) {
	if (base::current == begin) {
	  throw stop_iteration();
	} else {
	  --base::current;
	}
      }
      return this;
    }

  private:
    out_iterator begin;
    out_iterator end;
  };

  template<typename OutIter>
  inline SciSwigIterator*
  make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, SwigSciObject seq = SwigSciObject())
  {
    return new SciSwigIteratorClosed_T<OutIter>(current, begin, end, seq);
  }

  template<typename OutIter>
  inline SciSwigIterator*
  make_output_iterator(const OutIter& current, SwigSciObject seq = SwigSciObject())
  {
    return new SciSwigIteratorOpen_T<OutIter>(current, seq);
  }
}
}


%fragment("SciSwigIterator");
namespace swig
{
// Throw a StopIteration exception
  %ignore stop_iteration;
  struct stop_iteration {};

  %typemap(throws, noblock=1) stop_iteration
  {
    SWIG_Scilab_Raise(0, "stop_iteration", NULL);
    return SWIG_ERROR;
  }

// Mark methods that return new objects
  %newobject SciSwigIterator::copy;
  %newobject SciSwigIterator::operator + (ptrdiff_t n) const;
  %newobject SciSwigIterator::operator - (ptrdiff_t n) const;

  %nodirector SciSwigIterator;

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

  %ignore SciSwigIterator::operator==;
  %ignore SciSwigIterator::operator!=;
  %ignore SciSwigIterator::operator++;
  %ignore SciSwigIterator::operator--;
  %ignore SciSwigIterator::operator+;
  %ignore SciSwigIterator::operator-;

  struct SciSwigIterator
  {
  protected:
    SciSwigIterator(SwigSciObject seq);

  public:
    virtual ~SciSwigIterator();

    virtual SwigSciObject value() const = 0;

    virtual SciSwigIterator *incr(size_t n = 1) = 0;

    virtual SciSwigIterator *decr(size_t n = 1);

    virtual ptrdiff_t distance(const SciSwigIterator &x) const;

    virtual bool equal (const SciSwigIterator &x) const;

    virtual SciSwigIterator *copy() const = 0;

    SwigSciObject next();
    SwigSciObject previous();
    SciSwigIterator *advance(ptrdiff_t n);

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