/* -----------------------------------------------------------------------------
 * rubycontainer.swg
 *
 * Ruby sequence <-> C++ container wrapper
 *
 * This wrapper, and its iterator, allows a general use (and reuse) of
 * the mapping between C++ and Ruby, thanks to the C++ templates.
 *
 * Of course, it needs the C++ compiler to support templates, but
 * since we will use this wrapper with the STL containers, that should
 * be the case.
 * ----------------------------------------------------------------------------- */

%{
#include <iostream>
%}


#if !defined(SWIG_NO_EXPORT_ITERATOR_METHODS)
# if !defined(SWIG_EXPORT_ITERATOR_METHODS)
#  define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS
# endif
#endif

%include <rubyiterators.swg>

/**** The RubySequence C++ Wrap ***/

%fragment("<stdexcept>");

%include <std_except.i>


%fragment("RubySequence_Base","header")
{
%#include <functional>


namespace swig {
  template < class T >
  struct yield
  {
    bool
    operator()( const T& v ) const
    { 
      return RTEST( rb_yield( swig::from< T >(v) ) );
    }
  };


  inline size_t
  check_index(ptrdiff_t i, size_t size, bool insert = false) {
    if ( i < 0 ) {
      if ((size_t) (-i) <= size)
	return (size_t) (i + size);
    } else if ( (size_t) i < size ) {
      return (size_t) i;
    } else if (insert && ((size_t) i == size)) {
      return size;
    }
    
    throw std::out_of_range("index out of range");
  }

  inline size_t
  slice_index(ptrdiff_t i, size_t size) {
    if ( i < 0 ) {
      if ((size_t) (-i) <= size) {
	return (size_t) (i + size);
      } else {
	throw std::out_of_range("index out of range");
      }
    } else {
      return ( (size_t) i < size ) ? ((size_t) i) : size;
    }
  }

  template <class Sequence, class Difference>
  inline typename Sequence::iterator
  getpos(Sequence* self, Difference i)  {
    typename Sequence::iterator pos = self->begin();
    std::advance(pos, check_index(i,self->size()));
    return pos;
  }

  template <class Sequence, class Difference>
  inline typename Sequence::const_iterator
  cgetpos(const Sequence* self, Difference i)  {
    typename Sequence::const_iterator pos = self->begin();
    std::advance(pos, check_index(i,self->size()));
    return pos;
  }

  template <class Sequence>
  inline void
  resize(Sequence *seq, typename Sequence::size_type n, typename Sequence::value_type x) {
    seq->resize(n, x);
  }

  template <class Sequence, class Difference>
  inline Sequence*
  getslice(const Sequence* self, Difference i, Difference j) {
    typename Sequence::size_type size = self->size();
    typename Sequence::size_type ii = swig::check_index(i, size, (i == size && j == size));
    typename Sequence::size_type jj = swig::slice_index(j, size);

    if (jj > ii) {
      typename Sequence::const_iterator vb = self->begin();
      typename Sequence::const_iterator ve = self->begin();
      std::advance(vb,ii);
      std::advance(ve,jj);
      return new Sequence(vb, ve);
    } else {
      return new Sequence();
    }
  }

  template <class Sequence, class Difference, class InputSeq>
  inline void
  setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) {
    typename Sequence::size_type size = self->size();
    typename Sequence::size_type ii = swig::check_index(i, size, true);
    typename Sequence::size_type jj = swig::slice_index(j, size);
    if (jj < ii) jj = ii;
    size_t ssize = jj - ii;
    if (ssize <= v.size()) {
      typename Sequence::iterator sb = self->begin();
      typename InputSeq::const_iterator vmid = v.begin();
      std::advance(sb,ii);
      std::advance(vmid, jj - ii);
      self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end());
    } else {
      typename Sequence::iterator sb = self->begin();
      typename Sequence::iterator se = self->begin();
      std::advance(sb,ii);
      std::advance(se,jj);
      self->erase(sb,se);
      self->insert(sb, v.begin(), v.end());
    }
  }

  template <class Sequence, class Difference>
  inline void
  delslice(Sequence* self, Difference i, Difference j) {
    typename Sequence::size_type size = self->size();
    typename Sequence::size_type ii = swig::check_index(i, size, true);
    typename Sequence::size_type jj = swig::slice_index(j, size);
    if (jj > ii) {
      typename Sequence::iterator sb = self->begin();
      typename Sequence::iterator se = self->begin();
      std::advance(sb,ii);
      std::advance(se,jj);
      self->erase(sb,se);
    }
  }
}
}

%fragment("RubySequence_Cont","header",
	  fragment="<stddef.h>",
	  fragment="StdTraits",
	  fragment="RubySequence_Base",
	  fragment="ConstIterator_T")
{
namespace swig
{

  /**
   * This class is a proxy class for references, used to return and set values
   * of an element of a Ruby Array of stuff.
   * It can be used by RubySequence_InputIterator to make it work with STL
   * algorithms.
   */
  template <class T>
  struct RubySequence_Ref
  {
    RubySequence_Ref(VALUE  seq, int index)
      : _seq(seq), _index(index)
    {
    }
    
    operator T () const
    {
      VALUE item = rb_ary_entry(_seq, _index );
      try {
	return swig::as<T>(item);
      } catch (const std::invalid_argument& e) {
	char msg[1024];
	sprintf(msg, "in sequence element %d ", _index);
	VALUE lastErr = rb_gv_get("$!");
	if ( lastErr == Qnil ) {
	  %type_error(swig::type_name<T>());
	}
	VALUE str = rb_str_new2(msg);
	str = rb_str_cat2( str, e.what() );
	SWIG_Ruby_ExceptionType( NULL, str );
	throw;
      }
    }

    RubySequence_Ref& operator=(const T& v)
    {
      rb_ary_set(_seq, _index, swig::from< T >(v));
      return *this;
    }

  private:
    VALUE  _seq;
    int _index;
  };


  /**
   * This class is a proxy to return a pointer to a class, usually
   * RubySequence_Ref. 
   * It can be used by RubySequence_InputIterator to make it work with STL
   * algorithms.
   */
  template <class T>
  struct RubySequence_ArrowProxy
  {
    RubySequence_ArrowProxy(const T& x): m_value(x) {}
    const T* operator->() const { return &m_value; }
    operator const T*() const { return &m_value; }
    T m_value;
  };


  /**
   * Input Iterator.  This adapator class is a random access iterator that 
   * allows you to use STL algorithms with a Ruby class (a Ruby Array by default).
   */
  template <class T, class Reference = RubySequence_Ref< T > >
  struct RubySequence_InputIterator
  {
    typedef RubySequence_InputIterator<T, Reference > self;

    typedef std::random_access_iterator_tag iterator_category;
    typedef Reference reference;
    typedef T value_type;
    typedef T* pointer;
    typedef ptrdiff_t difference_type;

    RubySequence_InputIterator()
    {
    }

    RubySequence_InputIterator(VALUE  seq, int index)
      : _seq(seq), _index(index)
    {
    }

    reference operator*() const
    {
      return reference(_seq, _index);
    }

    RubySequence_ArrowProxy<T>
    operator->() const {
      return RubySequence_ArrowProxy<T>(operator*());
    }

    bool operator==(const self& ri) const
    {
      return (_index == ri._index) && (_seq == ri._seq);
    }

    bool operator!=(const self& ri) const
    {
      return !(operator==(ri));
    }

    self& operator ++ ()
    {
      ++_index;
      return *this;
    }

    self& operator -- ()
    {
      --_index;
      return *this;
    }

    self& operator += (difference_type n)
    {
      _index += n;
      return *this;
    }

    self operator +(difference_type n) const
    {
      return self(_seq, _index + n);
    }

    self& operator -= (difference_type n)
    {
      _index -= n;
      return *this;
    }

    self operator -(difference_type n) const
    {
      return self(_seq, _index - n);
    }

    difference_type operator - (const self& ri) const
    {
      return _index - ri._index;
    }

    bool operator < (const self& ri) const
    {
      return _index < ri._index;
    }

    reference
    operator[](difference_type n) const
    {
      return reference(_seq, _index + n);
    }

  private:
    VALUE  _seq;
    difference_type _index;
  };


  /**
   * This adaptor class allows you to use a Ruby Array as if it was an STL
   * container, giving it begin(), end(), and iterators.
   */
  template <class T>
  struct RubySequence_Cont
  {
    typedef RubySequence_Ref<T> reference;
    typedef const RubySequence_Ref<T> const_reference;
    typedef T value_type;
    typedef T* pointer;
    typedef int difference_type;
    typedef int size_type;
    typedef const pointer const_pointer;
    typedef RubySequence_InputIterator<T, reference> iterator;
    typedef RubySequence_InputIterator<T, const_reference> const_iterator;

    RubySequence_Cont(VALUE  seq) : _seq(0)
    {
      if (!rb_obj_is_kind_of(seq, rb_cArray)) {
	throw std::invalid_argument("an Array is expected");
      }
      _seq = seq;
    }

    ~RubySequence_Cont()
    {
    }

    size_type size() const
    {
      return RARRAY_LEN(_seq);
    }

    bool empty() const
    {
      return size() == 0;
    }

    iterator begin()
    {
      return iterator(_seq, 0);
    }

    const_iterator begin() const
    {
      return const_iterator(_seq, 0);
    }

    iterator end()
    {
      return iterator(_seq, size());
    }

    const_iterator end() const
    {
      return const_iterator(_seq, size());
    }

    reference operator[](difference_type n)
    {
      return reference(_seq, n);
    }

    const_reference operator[](difference_type n)  const
    {
      return const_reference(_seq, n);
    }

    bool check(bool set_err = false) const
    {
      int s = (int) size();
      for (int i = 0; i < s; ++i) {
	VALUE item = rb_ary_entry(_seq, i );
	if (!swig::check<value_type>(item)) {
	  if (set_err) {
	    char msg[1024];
	    sprintf(msg, "in sequence element %d", i);
	    SWIG_Error(SWIG_RuntimeError, msg);
	  }
	  return false;
	}
      }
      return true;
    }

  private:
    VALUE  _seq;
  };

}
}

/** 
 * Macros used to typemap an STL iterator -> SWIGIterator conversion.
 */
%define %swig_sequence_iterator(Sequence...)
#if defined(SWIG_EXPORT_ITERATOR_METHODS)

  %typemap(out,noblock=1,fragment="RubySequence_Cont")
    const_iterator, const_reverse_iterator {
    $result = SWIG_NewPointerObj(swig::make_const_iterator(%static_cast($1,const $type &),
							   self),
				 swig::ConstIterator::descriptor(),SWIG_POINTER_OWN);
  }

  %typemap(out,noblock=1,fragment="RubySequence_Cont")
    iterator, reverse_iterator {
    $result = SWIG_NewPointerObj(swig::make_nonconst_iterator(%static_cast($1,const $type &),
							      self),
				 swig::Iterator::descriptor(),SWIG_POINTER_OWN);
  }

  %typemap(out,noblock=1,fragment="RubySequence_Cont")
    std::pair<const_iterator, const_iterator> {
    $result = rb_ary_new2(2);
    rb_ary_push($result, SWIG_NewPointerObj(swig::make_const_iterator(%static_cast($1,const $type &).first),
					    swig::ConstIterator::descriptor(),SWIG_POINTER_OWN));
    rb_ary_push($result, SWIG_NewPointerObj(swig::make_const_iterator(%static_cast($1,const $type &).second),
					    swig::ConstIterator::descriptor(),SWIG_POINTER_OWN));
  }

  // std::map/multimap/set allow returning std::pair< iterator, iterator > from
  // equal_range, but we cannot still modify the key, so the iterator is
  // const.
  %typemap(out,noblock=1,fragment="RubySequence_Cont")
    std::pair<iterator, iterator> {
    $result = rb_ary_new2(2);
    rb_ary_push($result, SWIG_NewPointerObj(swig::make_const_iterator(%static_cast($1,const $type &).first),
					    swig::ConstIterator::descriptor(),SWIG_POINTER_OWN));
    rb_ary_push($result, SWIG_NewPointerObj(swig::make_const_iterator(%static_cast($1,const $type &).second),
					    swig::ConstIterator::descriptor(),SWIG_POINTER_OWN));
  }


  %typemap(in,noblock=1,fragment="RubySequence_Cont")
    const_iterator(swig::ConstIterator *iter = 0, int res),
    const_reverse_iterator(swig::ConstIterator *iter = 0, int res) {
    res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::ConstIterator::descriptor(), 0);
    if (!SWIG_IsOK(res) || !iter) {
      %argument_fail(SWIG_TypeError, "$type", $symname, $argnum);
    } else {
      swig::ConstIterator_T<$type > *iter_t = dynamic_cast<swig::ConstIterator_T<$type > *>(iter);
      if (iter_t) {
	$1 = iter_t->get_current();
      } else {
	%argument_fail(SWIG_TypeError, "$type", $symname, $argnum);
      }
    }
  }

  %typemap(in,noblock=1,fragment="RubySequence_Cont")
    iterator(swig::Iterator *iter = 0, int res),
    reverse_iterator(swig::Iterator *iter = 0, int res) {
    res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::Iterator::descriptor(), 0);
    if (!SWIG_IsOK(res) || !iter) {
      %argument_fail(SWIG_TypeError, "$type", $symname, $argnum);
    } else {
      swig::Iterator_T<$type > *iter_t = dynamic_cast<swig::Iterator_T<$type > *>(iter);
      if (iter_t) {
	$1 = iter_t->get_current();
      } else {
	%argument_fail(SWIG_TypeError, "$type", $symname, $argnum);
      }
    }
  }

  %typecheck(%checkcode(ITERATOR),noblock=1,fragment="RubySequence_Cont")
    const_iterator, const_reverse_iterator {
    swig::ConstIterator *iter = 0;
    int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::ConstIterator::descriptor(), 0);
    $1 = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::ConstIterator_T<$type > *>(iter) != 0));
  }

  %typecheck(%checkcode(ITERATOR),noblock=1,fragment="RubySequence_Cont")
    iterator, reverse_iterator {
    swig::ConstIterator *iter = 0;
    int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::Iterator::descriptor(), 0);
    $1 = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::Iterator_T<$type > *>(iter) != 0));
  }

  %fragment("RubySequence_Cont");

//   %newobject iterator;
//   %newobject const_iterator;
//   %extend  {
//     swig::Iterator* iterator(VALUE* RUBY_SELF) {
//       return swig::make_nonconst_iterator($self->begin(), $self->begin(), 
// 				             $self->end(), *RUBY_SELF);
//     }

//     swig::ConstIterator* const_iterator(VALUE* RUBY_SELF) {
//       return swig::make_const_iterator($self->begin(), $self->begin(), 
// 					$self->end(), *RUBY_SELF);
//     }
//   }
#endif //SWIG_EXPORT_ITERATOR_METHODS
%enddef


/**** The Ruby container methods  ****/



%define %swig_container_methods(Container...)

  %extend {

  %newobject dup;
  Container* dup()
    {
      return new Container(*$self);
    }

  }

%enddef


/**
 * Macro used to define common Ruby printing methods for STL container
 */
%define %swig_sequence_printing_methods(Sequence...)

  %extend {

  VALUE inspect()
    {
      Sequence::const_iterator i = $self->begin();
      Sequence::const_iterator e = $self->end();
      const char *type_name = swig::type_name< Sequence >();
      VALUE str = rb_str_new2(type_name);
      str = rb_str_cat2( str, " [" );
      bool comma = false;
      VALUE tmp;
      for ( ; i != e; ++i, comma = true )
	{
	  if (comma) str = rb_str_cat2( str, "," );
	  tmp = swig::from< Sequence::value_type >( *i );
	  tmp = rb_inspect( tmp );
	  str = rb_str_buf_append( str, tmp );
	}
      str = rb_str_cat2( str, "]" );
      return str;
    }

  VALUE to_a()
    {
      Sequence::const_iterator i = $self->begin();
      Sequence::const_iterator e = $self->end();
      VALUE ary = rb_ary_new2( std::distance( i, e ) );
      VALUE tmp;
      for ( ; i != e; ++i )
	{
	  tmp = swig::from< Sequence::value_type >( *i );
	  rb_ary_push( ary, tmp );
	}
      return ary;
    }

  VALUE to_s()
    {
      Sequence::iterator i = $self->begin();
      Sequence::iterator e = $self->end();
      VALUE str = rb_str_new2( "" );
      VALUE tmp;
      for ( ; i != e; ++i )
	{
	  tmp = swig::from< Sequence::value_type >( *i );
	  tmp = rb_obj_as_string( tmp );
	  str = rb_str_buf_append( str, tmp );
	}
      return str;
    }
}
%enddef


/**
 * Macro used to add common methods to all STL sequence-type containers 
 */
%define %swig_sequence_methods_non_resizable_common(Sequence...)
  %swig_container_methods(%arg(Sequence))
  %swig_sequence_iterator(%arg(Sequence))
  %swig_sequence_printing_methods(%arg(Sequence))

  %fragment("RubySequence_Base");

  %extend {

  VALUE slice( difference_type i, difference_type length ) throw (std::invalid_argument) {
      if ( length < 0 )
        return Qnil;
      std::size_t len = $self->size();
      if ( i < 0 ) {
        if ( i + static_cast<Sequence::difference_type>(len) < 0 )
          return Qnil;
        else
          i = len + i;
      }
      Sequence::difference_type j = length + i;
      if ( j > static_cast<Sequence::difference_type>(len) )
        j = len;

      VALUE r = Qnil;
      try {
	r = swig::from< const Sequence* >( swig::getslice(self, i, j) );
      }
      catch( std::out_of_range ) {
      }
      return r;
    }


    Sequence* each()
      {
	if ( !rb_block_given_p() )
	  rb_raise( rb_eArgError, "no block given");

	VALUE r;
	Sequence::const_iterator i = self->begin();
	Sequence::const_iterator e = self->end();
	for ( ; i != e; ++i )
	  {
	    r = swig::from< Sequence::value_type >(*i);
	    rb_yield(r);
	  }
	
	return self;
      }

    VALUE __delete2__(const value_type& i) {
      VALUE r = Qnil;
      return r;
    }

  }
%enddef

%define %swig_sequence_methods_resizable_common(Sequence...)
  %extend {

    %newobject select;
    Sequence* select() {
      if ( !rb_block_given_p() )
	rb_raise( rb_eArgError, "no block given" );

      Sequence* r = new Sequence();
      Sequence::const_iterator i = $self->begin();
      Sequence::const_iterator e = $self->end();
      for ( ; i != e; ++i )
	{
	  VALUE v = swig::from< Sequence::value_type >(*i);
	  if ( RTEST( rb_yield(v) ) )
	    $self->insert( r->end(), *i);
	}
	
      return r;
    }

    VALUE delete_at(difference_type i) {
      VALUE r = Qnil;
      try {
	Sequence::iterator at = swig::getpos(self, i);
	r = swig::from< Sequence::value_type >( *(at) );
	$self->erase(at); 
      }
      catch (std::out_of_range)
	{
	}
      return r;
    }
  }
%enddef

%define %swig_sequence_methods_common(Sequence...)
  %swig_sequence_methods_non_resizable_common(%arg(Sequence))
  %swig_sequence_methods_resizable_common(%arg(Sequence))
%enddef

/**
 * Macro used to add functions for back insertion of values in
 * STL sequence containers
 */
%define %swig_sequence_back_inserters( Sequence... )
  %extend {

    VALUE pop() {
      if ($self->empty()) return Qnil;
      Sequence::value_type x = self->back();
      $self->pop_back();
      return swig::from< Sequence::value_type >( x );
    }

    %alias push "<<";
    const value_type push( const value_type& e ) {
      $self->push_back( e );
      return e;
    }

    %newobject reject;
    Sequence* reject() {
      if ( !rb_block_given_p() )
	rb_raise( rb_eArgError, "no block given" );

      Sequence* r = new Sequence();
      std::remove_copy_if( $self->begin(), $self->end(),              
			   std::back_inserter(*r),
			   swig::yield< Sequence::value_type >() );
      return r;
    }

  }
%enddef

%define %swig_sequence_methods_extra(Sequence...)
  %extend {
    %alias reject_bang "delete_if";
    Sequence* reject_bang() {
      if ( !rb_block_given_p() )
	rb_raise( rb_eArgError, "no block given" );

      $self->erase( std::remove_if( $self->begin(), $self->end(),
            swig::yield< Sequence::value_type >() ), $self->end() );
      return $self;
    }
  }
%enddef

%define %swig_sequence_methods_non_resizable_accessors(Sequence...)
  %extend {

    VALUE at(difference_type i) const {
      VALUE r = Qnil;
      try {
	r = swig::from< Sequence::value_type >( *(swig::cgetpos(self, i)) );
      }
      catch( std::out_of_range ) {
      }
      return r;
    }

    VALUE __getitem__(difference_type i, difference_type length) const throw (std::invalid_argument) {
      if ( length < 0 )
        return Qnil;
      std::size_t len = $self->size();
      if ( i < 0 ) {
        if ( i + static_cast<Sequence::difference_type>(len) < 0 )
          return Qnil;
        else
          i = len + i;
      }
      Sequence::difference_type j = length + i;
      if ( j > static_cast<Sequence::difference_type>(len) )
        j = len;

      VALUE r = Qnil;
      try {
	r = swig::from< const Sequence* >( swig::getslice(self, i, j) );
      }
      catch( std::out_of_range ) {
      }
      return r;
    }

    VALUE __getitem__(difference_type i) const {
      VALUE r = Qnil;
      try {
	r = swig::from< Sequence::value_type >( *(swig::cgetpos(self, i)) );
      }
      catch( std::out_of_range ) {
      }
      return r;
    }

    VALUE __getitem__(VALUE i) const throw (std::invalid_argument) {
      if ( rb_obj_is_kind_of( i, rb_cRange ) == Qfalse ) {
        rb_raise( rb_eTypeError, "not a valid index or range" );
      }

      static ID id_end   = rb_intern("end");
      static ID id_start = rb_intern("begin");
      static ID id_noend = rb_intern("exclude_end?");

      VALUE start = rb_funcall( i, id_start, 0 );
      VALUE end   = rb_funcall( i, id_end, 0 );
      bool  noend = ( rb_funcall( i, id_noend, 0 ) == Qtrue );

      int len = $self->size();

      int s = NUM2INT( start );
      if ( s < 0 ) {
        s = len + s;
        if ( s < 0 )
          return Qnil;
      } else if ( s > len )
        return Qnil;

      int e = NUM2INT( end );
      if ( e < 0 ) e = len + e;
      if ( noend ) e -= 1;
      if ( e < 0 ) e = -1;
      if ( e >= len ) e = len - 1;
      if ( s == len ) e = len - 1;

      return swig::from< Sequence* >( swig::getslice(self, s, e+1) );
    }

    VALUE __setitem__(difference_type i, const value_type& x) throw (std::invalid_argument, std::out_of_range)
      {
	if ( i >= static_cast<Sequence::difference_type>( $self->size()) )
          swig::resize( $self, i+1, x );
        else
          *(swig::getpos($self, i)) = x;

	return swig::from< Sequence::value_type >( x );
      }

    VALUE __setitem__(difference_type i, difference_type length, const Sequence& v) throw (std::invalid_argument) {

      if ( length < 0 )
        return Qnil;
      std::size_t len = $self->size();
      if ( i < 0 ) {
        if ( i + static_cast<Sequence::difference_type>(len) < 0 )
          return Qnil;
        else
          i = len + i;
      }
      Sequence::difference_type j = length + i;
      if ( j > static_cast<Sequence::difference_type>(len) ) {
        swig::resize( $self, j, *(v.begin()) );
      }

      VALUE r = Qnil;
      swig::setslice($self, i, j, v);
      r = swig::from< const Sequence* >( &v );
      return r;
    }
 }
%enddef

/**
 * Macro used to add functions for non resizable sequences
 */
%define %swig_sequence_methods_non_resizable(Sequence...)
  %swig_sequence_methods_non_resizable_common(%arg(Sequence))
  %swig_sequence_methods_non_resizable_accessors(%arg(Sequence))
%enddef


/**
 * Macro used to add functions for sequences
 */
%define %swig_sequence_methods(Sequence...)
  %swig_sequence_methods_non_resizable_common(%arg(Sequence))
  %swig_sequence_methods_resizable_common(%arg(Sequence))
  %swig_sequence_methods_non_resizable_accessors(%arg(Sequence))
  %swig_sequence_methods_extra(%arg(Sequence));
  %swig_sequence_back_inserters(%arg(Sequence));
%enddef

%define %swig_sequence_methods_non_resizable_val(Sequence...)
  %swig_sequence_methods_non_resizable(%arg(Sequence))
%enddef

%define %swig_sequence_methods_val(Sequence...)
  %swig_sequence_methods(%arg(Sequence))
%enddef


/**
 * Macro used to add functions for front insertion of
 * elements in STL sequence containers that support it.
 */
%define %swig_sequence_front_inserters( Sequence... )
%extend {

  VALUE shift()
    {
      if ($self->empty()) return Qnil;
      Sequence::value_type x = self->front();
      $self->erase( $self->begin() );
      return swig::from< Sequence::value_type >( x );
    }

  %typemap(in) (int argc, VALUE* argv) {
    $1 = argc - 1;
    $2 = argv + 1;
  }

  Sequence* insert( difference_type pos, int argc, VALUE* argv, ... )
    {
      std::size_t len = $self->size();
      std::size_t   i = swig::check_index( pos, len, true );
      Sequence::iterator start;

      VALUE elem = argv[0];
      int idx = 0;
      try {
	Sequence::value_type val = swig::as<Sequence::value_type>( elem );
	if ( i >= len ) {
	  $self->resize(i-1, val);
	  return $self;
	}
	start = $self->begin();
	std::advance( start, i );
	$self->insert( start++, val );

	for ( ++idx; idx < argc; ++idx )
	  {
	    elem = argv[idx];
	    val = swig::as<Sequence::value_type>( elem );
	    $self->insert( start++, val );
	  }

      } 
      catch(const std::invalid_argument &)
	{
	  rb_raise( rb_eArgError, "%s",
		    Ruby_Format_TypeError( "", 
					   swig::type_name<Sequence::value_type>(),
					   __FUNCTION__, idx+2, elem ));
	}


      return $self;
    }

  %typemap(in) (int argc, VALUE* argv) {
    $1 = argc;
    $2 = argv;
  }

  Sequence* unshift( int argc, VALUE* argv, ... )
    {
      for ( int idx = argc-1; idx >= 0; --idx )
	{
	  Sequence::iterator start = $self->begin();
	  VALUE elem = argv[idx];
	  try {
	    Sequence::value_type val = swig::as<Sequence::value_type>( elem );
	    $self->insert( start, val );
	  }
	  catch(const std::invalid_argument &)
	    {
	      rb_raise( rb_eArgError, "%s",
			Ruby_Format_TypeError( "", 
					       swig::type_name<Sequence::value_type>(),
					       __FUNCTION__, idx+2, elem ));
	    }
	}

      return $self;
    }
}
%enddef


//
// Common fragments
//

%fragment("StdSequenceTraits","header",
	  fragment="StdTraits",
	  fragment="RubySequence_Cont",
	  fragment="GC_VALUE_definition")
{
namespace swig {
  template <class RubySeq, class Seq>
  inline void
  assign(const RubySeq& rubyseq, Seq* seq) {
    // seq->assign(rubyseq.begin(), rubyseq.end()); // not used as not always implemented
    typedef typename RubySeq::value_type value_type;
    typename RubySeq::const_iterator it = rubyseq.begin();
    for (;it != rubyseq.end(); ++it) {
      seq->insert(seq->end(),(value_type)(*it));
    }
  }

  template <class Seq, class T = typename Seq::value_type >
  struct traits_asptr_stdseq {
    typedef Seq sequence;
    typedef T value_type;

    static int asptr(VALUE obj, sequence **seq) {
      if (rb_obj_is_kind_of(obj, rb_cArray) == Qtrue) {
	try {
	  RubySequence_Cont<value_type> rubyseq(obj);
	  if (seq) {
	    sequence *pseq = new sequence();
	    assign(rubyseq, pseq);
	    *seq = pseq;
	    return SWIG_NEWOBJ;
	  } else {
	    return rubyseq.check() ? SWIG_OK : SWIG_ERROR;
	  }
	} catch (std::exception& e) {
	  if (seq) {
	    VALUE lastErr = rb_gv_get("$!");
	    if (lastErr == Qnil) {
	      rb_raise(rb_eTypeError, "%s", e.what());
	    }
	  }
	  return SWIG_ERROR;
	}
      } else {
	sequence *p;
	swig_type_info *descriptor = swig::type_info<sequence>();
	if (descriptor && SWIG_IsOK(SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0))) {
	  if (seq) *seq = p;
	  return SWIG_OLDOBJ;
	}
      }
      return SWIG_ERROR;
    }
  };

  // Partial specialization for GC_VALUE's.  No need to typecheck each
  // element.
  template< class Seq >
  struct traits_asptr_stdseq< Seq, swig::GC_VALUE > {
    typedef Seq sequence;
    typedef swig::GC_VALUE value_type;

    static int asptr(VALUE obj, sequence **seq) {
      if (rb_obj_is_kind_of(obj, rb_cArray) == Qtrue) {
	try {
	  if (seq) {
	    RubySequence_Cont<value_type> rubyseq(obj);
	    sequence *pseq = new sequence();
	    assign(rubyseq, pseq);
	    *seq = pseq;
	    return SWIG_NEWOBJ;
	  } else {
	    return true;
	  }
	} catch (std::exception& e) {
	  if (seq) {
	    VALUE lastErr = rb_gv_get("$!");
	    if (lastErr == Qnil) {
	      rb_raise(rb_eTypeError, "%s", e.what());
	    }
	  }
	  return SWIG_ERROR;
	}
      } else {
	sequence *p;
	swig_type_info *descriptor = swig::type_info<sequence>();
	if (descriptor && SWIG_IsOK(SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0))) {
	  if (seq) *seq = p;
	  return SWIG_OLDOBJ;
	}
      }
      return SWIG_ERROR;
    }
  };

  template <class Seq, class T = typename Seq::value_type >
  struct traits_from_stdseq {
    typedef Seq sequence;
    typedef T value_type;
    typedef typename Seq::size_type size_type;
    typedef typename sequence::const_iterator const_iterator;

    static VALUE from(const sequence& seq) {
#ifdef SWIG_RUBY_EXTRA_NATIVE_CONTAINERS
      swig_type_info *desc = swig::type_info<sequence>();
      if (desc && desc->clientdata) {
	return SWIG_NewPointerObj(new sequence(seq), desc, SWIG_POINTER_OWN);
      }
#endif
      size_type size = seq.size();
      if (size <= (size_type)INT_MAX) {
	VALUE obj = rb_ary_new2((int)size);
	int i = 0;
	for (const_iterator it = seq.begin();
	     it != seq.end(); ++it, ++i) {
	  rb_ary_push(obj, swig::from< value_type >(*it));
	}
	rb_obj_freeze(obj);  // treat as immutable result
	return obj;
      } else {
	rb_raise(rb_eRangeError,"sequence size not valid in ruby");
	return Qnil;
      }
    }
  };
}
}


%include <rubycontainer_extended.swg>
