#line 1 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
/* -*- c -*-
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
|| $Id: iterators.cmod,v 1.56 2005/10/13 01:03:02 nilsson Exp $
*/

#include "global.h"
RCSID("$Id: iterators.cmod,v 1.56 2005/10/13 01:03:02 nilsson Exp $");
#include "main.h"
#include "object.h"
#include "mapping.h"
#include "multiset.h"
#include "svalue.h"
#include "array.h"
#include "pike_macros.h"
#include "pike_error.h"
#include "pike_memory.h"
#include "dynamic_buffer.h"
#include "interpret.h"
#include "las.h"
#include "gc.h"
#include "stralloc.h"
#include "pike_security.h"
#include "opcodes.h"
#include "pike_error.h"
#include "program.h"
#include "operators.h"
#include "builtin_functions.h"
#include "constants.h"

#define sp Pike_sp

/*! @class Iterator
 *!
 *! This is the interface for iterator objects. They implement an
 *! interface to a collection or stream of data items and a cursor
 *! that can be used to iterate over and examine individual items in
 *! the data set.
 *!
 *! Iterators are typically created to access a data set in some
 *! specific object, array, mapping, multiset or string. An object can
 *! have several iterators that access different data sets in it, or
 *! the same in different ways. E.g. strings have both an iterator for
 *! access char-by-char (@[String.Iterator]), and another for access
 *! over splitted substrings (@[String.SplitIterator]).
 *! @[lfun::_get_iterator] may be defined in an object to get an
 *! instance of the canonical iterator type for it. It's used by e.g.
 *! @[foreach] to iterate over objects conveniently.
 *!
 *! It's not an error to advance an iterator past the beginning or end
 *! of the data set; @[`!()] will only return true then, and @[index]
 *! and @[value] will return @[UNDEFINED]. An iterator in that state
 *! need not keep track of positions, so it's undefined what happens
 *! if it's "moved back" into the set of items.
 *!
 *! Backward movement for iterators is optional. It's supported if and
 *! only if @[`-()] is defined, but even then it's undefined how far
 *! back the iterator can move. Therefore iterators may support only a
 *! limited amount of backward movement, e.g. when they access a
 *! stream through a limited buffer. If such an iterator is moved back
 *! past the limit then it'll behave as if it's pointing entirely
 *! outside the data set (see above).
 *!
 *! An iterator that doesn't support backward movement at all should
 *! throw an error if it's attempted.
 *!
 *! @seealso
 *!   @[predef::get_iterator], @[lfun::_get_iterator],
 *!   @[Array.Iterator], @[Mapping.Iterator], @[Multiset.Iterator],
 *!   @[String.Iterator], @[String.SplitIterator].
 */


#undef class_Iterator_defined
#define class_Iterator_defined
struct program *Iterator_program=NULL;
static int Iterator_program_fun_num=-1;
/*! @decl void create (void|mixed data)
   *!
   *! Initialize this iterator to access a data set in @[data]. The
   *! type of @[data] is specific to the iterator implementation. An
   *! iterator may also access some implicit data set, in which case
   *! @[data] isn't specified at all.
   *!
   *! The iterator initially points to the first item in the data set,
   *! if there is any.
   *!
   *! The iterator need not support being reused, so this function is
   *! typically static.
   */
  #define f_Iterator_create_defined
ptrdiff_t f_Iterator_create_fun_num = 0;
/*! @decl int(0..1) `!()
   *!
   *! Returns @expr{0@} (zero) when the iterator points to an item,
   *! @expr{1@} otherwise.
   */
  #define f_Iterator_cq__backtick_21_defined
ptrdiff_t f_Iterator_cq__backtick_21_fun_num = 0;
/*! @decl Iterator `+ (int steps)
   *!
   *! Returns a clone of this iterator which is advanced the specified
   *! number of steps. The amount may be negative to move backwards.
   *! If the iterator doesn't support backward movement it should
   *! throw an exception in that case.
   */
  #define f_Iterator_cq__backtick_add_defined
ptrdiff_t f_Iterator_cq__backtick_add_fun_num = 0;
/*! @decl Iterator `+= (int steps)
   *!
   *! Advance this iterator the specified number of steps and return
   *! it. The amount may be negative to move backwards. If the
   *! iterator doesn't support backward movement it should throw an
   *! exception in that case.
   *!
   *! @[foreach] calls this function with a step value of @expr{1@}.
   *!
   *! @note
   *!   @[foreach] will call this function even when the the
   *!   iterator has more than one reference. If you want to
   *!   loop over a copy of the iterator, you can create a
   *!   copy by adding @expr{0@} (zero) to it:
   *!   @code
   *!     Iterator iterator;
   *!     ...
   *!     foreach(iterator+0; mixed index; mixed value) {
   *!       ...
   *!     }
   *!   @endcode
   *!
   *! @note
   *!   Even though this function is an lfun, it is often beneficial
   *!   to not declare it static, since code might want to advance
   *!   the iterator by hand.
   */
  #define f_Iterator_cq__backtick_add_eq_defined
ptrdiff_t f_Iterator_cq__backtick_add_eq_fun_num = 0;
/*! @decl optional Iterator `- (int steps)
   *!
   *! This lfun should be defined if and only if the iterator supports
   *! backward movement to some degree. It should back up the
   *! specified number of steps. The amount may be negative to move
   *! forward.
   */
  #define f_Iterator_cq__backtick_2D_defined
ptrdiff_t f_Iterator_cq__backtick_2D_fun_num = 0;
/*! @decl mixed index()
   *!
   *! Returns the current index, or @[UNDEFINED] if the iterator
   *! doesn't point to any item.
   *!
   *! If there's no obvious index set then the index is the current
   *! position in the data set, counting from @expr{0@}.
   */
  #define f_Iterator_index_defined
ptrdiff_t f_Iterator_index_fun_num = 0;
/*! @decl mixed value()
   *!
   *! Returns the current value, or @[UNDEFINED] if the iterator
   *! doesn't point to any item.
   */
  #define f_Iterator_value_defined
ptrdiff_t f_Iterator_value_fun_num = 0;
/*! @decl optional int _sizeof()
   *!
   *! Returns the total number of items in the data set according to
   *! this iterator. If the size of the data set is unlimited or
   *! unknown then this function shouldn't be defined.
   */
  #define f_Iterator_cq__sizeof_defined
ptrdiff_t f_Iterator_cq__sizeof_fun_num = 0;
/*! @decl optional void _random()
   *!
   *! If this function is defined then it sets the iterator to point
   *! to a random item in the accessible set. The random distribution
   *! should be rectangular within that set, and the pseudorandom
   *! sequence provided by @[random] should be used.
   */
  #define f_Iterator_cq__random_defined
ptrdiff_t f_Iterator_cq__random_fun_num = 0;
/*! @decl optional int(0..1) first()
   *!
   *! If this function is defined then it resets the iterator to point
   *! to the first item.
   *!
   *! @returns
   *!   Returns zero if there are no items at all in
   *!   the data set, one otherwise.
   *!
   *! @note
   *!   It's not enough to set the iterator to the earliest accessible
   *!   item. If the iterator doesn't support backing up to the
   *!   original start position then this function should not be
   *!   implemented.
   */
  #define f_Iterator_first_defined
ptrdiff_t f_Iterator_first_fun_num = 0;
/*! @decl optional int next()
   *!
   *! If this function is defined it should advance the iterator one
   *! step, just like @expr{@[`+=](1)@} would do.
   *!
   *! @returns
   *!   Returns @tt{1@} if it succeeded in advancing, and
   *!   @tt{0@} (zero) at end of iterator.
   */
  #define f_Iterator_next_defined
ptrdiff_t f_Iterator_next_fun_num = 0;
/*! @decl optional void set_index(zero index)
   *!
   *! If this function is defined it should set the iterator at
   *! the specified index.
   *!
   *! @note
   *!   It should be possible to set the index at the end of
   *!   the iterator.
   */
  #define f_Iterator_set_index_defined
ptrdiff_t f_Iterator_set_index_fun_num = 0;
/*! @endclass
 */

/*! @module Mapping
 */
/*! @class Iterator
 *! @inherit predef::Iterator
 *!
 *!   An object of this class is returned by @[get_iterator()] when
 *!   called with a mapping.
 *!
 *! @seealso
 *!   @[get_iterator]
 */

#undef class_mapping_iterator_defined
#define class_mapping_iterator_defined
struct program *mapping_iterator_program=NULL;
static int mapping_iterator_program_fun_num=-1;
#line 270 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
/* All variables *must* be before all functions! */
  
#undef var_bucket_mapping_iterator_defined
#define var_bucket_mapping_iterator_defined

#undef var_m_mapping_iterator_defined
#define var_m_mapping_iterator_defined

#undef var_md_mapping_iterator_defined
#define var_md_mapping_iterator_defined

#undef var_current_mapping_iterator_defined
#define var_current_mapping_iterator_defined

#undef THIS
#define THIS ((struct mapping_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_MAPPING_ITERATOR
#define THIS_MAPPING_ITERATOR ((struct mapping_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_MAPPING_ITERATOR
#define OBJ2_MAPPING_ITERATOR(o) ((struct mapping_iterator_struct *)(o->storage+mapping_iterator_storage_offset))

#undef GET_MAPPING_ITERATOR_STORAGE
#define GET_MAPPING_ITERATOR_STORAGE ((struct mapping_iterator_struct *)(o->storage+mapping_iterator_storage_offset)
static ptrdiff_t mapping_iterator_storage_offset;
struct mapping_iterator_struct {

#ifdef var_bucket_mapping_iterator_defined
#line 271 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
int bucket;
#endif /* var_bucket_mapping_iterator_defined */

#ifdef var_m_mapping_iterator_defined
#line 272 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct mapping *m;
#endif /* var_m_mapping_iterator_defined */

#ifdef var_md_mapping_iterator_defined
#line 273 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct mapping_data *md;
#endif /* var_md_mapping_iterator_defined */

#ifdef var_current_mapping_iterator_defined
#line 274 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct keypair *current;
#endif /* var_current_mapping_iterator_defined */
};
#define f_mapping_iterator_value_defined
ptrdiff_t f_mapping_iterator_value_fun_num = 0;
void f_mapping_iterator_value(INT32 args) {
#line 276 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("value",args,0);
{
      if(THIS->current)
	push_svalue(& THIS->current->val);
      else
      {
	push_undefined();
      }
    }

  }
#define f_mapping_iterator_index_defined
ptrdiff_t f_mapping_iterator_index_fun_num = 0;
void f_mapping_iterator_index(INT32 args) {
#line 286 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("index",args,0);
{
      if(THIS->current)
	push_svalue(& THIS->current->ind);
      else
      {
	push_undefined();
      }
    }

  }
#line 296 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
static int step_bucket(struct mapping_iterator_struct *i)
    {
      if (i->md) {
	while(! i->current)
	{
	  i->bucket++;
	  if(i->bucket >= i->md->hashsize)
	    return 0;
	  i->current=i->md->hash[i->bucket];
	}
      }
      return 1;
    }

  static int mi_step(struct mapping_iterator_struct *i)
    {
      if(! i->current) return 0;
      i->current=i->current->next;
      return step_bucket(i);
    }
  
  #define f_mapping_iterator_cq__backtick_add_defined
ptrdiff_t f_mapping_iterator_cq__backtick_add_fun_num = 0;
void f_mapping_iterator_cq__backtick_add(INT32 args) {
#line 317 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 317 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+",args,1);
#line 317 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+",1,"int(0..)");
steps=Pike_sp[0-1].u.integer;
#line 318 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      struct object *o=low_clone(mapping_iterator_program);
      if (steps < 0)
	SIMPLE_ARG_ERROR ("Mapping.Iterator.`+", 1,
			  "This iterator doesn't support going backwards.\n");
      OBJ2_MAPPING_ITERATOR(o)[0] = *THIS;
      if (THIS->m)
	add_ref(THIS->m);
      if (THIS->md) {
	add_ref(THIS->md);
	THIS->md->valrefs++;
      }
      while(--steps>=0 && mi_step(OBJ2_MAPPING_ITERATOR(o)));
      do { struct object * ret_=(o); pop_stack(); push_object(ret_); return; }while(0);
#line 332 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_mapping_iterator_cq__backtick_add_eq_defined
ptrdiff_t f_mapping_iterator_cq__backtick_add_eq_fun_num = 0;
void f_mapping_iterator_cq__backtick_add_eq(INT32 args) {
#line 334 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 334 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+=",args,1);
#line 334 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+=",1,"int(0..)");
steps=Pike_sp[0-1].u.integer;
#line 335 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (steps < 0)
	SIMPLE_ARG_ERROR ("Mapping.Iterator.`+=", 1,
			  "This iterator doesn't support going backwards.\n");
      while(--steps>=0 && mi_step(THIS));
      do { struct object * ret_=(Pike_fp->current_object); add_ref(ret_); pop_stack(); push_object(ret_); return; }while(0);
#line 341 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_mapping_iterator_first_defined
ptrdiff_t f_mapping_iterator_first_fun_num = 0;
void f_mapping_iterator_first(INT32 args) {
#line 343 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("first",args,0);
{
      THIS->current=0;
      THIS->bucket=-1;
      do { INT_TYPE ret_=(step_bucket(THIS));  push_int(ret_); return; }while(0);
#line 348 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#line 350 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
/* Hubbe: Should this really be destructive ?? */
  #define f_mapping_iterator_cq__random_defined
ptrdiff_t f_mapping_iterator_cq__random_fun_num = 0;
void f_mapping_iterator_cq__random(INT32 args) {
#line 351 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("_random",args,0);
{
      if(THIS->md && THIS->md->hashsize)
      {
	size_t k;
	struct keypair *tmp;
	THIS->bucket=my_rand() % THIS->md->hashsize;
	k=0;
	for(tmp=THIS->md->hash[THIS->bucket];tmp;tmp=tmp->next) k++;
	tmp=THIS->md->hash[THIS->bucket];
	if(k)
	{
	  k=my_rand() % k;
	  while(--k > 0) tmp=tmp->next;
	}
	THIS->current=tmp;
      }else{
	THIS->bucket=-1;
	THIS->current=0;
      }
      step_bucket(THIS);
      do { struct object * ret_=(Pike_fp->current_object); add_ref(ret_);  push_object(ret_); return; }while(0);
#line 373 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_mapping_iterator_next_defined
ptrdiff_t f_mapping_iterator_next_fun_num = 0;
void f_mapping_iterator_next(INT32 args) {
#line 375 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("next",args,0);
#line 375 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{ do { INT_TYPE ret_=(mi_step(THIS));  push_int(ret_); return; }while(0);}
  }
#define f_mapping_iterator_cq__backtick_21_defined
ptrdiff_t f_mapping_iterator_cq__backtick_21_fun_num = 0;
void f_mapping_iterator_cq__backtick_21(INT32 args) {
#line 376 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("`!",args,0);
#line 376 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{ do { INT_TYPE ret_=(!THIS->current);  push_int(ret_); return; }while(0);}

  }
#define f_mapping_iterator_create_defined
ptrdiff_t f_mapping_iterator_create_fun_num = 0;
void f_mapping_iterator_create(INT32 args) {
#line 378 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct mapping * map;
#line 378 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("create",args,1);
#line 378 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_MAPPING) SIMPLE_BAD_ARG_ERROR("create",1,"mapping(mixed:mixed)");
#line 378 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
debug_malloc_pass(map=Pike_sp[0-1].u.mapping);
{
      if(THIS->m)
	Pike_error("Mapping iterators cannot be reused.\n");

      add_ref(THIS->m=map);
      THIS->md=map->data;
      add_ref(THIS->md);
      THIS->md->valrefs++;
      THIS->bucket=-1;
      step_bucket(THIS);
    }

  }

#undef internal_init_mapping_iterator_defined
#define internal_init_mapping_iterator_defined

#undef mapping_iterator_event_handler_defined
#define mapping_iterator_event_handler_defined
static void init_mapping_iterator_struct(void)
#line 392 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      THIS->m=0;
      THIS->md=0;
      THIS->current=0;
      THIS->bucket=0;
    }

  
#undef internal_exit_mapping_iterator_defined
#define internal_exit_mapping_iterator_defined

#undef mapping_iterator_event_handler_defined
#define mapping_iterator_event_handler_defined
static void exit_mapping_iterator_struct(void)
#line 400 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (THIS->md) {
	THIS->md->valrefs--;
	free_mapping_data(THIS->md);
      }
      if (THIS->m) {
	free_mapping(THIS->m);
      }
    }

#ifdef mapping_iterator_event_handler_defined
static void mapping_iterator_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_mapping_iterator_defined
  case PROG_EVENT_INIT: init_mapping_iterator_struct(); break;

#endif /* internal_init_mapping_iterator_defined */

#ifdef internal_exit_mapping_iterator_defined
  case PROG_EVENT_EXIT: exit_mapping_iterator_struct(); break;

#endif /* internal_exit_mapping_iterator_defined */
  default: break; 
  }
}

#endif /* mapping_iterator_event_handler_defined */
#line 409 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
;
/*! @endclass
 */
/*! @endmodule
 */


/*! @module Array
 */
/*! @class Iterator
 *! @inherit predef::Iterator
 *!
 *!   An object of this class is returned by @[get_iterator()] when
 *!   called with an array.
 *!
 *! @seealso
 *!   @[get_iterator]
 */

#undef class_array_iterator_defined
#define class_array_iterator_defined
struct program *array_iterator_program=NULL;
static int array_iterator_program_fun_num=-1;

#undef var_pos_array_iterator_defined
#define var_pos_array_iterator_defined

#undef var_a_array_iterator_defined
#define var_a_array_iterator_defined

#undef THIS
#define THIS ((struct array_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_ARRAY_ITERATOR
#define THIS_ARRAY_ITERATOR ((struct array_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_ARRAY_ITERATOR
#define OBJ2_ARRAY_ITERATOR(o) ((struct array_iterator_struct *)(o->storage+array_iterator_storage_offset))

#undef GET_ARRAY_ITERATOR_STORAGE
#define GET_ARRAY_ITERATOR_STORAGE ((struct array_iterator_struct *)(o->storage+array_iterator_storage_offset)
static ptrdiff_t array_iterator_storage_offset;
struct array_iterator_struct {

#ifdef var_pos_array_iterator_defined
#line 429 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
int pos;
#endif /* var_pos_array_iterator_defined */

#ifdef var_a_array_iterator_defined
#line 430 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct array *a;
#endif /* var_a_array_iterator_defined */
};
#define f_array_iterator_value_defined
ptrdiff_t f_array_iterator_value_fun_num = 0;
void f_array_iterator_value(INT32 args) {
#line 432 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("value",args,0);
{
      if(!THIS->a || THIS->pos < 0 || THIS->pos >= THIS->a->size)
      {
	push_undefined();
      }else{
	push_svalue(THIS->a->item + THIS->pos);
      }
    }

  }
#define f_array_iterator_index_defined
ptrdiff_t f_array_iterator_index_fun_num = 0;
void f_array_iterator_index(INT32 args) {
#line 442 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("index",args,0);
{
      if(!THIS->a || THIS->pos < 0 || THIS->pos >= THIS->a->size)
      {
	push_undefined();
      }else{
	do { INT_TYPE ret_=(THIS->pos);  push_int(ret_); return; }while(0);
#line 449 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}
    }

  }
#define f_array_iterator_cq__backtick_add_defined
ptrdiff_t f_array_iterator_cq__backtick_add_fun_num = 0;
void f_array_iterator_cq__backtick_add(INT32 args) {
#line 452 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 452 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+",args,1);
#line 452 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+",1,"int");
steps=Pike_sp[0-1].u.integer;
#line 453 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      struct object *o=low_clone(array_iterator_program);
      OBJ2_ARRAY_ITERATOR(o)[0]=*THIS;
      if (THIS->a)
	add_ref(THIS->a);
      OBJ2_ARRAY_ITERATOR(o)->pos+=steps;
      do { struct object * ret_=(o); pop_stack(); push_object(ret_); return; }while(0);
#line 460 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_array_iterator_cq__backtick_add_eq_defined
ptrdiff_t f_array_iterator_cq__backtick_add_eq_fun_num = 0;
void f_array_iterator_cq__backtick_add_eq(INT32 args) {
#line 462 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 462 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+=",args,1);
#line 462 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+=",1,"int");
steps=Pike_sp[0-1].u.integer;
#line 463 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
    THIS->pos+=steps;
    do { struct object * ret_=(Pike_fp->current_object); add_ref(ret_); pop_stack(); push_object(ret_); return; }while(0);
#line 466 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_array_iterator_cq__backtick_2D_defined
ptrdiff_t f_array_iterator_cq__backtick_2D_fun_num = 0;
void f_array_iterator_cq__backtick_2D(INT32 args) {
#line 468 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 468 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`-",args,1);
#line 468 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`-",1,"int");
steps=Pike_sp[0-1].u.integer;
#line 469 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
    struct object *o=low_clone(array_iterator_program);
    OBJ2_ARRAY_ITERATOR(o)[0]=*THIS;
    add_ref(THIS->a);
    OBJ2_ARRAY_ITERATOR(o)->pos-=steps;
    do { struct object * ret_=(o); pop_stack(); push_object(ret_); return; }while(0);
#line 475 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_array_iterator_first_defined
ptrdiff_t f_array_iterator_first_fun_num = 0;
void f_array_iterator_first(INT32 args) {
#line 477 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("first",args,0);
{
      THIS->pos=0;
      do { INT_TYPE ret_=(THIS->a && THIS->pos < THIS->a->size);  push_int(ret_); return; }while(0);
#line 481 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_array_iterator_set_index_defined
ptrdiff_t f_array_iterator_set_index_fun_num = 0;
void f_array_iterator_set_index(INT32 args) {
#line 483 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE pos;
#line 483 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("set_index",args,1);
#line 483 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("set_index",1,"int");
pos=Pike_sp[0-1].u.integer;
#line 484 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if(!THIS->a || pos < 0 || pos > THIS->a->size)
      {
	Pike_error("Bad position.\n");
      }else{
	THIS->pos = pos;
      }      
    }

  }
#line 493 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
/* Hubbe: Should this really be destructive ?? */
  #define f_array_iterator_cq__random_defined
ptrdiff_t f_array_iterator_cq__random_fun_num = 0;
void f_array_iterator_cq__random(INT32 args) {
#line 494 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("_random",args,0);
{
      if(THIS->a && THIS->a->size)
	THIS->pos=my_rand() % THIS->a->size;
      else
	THIS->pos=0;
      do { struct object * ret_=(Pike_fp->current_object); add_ref(ret_);  push_object(ret_); return; }while(0);
#line 501 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_array_iterator_next_defined
ptrdiff_t f_array_iterator_next_fun_num = 0;
void f_array_iterator_next(INT32 args) {
#line 503 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("next",args,0);
{
      THIS->pos++;
      do { INT_TYPE ret_=(THIS->a && THIS->pos >= 0 && THIS->pos < THIS->a->size);  push_int(ret_); return; }while(0);
#line 507 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_array_iterator_cq__backtick_21_defined
ptrdiff_t f_array_iterator_cq__backtick_21_fun_num = 0;
void f_array_iterator_cq__backtick_21(INT32 args) {
#line 509 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("`!",args,0);
{
      do { INT_TYPE ret_=(!(THIS->a && THIS->pos >= 0 && THIS->pos < THIS->a->size));  push_int(ret_); return; }while(0);
#line 512 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_array_iterator_create_defined
ptrdiff_t f_array_iterator_create_fun_num = 0;
void f_array_iterator_create(INT32 args) {
#line 514 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct array * a;
#line 514 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("create",args,1);
#line 514 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_ARRAY) SIMPLE_BAD_ARG_ERROR("create",1,"array");
#line 514 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
debug_malloc_pass(a=Pike_sp[0-1].u.array);
{
      if(THIS->a)
	Pike_error("Array iterators cannot be reused.\n");
      
      add_ref(THIS->a=a);
    }
  
  }

#undef internal_init_array_iterator_defined
#define internal_init_array_iterator_defined

#undef array_iterator_event_handler_defined
#define array_iterator_event_handler_defined
static void init_array_iterator_struct(void)
#line 523 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      THIS->a=0;
      THIS->pos=0;
    }

  
#undef internal_exit_array_iterator_defined
#define internal_exit_array_iterator_defined

#undef array_iterator_event_handler_defined
#define array_iterator_event_handler_defined
static void exit_array_iterator_struct(void)
#line 529 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (THIS->a)
	free_array(THIS->a);
    }
    

#ifdef array_iterator_event_handler_defined
static void array_iterator_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_array_iterator_defined
  case PROG_EVENT_INIT: init_array_iterator_struct(); break;

#endif /* internal_init_array_iterator_defined */

#ifdef internal_exit_array_iterator_defined
  case PROG_EVENT_EXIT: exit_array_iterator_struct(); break;

#endif /* internal_exit_array_iterator_defined */
  default: break; 
  }
}

#endif /* array_iterator_event_handler_defined */
#line 534 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
;

/*! @endclass
 */
/*! @endmodule
 */

/*! @module Multiset
 */
/*! @class Iterator
 *! @inherit predef::Iterator
 *!
 *!   An object of this class is returned by @[get_iterator()] when
 *!   called with a multiset.
 *!
 *! @seealso
 *!   @[get_iterator]
 */

#undef class_multiset_iterator_defined
#define class_multiset_iterator_defined
struct program *multiset_iterator_program=NULL;
static int multiset_iterator_program_fun_num=-1;

#undef var_l_multiset_iterator_defined
#define var_l_multiset_iterator_defined

#undef var_lock_index_multiset_iterator_defined
#define var_lock_index_multiset_iterator_defined

#undef var_nodepos_multiset_iterator_defined
#define var_nodepos_multiset_iterator_defined

#undef THIS
#define THIS ((struct multiset_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_MULTISET_ITERATOR
#define THIS_MULTISET_ITERATOR ((struct multiset_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_MULTISET_ITERATOR
#define OBJ2_MULTISET_ITERATOR(o) ((struct multiset_iterator_struct *)(o->storage+multiset_iterator_storage_offset))

#undef GET_MULTISET_ITERATOR_STORAGE
#define GET_MULTISET_ITERATOR_STORAGE ((struct multiset_iterator_struct *)(o->storage+multiset_iterator_storage_offset)
static ptrdiff_t multiset_iterator_storage_offset;
struct multiset_iterator_struct {

#ifdef var_l_multiset_iterator_defined
#line 554 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct multiset *l;
#endif /* var_l_multiset_iterator_defined */

#ifdef var_lock_index_multiset_iterator_defined
#line 555 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
int lock_index;
#endif /* var_lock_index_multiset_iterator_defined */

#ifdef var_nodepos_multiset_iterator_defined
#line 556 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
ptrdiff_t nodepos;
#endif /* var_nodepos_multiset_iterator_defined */
};
#define f_multiset_iterator_value_defined
ptrdiff_t f_multiset_iterator_value_fun_num = 0;
void f_multiset_iterator_value(INT32 args) {
#line 558 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("value",args,0);
{
      if (!THIS->l) Pike_error ("Iterator not initialized.\n");
      if (THIS->nodepos < 0 || msnode_is_deleted (THIS->l, THIS->nodepos))
	push_undefined();
      else
	push_multiset_value (THIS->l, THIS->nodepos);
    }

  }
#define f_multiset_iterator_index_defined
ptrdiff_t f_multiset_iterator_index_fun_num = 0;
void f_multiset_iterator_index(INT32 args) {
#line 567 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("index",args,0);
{
      if (!THIS->l) Pike_error ("Iterator not initialized.\n");
      if (THIS->nodepos < 0 || msnode_is_deleted (THIS->l, THIS->nodepos))
	push_undefined();
      else
	push_multiset_index (THIS->l, THIS->nodepos);
    }

  }
#line 576 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
static struct object *li_copy (struct multiset_iterator_struct *li)
    {
      struct object *o = low_clone (multiset_iterator_program);
      struct multiset_iterator_struct *copy = OBJ2_MULTISET_ITERATOR (o);
      if ((copy->l = li->l))
	add_ref(li->l);
      if ((copy->nodepos = li->nodepos) >= 0) add_msnode_ref (copy->l);
      if ((copy->lock_index = li->lock_index)) {
	add_ref (copy->l->msd);
	copy->l->msd->noval_refs++;
      }
      return o;
    }

  static void li_step (struct multiset_iterator_struct *li, int steps)
    {
      ptrdiff_t newpos = li->nodepos;

      if (li->nodepos < 0) return;

      if (steps > 0)
	do {
	  newpos = multiset_next (li->l, newpos);
	  if (newpos < 0) {
	    sub_msnode_ref (li->l);
	    break;
	  }
	} while (--steps);
      else if (steps < 0)
	do {
	  newpos = multiset_prev (li->l, newpos);
	  if (newpos < 0) {
	    sub_msnode_ref (li->l);
	    break;
	  }
	} while (++steps);

      li->nodepos = newpos;
    }

  #define f_multiset_iterator_cq__backtick_add_eq_defined
ptrdiff_t f_multiset_iterator_cq__backtick_add_eq_fun_num = 0;
void f_multiset_iterator_cq__backtick_add_eq(INT32 args) {
#line 616 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 616 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+=",args,1);
#line 616 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+=",1,"int");
steps=Pike_sp[0-1].u.integer;
#line 617 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (!THIS->l) Pike_error ("Iterator not initialized.\n");
      li_step (THIS, steps);
      do { struct object * ret_=(Pike_fp->current_object); add_ref(ret_); pop_stack(); push_object(ret_); return; }while(0);
#line 621 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_multiset_iterator_cq__backtick_add_defined
ptrdiff_t f_multiset_iterator_cq__backtick_add_fun_num = 0;
void f_multiset_iterator_cq__backtick_add(INT32 args) {
#line 623 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 623 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+",args,1);
#line 623 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+",1,"int");
steps=Pike_sp[0-1].u.integer;
#line 624 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      struct object *o;
      if (!THIS->l) Pike_error ("Iterator not initialized.\n");
      o = li_copy (THIS);
      li_step (OBJ2_MULTISET_ITERATOR (o), steps);
      do { struct object * ret_=(o); pop_stack(); push_object(ret_); return; }while(0);
#line 630 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_multiset_iterator_cq__backtick_2D_defined
ptrdiff_t f_multiset_iterator_cq__backtick_2D_fun_num = 0;
void f_multiset_iterator_cq__backtick_2D(INT32 args) {
#line 632 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 632 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`-",args,1);
#line 632 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`-",1,"int");
steps=Pike_sp[0-1].u.integer;
#line 633 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      struct object *o;
      if (!THIS->l) Pike_error ("Iterator not initialized.\n");
      o = li_copy (THIS);
      li_step (OBJ2_MULTISET_ITERATOR (o), -steps);
      do { struct object * ret_=(o); pop_stack(); push_object(ret_); return; }while(0);
#line 639 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_multiset_iterator_first_defined
ptrdiff_t f_multiset_iterator_first_fun_num = 0;
void f_multiset_iterator_first(INT32 args) {
#line 641 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("first",args,0);
{
      if (!THIS->l) Pike_error ("Iterator not initialized.\n");
      if (THIS->nodepos >= 0) sub_msnode_ref (THIS->l);
      THIS->nodepos = multiset_first (THIS->l);
      do { INT_TYPE ret_=(THIS->nodepos >= 0);  push_int(ret_); return; }while(0);
#line 647 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_multiset_iterator_next_defined
ptrdiff_t f_multiset_iterator_next_fun_num = 0;
void f_multiset_iterator_next(INT32 args) {
#line 649 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("next",args,0);
{
      if (!THIS->l) Pike_error ("Iterator not initialized.\n");
      if (THIS->nodepos >= 0) {
	THIS->nodepos = multiset_next (THIS->l, THIS->nodepos);
	if (THIS->nodepos >= 0) do { INT_TYPE ret_=(1);  push_int(ret_); return; }while(0);
#line 655 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
sub_msnode_ref (THIS->l);
      }
      do { INT_TYPE ret_=(0);  push_int(ret_); return; }while(0);
#line 658 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_multiset_iterator_cq__backtick_21_defined
ptrdiff_t f_multiset_iterator_cq__backtick_21_fun_num = 0;
void f_multiset_iterator_cq__backtick_21(INT32 args) {
#line 660 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("`!",args,0);
{
      if (!THIS->l) Pike_error ("Iterator not initialized.\n");
      do { INT_TYPE ret_=(THIS->nodepos < 0 || msnode_is_deleted (THIS->l, THIS->nodepos));  push_int(ret_); return; }while(0);
#line 664 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#line 666 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
/* Hubbe: Should this really be destructive ??
   * I let this question stand; I'm only adapting multiset_iterator. /mast */
  #define f_multiset_iterator_cq__random_defined
ptrdiff_t f_multiset_iterator_cq__random_fun_num = 0;
void f_multiset_iterator_cq__random(INT32 args) {
#line 668 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("_random",args,0);
{
      if (!THIS->l) Pike_error ("Iterator not initialized.\n");
      if (THIS->nodepos >= 0) {
	sub_msnode_ref (THIS->l);
	THIS->nodepos = -1;
      }
      if (!multiset_is_empty (THIS->l))
	THIS->nodepos =
	  multiset_get_nth (THIS->l, my_rand() % multiset_sizeof (THIS->l));
      do { struct object * ret_=(Pike_fp->current_object); add_ref(ret_);  push_object(ret_); return; }while(0);
#line 679 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_multiset_iterator_lock_index_defined
ptrdiff_t f_multiset_iterator_lock_index_fun_num = 0;
void f_multiset_iterator_lock_index(INT32 args) {
#line 681 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("lock_index",args,0);
{
      if (!THIS->l) Pike_error ("Iterator not initialized.\n");
      if (!THIS->lock_index) {
	add_ref (THIS->l->msd);
	THIS->l->msd->noval_refs++;
	THIS->lock_index = 1;
      }
    }

  }
#define f_multiset_iterator_unlock_index_defined
ptrdiff_t f_multiset_iterator_unlock_index_fun_num = 0;
void f_multiset_iterator_unlock_index(INT32 args) {
#line 691 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("unlock_index",args,0);
{
      if (!THIS->l) Pike_error ("Iterator not initialized.\n");
      if (THIS->lock_index) {
	THIS->l->msd->noval_refs--;
	sub_ref (THIS->l->msd);
#ifdef PIKE_DEBUG
	if (THIS->l->msd->refs <= 0) Pike_fatal ("msd ran out of refs unexpectedly.\n");
#endif
	THIS->lock_index = 0;
      }
    }

  }
#line 704 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
/* FIXME: Add more functions, e.g. insert, delete, add. */

  /* FIXME: Maybe the index should be locked when the iterator is used
   * in foreach, to behave more like the mapping iterator. */

  #define f_multiset_iterator_create_defined
ptrdiff_t f_multiset_iterator_create_fun_num = 0;
void f_multiset_iterator_create(INT32 args) {
#line 709 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct multiset * l;
#line 709 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("create",args,1);
#line 709 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_MULTISET) SIMPLE_BAD_ARG_ERROR("create",1,"multiset");
#line 709 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
debug_malloc_pass(l=Pike_sp[0-1].u.multiset);
{
      if (THIS->l) Pike_error ("Multiset iterators cannot be reused.\n");
      add_ref (THIS->l = l);
      THIS->lock_index = 0;
      THIS->nodepos = multiset_first (THIS->l);
    }

  }

#undef internal_init_multiset_iterator_defined
#define internal_init_multiset_iterator_defined

#undef multiset_iterator_event_handler_defined
#define multiset_iterator_event_handler_defined
static void init_multiset_iterator_struct(void)
#line 718 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      THIS->l = NULL;
    }

  
#undef internal_exit_multiset_iterator_defined
#define internal_exit_multiset_iterator_defined

#undef multiset_iterator_event_handler_defined
#define multiset_iterator_event_handler_defined
static void exit_multiset_iterator_struct(void)
#line 723 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (THIS->l) {
	if (THIS->nodepos >= 0) sub_msnode_ref (THIS->l);
	if (THIS->lock_index) {
	  THIS->l->msd->noval_refs--;
	  sub_ref (THIS->l->msd);
#ifdef PIKE_DEBUG
	  if (THIS->l->msd->refs <= 0) Pike_fatal ("msd ran out of refs unexpectedly.\n");
#endif
	}
	free_multiset (THIS->l);
	THIS->l = NULL;
      }
    }

#ifdef multiset_iterator_event_handler_defined
static void multiset_iterator_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_multiset_iterator_defined
  case PROG_EVENT_INIT: init_multiset_iterator_struct(); break;

#endif /* internal_init_multiset_iterator_defined */

#ifdef internal_exit_multiset_iterator_defined
  case PROG_EVENT_EXIT: exit_multiset_iterator_struct(); break;

#endif /* internal_exit_multiset_iterator_defined */
  default: break; 
  }
}

#endif /* multiset_iterator_event_handler_defined */
#line 737 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
;

/*! @endclass
 */
/*! @endmodule
 */

/*! @module String
 */
/*! @class Iterator
 *! @inherit predef::Iterator
 *!
 *!   An object of this class is returned by @[get_iterator()] when
 *!   called with a string.
 *!
 *! @seealso
 *!   @[get_iterator]
 */

#undef class_string_iterator_defined
#define class_string_iterator_defined
struct program *string_iterator_program=NULL;
static int string_iterator_program_fun_num=-1;

#undef var_pos_string_iterator_defined
#define var_pos_string_iterator_defined

#undef var_s_string_iterator_defined
#define var_s_string_iterator_defined

#undef THIS
#define THIS ((struct string_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_STRING_ITERATOR
#define THIS_STRING_ITERATOR ((struct string_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_STRING_ITERATOR
#define OBJ2_STRING_ITERATOR(o) ((struct string_iterator_struct *)(o->storage+string_iterator_storage_offset))

#undef GET_STRING_ITERATOR_STORAGE
#define GET_STRING_ITERATOR_STORAGE ((struct string_iterator_struct *)(o->storage+string_iterator_storage_offset)
static ptrdiff_t string_iterator_storage_offset;
struct string_iterator_struct {

#ifdef var_pos_string_iterator_defined
#line 757 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
int pos;
#endif /* var_pos_string_iterator_defined */

#ifdef var_s_string_iterator_defined
#line 758 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct pike_string *s;
#endif /* var_s_string_iterator_defined */
};
#define f_string_iterator_value_defined
ptrdiff_t f_string_iterator_value_fun_num = 0;
void f_string_iterator_value(INT32 args) {
#line 760 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("value",args,0);
{
      if(!THIS->s || THIS->pos < 0 || THIS->pos >= THIS->s->len)
      {
	push_undefined();
      }else{
	do { INT_TYPE ret_=(index_shared_string(THIS->s, THIS->pos));  push_int(ret_); return; }while(0);
#line 767 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}
    }

  }
#define f_string_iterator_index_defined
ptrdiff_t f_string_iterator_index_fun_num = 0;
void f_string_iterator_index(INT32 args) {
#line 770 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("index",args,0);
{
      if(!THIS->s || THIS->pos < 0 || THIS->pos >= THIS->s->len)
      {
	push_undefined();
      }else{
	do { INT_TYPE ret_=(THIS->pos);  push_int(ret_); return; }while(0);
#line 777 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}
    }

  }
#define f_string_iterator_cq__backtick_add_defined
ptrdiff_t f_string_iterator_cq__backtick_add_fun_num = 0;
void f_string_iterator_cq__backtick_add(INT32 args) {
#line 780 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 780 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+",args,1);
#line 780 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+",1,"int");
steps=Pike_sp[0-1].u.integer;
#line 781 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      struct object *o=low_clone(string_iterator_program);
      OBJ2_STRING_ITERATOR(o)[0]=*THIS;
      add_ref(THIS->s);
      OBJ2_STRING_ITERATOR(o)->pos+=steps;
      do { struct object * ret_=(o); pop_stack(); push_object(ret_); return; }while(0);
#line 787 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_string_iterator_cq__backtick_add_eq_defined
ptrdiff_t f_string_iterator_cq__backtick_add_eq_fun_num = 0;
void f_string_iterator_cq__backtick_add_eq(INT32 args) {
#line 789 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 789 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+=",args,1);
#line 789 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+=",1,"int");
steps=Pike_sp[0-1].u.integer;
#line 790 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
    THIS->pos+=steps;
    do { struct object * ret_=(Pike_fp->current_object); add_ref(ret_); pop_stack(); push_object(ret_); return; }while(0);
#line 793 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_string_iterator_cq__backtick_2D_defined
ptrdiff_t f_string_iterator_cq__backtick_2D_fun_num = 0;
void f_string_iterator_cq__backtick_2D(INT32 args) {
#line 795 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 795 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`-",args,1);
#line 795 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`-",1,"int");
steps=Pike_sp[0-1].u.integer;
#line 796 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
    struct object *o=low_clone(string_iterator_program);
    OBJ2_STRING_ITERATOR(o)[0]=*THIS;
    add_ref(THIS->s);
    OBJ2_STRING_ITERATOR(o)->pos-=steps;
    do { struct object * ret_=(o); pop_stack(); push_object(ret_); return; }while(0);
#line 802 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_string_iterator_first_defined
ptrdiff_t f_string_iterator_first_fun_num = 0;
void f_string_iterator_first(INT32 args) {
#line 804 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("first",args,0);
{
      THIS->pos=0;
      do { INT_TYPE ret_=(THIS->s && THIS->pos < THIS->s->len);  push_int(ret_); return; }while(0);
#line 808 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_string_iterator_set_index_defined
ptrdiff_t f_string_iterator_set_index_fun_num = 0;
void f_string_iterator_set_index(INT32 args) {
#line 810 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE pos;
#line 810 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("set_index",args,1);
#line 810 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("set_index",1,"int");
pos=Pike_sp[0-1].u.integer;
#line 811 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (!THIS->s || pos < 0 || pos > THIS->s->len) {
	Pike_error("Bad position.\n");
      }
      THIS->pos = pos;
    }

  }
#line 818 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
/* Hubbe: Should this really be destructive ?? */
  #define f_string_iterator_cq__random_defined
ptrdiff_t f_string_iterator_cq__random_fun_num = 0;
void f_string_iterator_cq__random(INT32 args) {
#line 819 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("_random",args,0);
{
      if(THIS->s->len)
	THIS->pos=my_rand() % THIS->s->len;
      else
	THIS->pos=0;
      do { struct object * ret_=(Pike_fp->current_object); add_ref(ret_);  push_object(ret_); return; }while(0);
#line 826 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_string_iterator_next_defined
ptrdiff_t f_string_iterator_next_fun_num = 0;
void f_string_iterator_next(INT32 args) {
#line 828 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("next",args,0);
{
      THIS->pos++;
      do { INT_TYPE ret_=(THIS->s && THIS->pos >= 0 && THIS->pos < THIS->s->len);  push_int(ret_); return; }while(0);
#line 832 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_string_iterator_cq__backtick_21_defined
ptrdiff_t f_string_iterator_cq__backtick_21_fun_num = 0;
void f_string_iterator_cq__backtick_21(INT32 args) {
#line 834 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("`!",args,0);
{
      do { INT_TYPE ret_=(!(THIS->s && THIS->pos >= 0 && THIS->pos < THIS->s->len));  push_int(ret_); return; }while(0);
#line 837 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_string_iterator_cq__search_defined
ptrdiff_t f_string_iterator_cq__search_fun_num = 0;
void f_string_iterator_cq__search(INT32 args) {
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct svalue * needle;
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct svalue * start;
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args < 1) wrong_number_of_args_error("_search",args,1);
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args > 2) wrong_number_of_args_error("_search",args,2);
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
needle=Pike_sp+0-args; dmalloc_touch_svalue(Pike_sp+0-args);
if (args > 1) {
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[1-args].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("_search",2,"int|void");
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
start=Pike_sp+1-args; dmalloc_touch_svalue(Pike_sp+1-args);
} else start=0;
{
      if (!THIS->s)
	Pike_error("No data to search.\n");
      ref_push_string(THIS->s);
      push_svalue(needle);
      if (start) push_svalue(start);
      else push_int(THIS->pos);
      f_search(3);
      stack_pop_n_elems_keep_top(args);
      /* Advance to the found position. */
      if (Pike_sp[-1].type == T_INT) {
	if (Pike_sp[-1].u.integer >= 0) {
	  THIS->pos = Pike_sp[-1].u.integer;
	} else {
	  THIS->pos = THIS->s->len;
	}
      }
    }

  }
#define f_string_iterator_create_defined
ptrdiff_t f_string_iterator_create_fun_num = 0;
void f_string_iterator_create(INT32 args) {
#line 860 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct pike_string * s;
#line 860 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("create",args,1);
#line 860 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("create",1,"string");
#line 860 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
debug_malloc_pass(s=Pike_sp[0-1].u.string);
{
      if(THIS->s)
	Pike_error("String iterators cannot be reused.\n");
      
      add_ref(THIS->s=s);
    }
  
  }

#undef internal_init_string_iterator_defined
#define internal_init_string_iterator_defined

#undef string_iterator_event_handler_defined
#define string_iterator_event_handler_defined
static void init_string_iterator_struct(void)
#line 869 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      THIS->s=0;
      THIS->pos=0;
    }

  
#undef internal_exit_string_iterator_defined
#define internal_exit_string_iterator_defined

#undef string_iterator_event_handler_defined
#define string_iterator_event_handler_defined
static void exit_string_iterator_struct(void)
#line 875 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      free_string(THIS->s);
    }

#ifdef string_iterator_event_handler_defined
static void string_iterator_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_string_iterator_defined
  case PROG_EVENT_INIT: init_string_iterator_struct(); break;

#endif /* internal_init_string_iterator_defined */

#ifdef internal_exit_string_iterator_defined
  case PROG_EVENT_EXIT: exit_string_iterator_struct(); break;

#endif /* internal_exit_string_iterator_defined */
  default: break; 
  }
}

#endif /* string_iterator_event_handler_defined */
#line 878 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
;

/*! @endclass
 */
/*! @endmodule
 */

/* Interal (for Stdio.File) class: Stdio.File->line_iterator.
 * Splits on lines, does only handle 8-bit characters.
 */

#undef class_file_line_iterator_defined
#define class_file_line_iterator_defined
struct program *file_line_iterator_program=NULL;
static int file_line_iterator_program_fun_num=-1;

#undef var_buffer_file_line_iterator_defined
#define var_buffer_file_line_iterator_defined

#undef var_current_file_line_iterator_defined
#define var_current_file_line_iterator_defined

#undef var_offset_file_line_iterator_defined
#define var_offset_file_line_iterator_defined

#undef var_index_file_line_iterator_defined
#define var_index_file_line_iterator_defined

#undef var_feed_file_line_iterator_defined
#define var_feed_file_line_iterator_defined

#undef THIS
#define THIS ((struct file_line_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_FILE_LINE_ITERATOR
#define THIS_FILE_LINE_ITERATOR ((struct file_line_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_FILE_LINE_ITERATOR
#define OBJ2_FILE_LINE_ITERATOR(o) ((struct file_line_iterator_struct *)(o->storage+file_line_iterator_storage_offset))

#undef GET_FILE_LINE_ITERATOR_STORAGE
#define GET_FILE_LINE_ITERATOR_STORAGE ((struct file_line_iterator_struct *)(o->storage+file_line_iterator_storage_offset)
static ptrdiff_t file_line_iterator_storage_offset;
struct file_line_iterator_struct {

#ifdef var_buffer_file_line_iterator_defined
#line 890 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct pike_string *buffer;
#endif /* var_buffer_file_line_iterator_defined */

#ifdef var_current_file_line_iterator_defined
#line 891 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct pike_string *current;
#endif /* var_current_file_line_iterator_defined */

#ifdef var_offset_file_line_iterator_defined
#line 892 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
int offset;
#endif /* var_offset_file_line_iterator_defined */

#ifdef var_index_file_line_iterator_defined
#line 893 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
int index;
#endif /* var_index_file_line_iterator_defined */

#ifdef var_feed_file_line_iterator_defined
#line 894 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct svalue feed;
#endif /* var_feed_file_line_iterator_defined */
};
static void fl_find_next(struct file_line_iterator_struct *ssi)
  {
    unsigned char *ptr, *eptr, *start;
    int start_off = ssi->offset;

    if (ssi->current)
    {
      free_string(ssi->current);
      ssi->current = NULL;
    }

    if (!ssi->buffer)
      return;

  again:
      start = ssi->buffer->str + start_off;
      ptr   = ssi->buffer->str + ssi->offset;
      eptr  = ssi->buffer->str + ssi->buffer->len;

      /* Loop until we find a '\n'. */
      while( ptr < eptr )
	if( *ptr != '\n'  )
	  ptr++;
	else
	{
	  ssi->current = make_shared_binary_string( start, ptr-start );
	  /* skip the '\n'
 */	  ssi->offset =  ptr - ((unsigned char *)ssi->buffer->str) + 1;
	  ssi->index++;
	  return;
	}

      apply_svalue( &ssi->feed, 0 );
      if( Pike_sp[-1].type == PIKE_T_STRING &&
	  Pike_sp[-1].u.string->len )
      {
	push_string(make_shared_binary_string( ssi->buffer->str+start_off,
					       ssi->buffer->len-start_off));
	free_string( ssi->buffer );
	stack_swap();
	f_add( 2 );
	ssi->buffer = Pike_sp[-1].u.string;
	dmalloc_touch_svalue(Pike_sp-1);
	Pike_sp--;

	if( !ssi->buffer->size_shift )
	{
	  ssi->offset -= start_off;
	  start_off = 0;
	  goto again;
	}
	/* Wide string.
 */      }
      else {
	/* End of stream.
 */	pop_stack();
	if (start != ptr) {
	  ssi->current = make_shared_binary_string(start, ptr-start);
	  ssi->index++;
	}
      }
      free_string( ssi->buffer );
      ssi->buffer = NULL;
      return;
   }
  
  #define f_file_line_iterator_value_defined
ptrdiff_t f_file_line_iterator_value_fun_num = 0;
void f_file_line_iterator_value(INT32 args) {
#line 963 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("value",args,0);
{
      if (THIS->current) {
	ref_push_string(THIS->current);
      } else {
	push_undefined();
      }
    }

  }
#define f_file_line_iterator_index_defined
ptrdiff_t f_file_line_iterator_index_fun_num = 0;
void f_file_line_iterator_index(INT32 args) {
#line 972 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("index",args,0);
{
      if (!THIS->current) {
	push_undefined();
      }else{
	do { INT_TYPE ret_=(THIS->index);  push_int(ret_); return; }while(0);
#line 978 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}
    }

  }
#define f_file_line_iterator_cq__backtick_add_defined
ptrdiff_t f_file_line_iterator_cq__backtick_add_fun_num = 0;
void f_file_line_iterator_cq__backtick_add(INT32 args) {
#line 981 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 981 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+",args,1);
#line 981 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+",1,"int(0..)");
steps=Pike_sp[0-1].u.integer;
#line 982 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      struct object *o=low_clone(file_line_iterator_program);
      struct file_line_iterator_struct *ssi;
      if (steps < 0)
	SIMPLE_ARG_ERROR ("Stdio.File.LineIterator.`+", 1,
			  "This iterator doesn't support going backwards.\n");
      (ssi = OBJ2_FILE_LINE_ITERATOR(o))[0]=*THIS;
      if (THIS->buffer) {
	add_ref(THIS->buffer);
      }
      if (THIS->current) {
	add_ref(THIS->current);
      }
      add_ref_svalue(&THIS->feed);
      while( steps-- )
	fl_find_next(ssi);
      do { struct object * ret_=(o); pop_stack(); push_object(ret_); return; }while(0);
#line 999 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_file_line_iterator_cq__backtick_add_eq_defined
ptrdiff_t f_file_line_iterator_cq__backtick_add_eq_fun_num = 0;
void f_file_line_iterator_cq__backtick_add_eq(INT32 args) {
#line 1001 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 1001 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+=",args,1);
#line 1001 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+=",1,"int(0..)");
steps=Pike_sp[0-1].u.integer;
#line 1002 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (steps < 0)
	SIMPLE_ARG_ERROR ("Stdio.File.LineIterator.`+=", 1,
			  "This iterator doesn't support going backwards.\n");
      while( steps-- )
	fl_find_next(THIS);
      do { struct object * ret_=(Pike_fp->current_object); add_ref(ret_); pop_stack(); push_object(ret_); return; }while(0);
#line 1009 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_file_line_iterator_next_defined
ptrdiff_t f_file_line_iterator_next_fun_num = 0;
void f_file_line_iterator_next(INT32 args) {
#line 1011 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("next",args,0);
{
      fl_find_next(THIS);
      do { INT_TYPE ret_=(!!THIS->current);  push_int(ret_); return; }while(0);
#line 1015 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_file_line_iterator_cq__backtick_21_defined
ptrdiff_t f_file_line_iterator_cq__backtick_21_fun_num = 0;
void f_file_line_iterator_cq__backtick_21(INT32 args) {
#line 1017 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("`!",args,0);
{
      do { INT_TYPE ret_=(!THIS->current);  push_int(ret_); return; }while(0);
#line 1020 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_file_line_iterator_create_defined
ptrdiff_t f_file_line_iterator_create_fun_num = 0;
void f_file_line_iterator_create(INT32 args) {
#line 1022 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct svalue * feed;
#line 1022 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args > 1) wrong_number_of_args_error("create",args,1);
if ((args > 0) && 
    ((Pike_sp[0-args].type != PIKE_T_INT) ||
     (Pike_sp[0-args].u.integer))) {
#line 1022 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-args].type != PIKE_T_FUNCTION) SIMPLE_BAD_ARG_ERROR("create",1,"function(:string)|void");
#line 1022 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
feed=Pike_sp+0-args; dmalloc_touch_svalue(Pike_sp+0-args);
} else feed=0;
#line 1023 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (THIS->buffer) {
	Pike_error("iterators cannot be reused.\n");
      }
      if (!feed) {
	Pike_error("iterator create argument must be function(:string).\n");
      }
      assign_svalue( &THIS->feed, feed );
      apply_svalue( &THIS->feed, 0 );
      if( Pike_sp[-1].type != PIKE_T_STRING )
	Pike_error("Feed function returned illegal value\n");
      THIS->buffer = Pike_sp[-1].u.string;
      dmalloc_touch_svalue(Pike_sp-1);
      Pike_sp--;
      THIS->offset = 0;
      THIS->current = NULL;
      THIS->index = -1;
      fl_find_next(THIS);
    }
  
  }

#undef internal_init_file_line_iterator_defined
#define internal_init_file_line_iterator_defined

#undef file_line_iterator_event_handler_defined
#define file_line_iterator_event_handler_defined
static void init_file_line_iterator_struct(void)
#line 1044 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      THIS->buffer = NULL;
      THIS->current = NULL;
      THIS->offset = 0;
      THIS->index = 0;
      THIS->feed.type = T_INT;
      THIS->feed.u.integer = 0;
    }

  
#undef internal_exit_file_line_iterator_defined
#define internal_exit_file_line_iterator_defined

#undef file_line_iterator_event_handler_defined
#define file_line_iterator_event_handler_defined
static void exit_file_line_iterator_struct(void)
#line 1054 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (THIS->buffer) {
	free_string(THIS->buffer);
	THIS->buffer = NULL;
      }
      if (THIS->current) {
	free_string(THIS->current);
	THIS->current = NULL;
      }
      free_svalue(&THIS->feed);
      THIS->feed.type = T_INT;
      THIS->feed.u.integer = 0;
    }
  
  

#ifdef file_line_iterator_event_handler_defined
static void file_line_iterator_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_file_line_iterator_defined
  case PROG_EVENT_INIT: init_file_line_iterator_struct(); break;

#endif /* internal_init_file_line_iterator_defined */

#ifdef internal_exit_file_line_iterator_defined
  case PROG_EVENT_EXIT: exit_file_line_iterator_struct(); break;

#endif /* internal_exit_file_line_iterator_defined */
  default: break; 
  }
}

#endif /* file_line_iterator_event_handler_defined */
/*! @module String
 */

/*! @class SplitIterator
 *! @inherit predef::Iterator
 *!
 *! An iterator that iterates over substrings of a string, separated
 *! by a character or several different characters.
 *!
 *! @note
 *!   Typically you don't need to explicitly use the SplitIterator.
 *!   Expressions like the following are automatically optimized into
 *!   using a SplitIterator.
 *!   @code
 *!     foreach(str/"\n", string line)
 *!       write("%s\n", line);
 *!   @endcode
 */

#undef class_string_split_iterator_defined
#define class_string_split_iterator_defined
struct program *string_split_iterator_program=NULL;
static int string_split_iterator_program_fun_num=-1;

#undef var_buffer_string_split_iterator_defined
#define var_buffer_string_split_iterator_defined

#undef var_current_string_split_iterator_defined
#define var_current_string_split_iterator_defined

#undef var_offset_string_split_iterator_defined
#define var_offset_string_split_iterator_defined

#undef var_index_string_split_iterator_defined
#define var_index_string_split_iterator_defined

#undef var_split_set_string_split_iterator_defined
#define var_split_set_string_split_iterator_defined

#undef var_split_set_size_string_split_iterator_defined
#define var_split_set_size_string_split_iterator_defined

#undef var_flags_string_split_iterator_defined
#define var_flags_string_split_iterator_defined

#undef var_feed_string_split_iterator_defined
#define var_feed_string_split_iterator_defined

#undef THIS
#define THIS ((struct string_split_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_STRING_SPLIT_ITERATOR
#define THIS_STRING_SPLIT_ITERATOR ((struct string_split_iterator_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_STRING_SPLIT_ITERATOR
#define OBJ2_STRING_SPLIT_ITERATOR(o) ((struct string_split_iterator_struct *)(o->storage+string_split_iterator_storage_offset))

#undef GET_STRING_SPLIT_ITERATOR_STORAGE
#define GET_STRING_SPLIT_ITERATOR_STORAGE ((struct string_split_iterator_struct *)(o->storage+string_split_iterator_storage_offset)
static ptrdiff_t string_split_iterator_storage_offset;
struct string_split_iterator_struct {

#ifdef var_buffer_string_split_iterator_defined
#line 1091 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct pike_string *buffer;
#endif /* var_buffer_string_split_iterator_defined */

#ifdef var_current_string_split_iterator_defined
#line 1092 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct pike_string *current;
#endif /* var_current_string_split_iterator_defined */

#ifdef var_offset_string_split_iterator_defined
#line 1093 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
int offset;
#endif /* var_offset_string_split_iterator_defined */

#ifdef var_index_string_split_iterator_defined
#line 1094 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
int index;
#endif /* var_index_string_split_iterator_defined */

#ifdef var_split_set_string_split_iterator_defined
#line 1095 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
p_wchar2 *split_set;
#endif /* var_split_set_string_split_iterator_defined */

#ifdef var_split_set_size_string_split_iterator_defined
#line 1096 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
int split_set_size;
#endif /* var_split_set_size_string_split_iterator_defined */

#ifdef var_flags_string_split_iterator_defined
#line 1097 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
int flags;
#endif /* var_flags_string_split_iterator_defined */

#ifdef var_feed_string_split_iterator_defined
#line 1098 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct svalue feed;
#endif /* var_feed_string_split_iterator_defined */
};
#line 1100 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
#define SIMPLE_SKIP(THIS, SHIFT, OFF) 	 	\
  do {						\
    PIKE_CONCAT(p_wchar, SHIFT) *s = 		\
      PIKE_CONCAT(STR,SHIFT)(THIS->buffer);	\
    while((OFF < THIS->buffer->len) &&		\
          s[OFF] == THIS->split_set[0]) {	\
      OFF++;					\
    }						\
  } while(0)

#define SIMPLE_SKIP_CASE(THIS, SHIFT, OFF)	\
  case SHIFT:					\
    SIMPLE_SKIP(THIS, SHIFT, OFF);		\
    break

#define COMPLEX_SKIP(THIS, SHIFT, OFF)	 		\
  do {							\
    PIKE_CONCAT(p_wchar, SHIFT) *s = 			\
      PIKE_CONCAT(STR,SHIFT)(THIS->buffer);		\
    while(OFF < THIS->buffer->len) {			\
      int i;						\
      p_wchar2 ch = s[OFF];				\
      for (i=0; i < THIS->split_set_size; i++) {	\
	if (ch == THIS->split_set[i]) {			\
	  goto PIKE_CONCAT(continue_skip,SHIFT);	\
	}						\
      }							\
      break;						\
    PIKE_CONCAT(continue_skip,SHIFT):			\
      OFF++;						\
    }							\
  } while(0)
  
#define COMPLEX_SKIP_CASE(THIS, SHIFT, OFF)	\
  case SHIFT:					\
    COMPLEX_SKIP(THIS, SHIFT, OFF);		\
    break

#define SIMPLE_SCAN(THIS, SHIFT, OFF)		\
  do {						\
    PIKE_CONCAT(p_wchar, SHIFT) *s = 		\
      PIKE_CONCAT(STR,SHIFT)(THIS->buffer);	\
    while((OFF < THIS->buffer->len) &&		\
          s[OFF] != THIS->split_set[0]) {	\
      OFF++;					\
    }						\
  } while(0)

#define SIMPLE_SCAN_CASE(THIS, SHIFT, OFF)	\
  case SHIFT:					\
    SIMPLE_SCAN(THIS, SHIFT, OFF);		\
    break

#define COMPLEX_SCAN(THIS, SHIFT, OFF)				\
  do {								\
    PIKE_CONCAT(p_wchar, SHIFT) *s = 				\
      PIKE_CONCAT(STR,SHIFT)(THIS->buffer);			\
    while(OFF < THIS->buffer->len) {				\
      int i;							\
      p_wchar2 ch = s[OFF];					\
      for (i=0; i < THIS->split_set_size; i++) {		\
	if (ch == THIS->split_set[i]) {				\
	  goto PIKE_CONCAT(break_scan,SHIFT);			\
	}							\
      }								\
      OFF++;							\
    }								\
  PIKE_CONCAT(break_scan, SHIFT): ;/* gcc complains without ;*/ \
  } while(0)

#define COMPLEX_SCAN_CASE(THIS, SHIFT, OFF)	\
  case SHIFT:					\
    COMPLEX_SCAN(THIS, SHIFT, OFF);		\
    break

#define SIMPLE_SCAN_PUSH(THIS, SHIFT, OFF)			\
  do {								\
    PIKE_CONCAT(p_wchar, SHIFT) *s = 				\
      PIKE_CONCAT(STR,SHIFT)(THIS->buffer);			\
    while((OFF < THIS->buffer->len) &&				\
          s[OFF] != THIS->split_set[0]) {			\
      OFF++;							\
    }								\
    push_string(PIKE_CONCAT(make_shared_binary_string, SHIFT)	\
      (s+offset, OFF-offset));					\
  } while(0)

#define SIMPLE_SCAN_CASE_PUSH(THIS, SHIFT, OFF)	\
  case SHIFT:					\
    SIMPLE_SCAN_PUSH(THIS, SHIFT, OFF);		\
    break

#define COMPLEX_SCAN_PUSH(THIS, SHIFT, OFF)				\
  do {									\
    PIKE_CONCAT(p_wchar, SHIFT) *s = 					\
      PIKE_CONCAT(STR,SHIFT)(THIS->buffer);				\
    while(OFF < THIS->buffer->len) {					\
      int i;								\
      p_wchar2 ch = s[OFF];						\
      for (i=0; i < THIS->split_set_size; i++) {			\
	if (ch == THIS->split_set[i]) {					\
	  push_string(PIKE_CONCAT(make_shared_binary_string, SHIFT)	\
	    (s+offset, OFF-offset));					\
	  goto PIKE_CONCAT(break_scan,SHIFT);				\
	}								\
      }									\
      OFF++;								\
    }									\
    push_string(PIKE_CONCAT(make_shared_binary_string, SHIFT)		\
      (s+offset, OFF-offset));						\
  PIKE_CONCAT(break_scan, SHIFT):					\
    ;									\
  } while(0)

#define COMPLEX_SCAN_CASE_PUSH(THIS, SHIFT, OFF)	\
  case SHIFT:						\
    COMPLEX_SCAN_PUSH(THIS, SHIFT, OFF);		\
    break

#define NEW_SKIP_CASE(SHIFT, FLAGS)				\
  case SHIFT:							\
    if (FLAGS) {						\
      /* Skip empty */						\
      if (ssi->split_set_size == 1) {				\
	SIMPLE_SKIP(ssi, SHIFT, offset);			\
      } else {							\
        COMPLEX_SKIP(ssi, SHIFT, offset);			\
      }								\
    }								\
    if (offset >= ssi->buffer->len) {				\
      free_string(ssi->buffer);					\
      ssi->buffer = NULL;					\
      ssi->offset = 0;						\
      offset = 0;						\
      if (ssi->feed.type == T_INT) {				\
	if (!(FLAGS)) {						\
	  copy_shared_string(ssi->current, empty_pike_string);	\
	  ssi->index++;						\
	}							\
	return;							\
      } else {							\
	/* Attempt to fill the buffer with some more. */	\
	apply_svalue(&ssi->feed, 0);				\
	if ((Pike_sp[-1].type == T_STRING) &&			\
	    (Pike_sp[-1].u.string->len)) {			\
	  ssi->buffer = Pike_sp[-1].u.string;			\
          dmalloc_touch_svalue(Pike_sp-1);			\
	  Pike_sp--;						\
	  goto reskip_empty;					\
	}							\
	free_svalue(&ssi->feed);				\
	ssi->feed.type = T_INT;					\
	ssi->feed.u.integer = 0;				\
	pop_stack();						\
	if (!(FLAGS)) {						\
	  copy_shared_string(ssi->current, empty_pike_string);	\
	  ssi->index++;						\
	}							\
	return;							\
      }								\
    }								\
    ssi->index++;						\
    end = offset;						\
    goto PIKE_CONCAT(scan_more_,SHIFT)

#define NEW_SCAN_MORE_CASE(SHIFT)				\
  case SHIFT:							\
  PIKE_CONCAT(scan_more_,SHIFT):				\
    if (ssi->split_set_size == 1) {				\
      SIMPLE_SCAN_PUSH(ssi, SHIFT, end);			\
    } else {							\
      COMPLEX_SCAN_PUSH(ssi, SHIFT, end);			\
    }								\
    if ((end == ssi->buffer->len) &&				\
	(ssi->feed.type != T_INT)) {				\
      apply_svalue(&ssi->feed, 0);				\
      if ((Pike_sp[-1].type == T_STRING) &&			\
	  (Pike_sp[-1].u.string->len)) {			\
	f_add(2);						\
	if (Pike_sp[-1].type != T_STRING) {			\
	  Pike_error("Bad result from concatenation!\n");	\
	}							\
	free_string(ssi->buffer);				\
	ssi->buffer = Pike_sp[-1].u.string;			\
        dmalloc_touch_svalue(Pike_sp-1);			\
	Pike_sp--;						\
	end -= offset;						\
	offset = 0;						\
	goto scan_more;						\
      }								\
      pop_stack();	/* Pop the end of stream marker. */	\
      								\
      /* Make sure we don't call feed() any more. */		\
      free_svalue(&ssi->feed);					\
      ssi->feed.type = T_INT;					\
      ssi->feed.u.integer = 0;					\
    }								\
    ssi->offset = end+1;					\
    ssi->current = Pike_sp[-1].u.string;			\
    dmalloc_touch_svalue(Pike_sp-1);				\
    Pike_sp--;							\
    if (ssi->offset > ssi->buffer->len) {			\
      free_string(ssi->buffer);					\
      ssi->buffer = 0;						\
    }								\
    break
  
  static void find_next(struct string_split_iterator_struct *ssi)
    {
      int offset = ssi->offset;
      int end;
      if (ssi->current) {
	free_string(ssi->current);
      }
      ssi->current = NULL;
      if (!ssi->buffer) {
	return;
      }
    reskip_empty:
      switch(ssi->buffer->size_shift) {
	NEW_SKIP_CASE(0, ssi->flags);
	NEW_SKIP_CASE(1, ssi->flags);
	NEW_SKIP_CASE(2, ssi->flags);
      default:
	Pike_fatal("Unsupported size shift!\n");
      }
    scan_more:
      switch(ssi->buffer->size_shift)
      {
	NEW_SCAN_MORE_CASE(0);
	NEW_SCAN_MORE_CASE(1);
	NEW_SCAN_MORE_CASE(2);
      default:
	Pike_fatal("Unsupported size shift!\n");
      }
    }

  #define f_string_split_iterator_value_defined
ptrdiff_t f_string_split_iterator_value_fun_num = 0;
void f_string_split_iterator_value(INT32 args) {
#line 1337 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("value",args,0);
{
      if (THIS->current) {
	ref_push_string(THIS->current);
      } else {
	push_undefined();
      }
    }

  }
#define f_string_split_iterator_index_defined
ptrdiff_t f_string_split_iterator_index_fun_num = 0;
void f_string_split_iterator_index(INT32 args) {
#line 1346 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("index",args,0);
{
      if (!THIS->current) {
	push_undefined();
      }else{
	do { INT_TYPE ret_=(THIS->index);  push_int(ret_); return; }while(0);
#line 1352 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}
    }

  }
#define f_string_split_iterator_cq__backtick_add_defined
ptrdiff_t f_string_split_iterator_cq__backtick_add_fun_num = 0;
void f_string_split_iterator_cq__backtick_add(INT32 args) {
#line 1355 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 1355 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+",args,1);
#line 1355 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+",1,"int(0..)");
steps=Pike_sp[0-1].u.integer;
#line 1356 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      struct object *o=low_clone(string_split_iterator_program);
      int i;
      struct string_split_iterator_struct *ssi;
      if (steps < 0)
	SIMPLE_ARG_ERROR ("String.SplitIterator.`+", 1,
			  "This iterator doesn't support going backwards.\n");
      (ssi = OBJ2_STRING_SPLIT_ITERATOR(o))[0]=*THIS;
      if (THIS->buffer) {
	add_ref(THIS->buffer);
      }
      if (THIS->current) {
	add_ref(THIS->current);
      }
      add_ref_svalue(&THIS->feed);
      for (i=0; i < steps; i++) {
	find_next(ssi);
      }
      do { struct object * ret_=(o); pop_stack(); push_object(ret_); return; }while(0);
#line 1375 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_string_split_iterator_cq__backtick_add_eq_defined
ptrdiff_t f_string_split_iterator_cq__backtick_add_eq_fun_num = 0;
void f_string_split_iterator_cq__backtick_add_eq(INT32 args) {
#line 1377 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
INT_TYPE steps;
#line 1377 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("`+=",args,1);
#line 1377 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("`+=",1,"int(0..)");
steps=Pike_sp[0-1].u.integer;
#line 1378 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
    int i;
    if (steps < 0)
      SIMPLE_ARG_ERROR ("String.SplitIterator.`+=", 1,
			"This iterator doesn't support going backwards.\n");
    for(i = 0; i < steps; i++) {
      find_next(THIS);
    }
    do { struct object * ret_=(Pike_fp->current_object); add_ref(ret_); pop_stack(); push_object(ret_); return; }while(0);
#line 1387 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_string_split_iterator_next_defined
ptrdiff_t f_string_split_iterator_next_fun_num = 0;
void f_string_split_iterator_next(INT32 args) {
#line 1389 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("next",args,0);
{
      find_next(THIS);
      do { INT_TYPE ret_=(!!THIS->current);  push_int(ret_); return; }while(0);
#line 1393 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_string_split_iterator_cq__backtick_21_defined
ptrdiff_t f_string_split_iterator_cq__backtick_21_fun_num = 0;
void f_string_split_iterator_cq__backtick_21(INT32 args) {
#line 1395 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("`!",args,0);
{
      do { INT_TYPE ret_=(!THIS->current);  push_int(ret_); return; }while(0);
#line 1398 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
#define f_string_split_iterator_cq__sizeof_defined
ptrdiff_t f_string_split_iterator_cq__sizeof_fun_num = 0;
void f_string_split_iterator_cq__sizeof(INT32 args) {
#line 1400 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 0) wrong_number_of_args_error("_sizeof",args,0);
{
    INT_TYPE res = 0;
    if (THIS->buffer) {
      int i, off;
      ref_push_string(THIS->buffer);
      if (THIS->offset) {
	push_int(THIS->offset);
	push_int(THIS->buffer->len);
	o_range();
      }
      for (i = 1; THIS->feed.type != T_INT; i++) {
	apply_svalue(&THIS->feed, 0);
	if ((Pike_sp[-1].type != T_STRING) ||
	    (!Pike_sp[-1].u.string->len)) {
	  /* End of stream marker. */
	  pop_stack();
	  free_svalue(&THIS->feed);
	  THIS->feed.type = T_INT;
	  THIS->feed.u.integer = 0;
	  break;
	}
      }
      f_add(i);	/* Join the segments. */
      free_string(THIS->buffer);
      THIS->buffer = Pike_sp[-1].u.string;
      THIS->offset = 0;
      dmalloc_touch_svalue(Pike_sp-1);
      Pike_sp--;

      /* Perform the scan. */
      for (off=0; off < THIS->buffer->len; off++) {
	if (THIS->flags) {
	  if (THIS->split_set_size == 1) {
	    switch(THIS->buffer->size_shift) {
	      SIMPLE_SKIP_CASE(THIS, 0, off);
	      SIMPLE_SKIP_CASE(THIS, 1, off);
	      SIMPLE_SKIP_CASE(THIS, 2, off);
	    default:
	      Pike_fatal("Unsupported size shift!\n");
	    }
	  } else {
	    switch(THIS->buffer->size_shift) {
	      COMPLEX_SKIP_CASE(THIS, 0, off);
	      COMPLEX_SKIP_CASE(THIS, 1, off);
	      COMPLEX_SKIP_CASE(THIS, 2, off);
	    default:
	      Pike_fatal("Unsupported size shift!\n");
	    }	  
	  }
	  if (off >= THIS->buffer->len) {
	    break;
	  }
	}
	res++;
	if (THIS->split_set_size == 1) {
	  switch(THIS->buffer->size_shift) {
	    SIMPLE_SCAN_CASE(THIS, 0, off);
	    SIMPLE_SCAN_CASE(THIS, 1, off);
	    SIMPLE_SCAN_CASE(THIS, 2, off);
	  default:
	    Pike_fatal("Unsupported size shift!\n");
	  }
	} else {
	  switch(THIS->buffer->size_shift) {
	    COMPLEX_SCAN_CASE(THIS, 0, off);
	    COMPLEX_SCAN_CASE(THIS, 1, off);
	    COMPLEX_SCAN_CASE(THIS, 2, off);
	  default:
	    Pike_fatal("Unsupported size shift!\n");
	  }
	}
      }
      if ((!THIS->flags) && (off == THIS->buffer->len)) {
	/* Ends with an empty segment. */
	res++;
      }
    }
    if (THIS->current) {
      res++;
    }
    do { INT_TYPE ret_=(res);  push_int(ret_); return; }while(0);
#line 1482 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

  }
/*! @decl void create(string buffer, int|array(int)|multiset(int) split_set,@
   *!                   int|void flags, function(:string)|void feed)
   *! @param buffer
   *!   The string to split.
   *! @param split_set
   *!   The character or characters to split on.
   *! @param flags
   *!   Skip empty elements if set.
   *! @param feed
   *!   Callback function that is called once the @[buffer] is used up
   *!   and the SplitIterator wants more data.
   */
  #define f_string_split_iterator_create_defined
ptrdiff_t f_string_split_iterator_create_fun_num = 0;
void f_string_split_iterator_create(INT32 args) {
#line 1496 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct pike_string * buffer;
#line 1496 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct svalue * split_set;
struct svalue * flags;
#line 1497 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct svalue * feed;
#line 1496 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args < 2) wrong_number_of_args_error("create",args,2);
#line 1496 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args > 4) wrong_number_of_args_error("create",args,4);
#line 1496 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[0-args].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("create",1,"string");
#line 1496 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
debug_malloc_pass(buffer=Pike_sp[0-args].u.string);
#line 1496 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
split_set=Pike_sp+1-args; dmalloc_touch_svalue(Pike_sp+1-args);
if (args > 2) {if(Pike_sp[2-args].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("create",3,"int|void");
#line 1497 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
flags=Pike_sp+2-args; dmalloc_touch_svalue(Pike_sp+2-args);
} else flags=0;
if ((args > 3) && 
    ((Pike_sp[3-args].type != PIKE_T_INT) ||
     (Pike_sp[3-args].u.integer))) {
#line 1497 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(Pike_sp[3-args].type != PIKE_T_FUNCTION) SIMPLE_BAD_ARG_ERROR("create",4,"function(:string)|void");
#line 1497 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
feed=Pike_sp+3-args; dmalloc_touch_svalue(Pike_sp+3-args);
} else feed=0;
#line 1498 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (THIS->buffer) {
	Pike_error("String.split() iterators cannot be reused.\n");
      }
      if (split_set->type == T_INT) {
	THIS->split_set = (p_wchar2 *)xalloc(sizeof(p_wchar2));
	THIS->split_set[0] = split_set->u.integer;
	THIS->split_set_size = 1;
      } else {
	struct array *a;
	int i;
	if (split_set->type == T_ARRAY) {
	  a = split_set->u.array;
	} else if (split_set->type == T_MULTISET) {
	  a = multiset_indices (split_set->u.multiset);
	  push_array (a);
	} else {
	  SIMPLE_BAD_ARG_ERROR("String.split", 2,
			       "int|array(int)|multiset(int)");
	}
	if (!a->size) {
	  SIMPLE_BAD_ARG_ERROR("String.split", 2,
			       "int|array(int)|multiset(int)");
	}
	for (i=0; i < a->size; i++) {
	  if (a->item[i].type != T_INT) {
	    SIMPLE_BAD_ARG_ERROR("String.split", 2,
				 "int|array(int)|multiset(int)");
	  }
	}
	THIS->split_set = (p_wchar2 *)xalloc(a->size * sizeof(p_wchar2));
	for (i=0; i < a->size; i++) {
	  THIS->split_set[i] = a->item[i].u.integer;
	}
	THIS->split_set_size = a->size;
	if (split_set->type == T_MULTISET) pop_stack();
      }
      add_ref(THIS->buffer = buffer);
      if (args > 2) {
	if (flags->type == T_INT) {
	  THIS->flags = flags->u.integer;
	} else {
	  THIS->flags = 0;
	}
	if (args > 3) {
	  assign_svalue(&THIS->feed, feed);
	} else {
	  /* NB: THIS->feed has already been set to 0 by the init code. */
	}
      } else {
	THIS->flags = 0;
      }
      THIS->offset = 0;
      THIS->current = NULL;
      THIS->index = -1;
      find_next(THIS);
    }
  
  }

#undef internal_init_string_split_iterator_defined
#define internal_init_string_split_iterator_defined

#undef string_split_iterator_event_handler_defined
#define string_split_iterator_event_handler_defined
static void init_string_split_iterator_struct(void)
#line 1557 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      THIS->buffer = NULL;
      THIS->current = NULL;
      THIS->offset = 0;
      THIS->index = 0;
      THIS->split_set = NULL;
      THIS->split_set_size = 0;
      THIS->flags = 0;
      THIS->feed.type = T_INT;
      THIS->feed.u.integer = 0;
    }

  
#undef internal_exit_string_split_iterator_defined
#define internal_exit_string_split_iterator_defined

#undef string_split_iterator_event_handler_defined
#define string_split_iterator_event_handler_defined
static void exit_string_split_iterator_struct(void)
#line 1570 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (THIS->buffer) {
	free_string(THIS->buffer);
	THIS->buffer = NULL;
      }
      if (THIS->current) {
	free_string(THIS->current);
	THIS->current = NULL;
      }
      free(THIS->split_set);
      THIS->split_set = NULL;
      free_svalue(&THIS->feed);
      THIS->feed.type = T_INT;
      THIS->feed.u.integer = 0;
    }

  
#undef internal_optimize_string_split_iterator_defined
#define internal_optimize_string_split_iterator_defined

#undef string_split_iterator_optimize_callback_defined
#define string_split_iterator_optimize_callback_defined
static node *optimize_string_split_iterator_struct(node *n)
#line 1587 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
      if (CDR(n) && (CDR(n)->token == F_ARG_LIST) &&
	  CADR(n) && (CADR(n)->token == F_APPLY) &&
	  CAADR(n) && (CAADR(n)->token == F_CONSTANT) &&
	  (CAADR(n)->u.sval.type == T_FUNCTION) &&
	  (CAADR(n)->u.sval.subtype == FUNCTION_BUILTIN) &&
	  (CAADR(n)->u.sval.u.efun->function == f_replace)) {
	/* String.SplitIterator(replace(...),...) */
	node *repl_args = CDADR(n);
	node **str = my_get_arg(&repl_args, 0);
	node **from = my_get_arg(&repl_args, 1);
	node **to = my_get_arg(&repl_args, 2);

	if (str && from && to) {
	  /* String.SplitIterator(replace(str, from, to), ...) */

	  int num;

	  if (((*to)->token == F_APPLY) &&
	      CAR(*to) && (CAR(*to)->token == F_CONSTANT) &&
	      (CAR(*to)->u.sval.type == T_FUNCTION) &&
	      (CAR(*to)->u.sval.subtype == FUNCTION_BUILTIN) &&
	      (CAR(*to)->u.sval.u.efun->function == f_allocate) &&
	      CDR(*to) && (CDR(*to)->token == F_ARG_LIST) &&
	      CADR(*to) && (CADR(*to)->token == F_CONSTANT) &&
	      (CADR(*to)->u.sval.type == T_INT) &&
	      (num = CADR(*to)->u.sval.u.integer) &&
	      CDDR(*to) && (CDDR(*to)->token == F_CONSTANT) &&
	      (CDDR(*to)->u.sval.type == T_STRING) &&
	      (CDDR(*to)->u.sval.u.string->len == 1)) {
	    /* String.SplitIterator(replace(str, from, allocate(num, "x")),
	     *                      ...) */
	    int split_val = index_shared_string(CDDR(*to)->u.sval.u.string, 0);

	    if (CDDR(n) &&
		(((CDDR(n)->token == F_CONSTANT) &&
		  (CDDR(n)->u.sval.type == T_INT) &&
		  (CDDR(n)->u.sval.u.integer == split_val)) ||
		 ((CDDR(n)->token == F_ARG_LIST) &&
		  CADDR(n) && (CADDR(n)->token == F_CONSTANT) &&
		  (CADDR(n)->u.sval.type == T_INT) &&
		  (CADDR(n)->u.sval.u.integer == split_val)))) {
	      /* String.SplitIterator(replace(str, from, allocate(n, "x")),
	       *                      'x', ...)
	       */
	      struct array *split = NULL;
	      node *res = NULL;

	      switch((*from)->token) {
	      case F_CONSTANT:
		if (((*from)->u.sval.type == T_ARRAY) &&
		    ((*from)->u.sval.u.array->size == num)) {
		  int i;
		  for (i=0; i < num; i++) {
		    if (((*from)->u.sval.u.array->item[i].type != T_STRING) ||
			((*from)->u.sval.u.array->item[i].u.string->len != 1)) {
		      return NULL;
		    }
		  }
		  split = allocate_array(num+1);
		  split->item[0].u.integer = split_val;
		  for (i=0; i < num; i++) {
		    split->item[i+1].u.integer =
		      index_shared_string((*from)->u.sval.u.array->
					  item[i].u.string, 0);
		  }
		  split->type_field = BIT_INT;
		}
		break;
	      case F_APPLY:
		if (CAR(*from) && (CAR(*from)->token == F_CONSTANT) &&
		    (CAR(*from)->u.sval.type == T_FUNCTION) &&
		    (CAR(*from)->u.sval.subtype == FUNCTION_BUILTIN)) {
		  if (CAR(*from)->u.sval.u.efun->function == f_allocate) {
		    /* FIXME: Not likely */
		  } else if (CAR(*from)->u.sval.u.efun->function ==
			     debug_f_aggregate) {
		    node *tmp = CDR(*from);
		    int i;
		    for (i = 0; tmp && (tmp->token == F_ARG_LIST);
			 tmp = CDR(tmp)) {
		      if (!CAR(tmp)) continue;
		      if ((CAR(tmp)->token != F_CONSTANT) || 
			  (CAR(tmp)->u.sval.type != T_STRING) ||
			  (CAR(tmp)->u.sval.u.string->len != 1)) {
			return NULL;
		      }
		      i++;
		    }
		    if (i != num) {
		      return NULL;
		    }
		    split = allocate_array(num+1);
		    split->item[0].u.integer = split_val;
		    tmp = CDR(*from);
		    for (i = 1; tmp && (tmp->token == F_ARG_LIST);
			 tmp = CDR(tmp)) {
		      if (!CAR(tmp)) continue;
		      split->item[i].u.integer =
			index_shared_string(CAR(tmp)->u.sval.u.string, 0);
		      i++;
		    }
		    split->type_field = BIT_INT;
		  }
		} else {
		  return NULL;
		}
		break;
	      default:
		return NULL;
	      }
	      if (!split) {
		return NULL;
	      }
	      push_array(split);	/* Simplify error-handling... */

	      /* Create the result...
	       *
	       * String.SplitIterator(str, split, ...)
	       */
	      if (CDDR(n)->token == F_ARG_LIST) {
		ADD_NODE_REF2(CAR(n),
		ADD_NODE_REF2(*str,
		ADD_NODE_REF2(CDDDR(n),
		  res =
		    mkapplynode(CAR(n),
			        mknode(F_ARG_LIST, *str,
				       mknode(F_ARG_LIST,
					      mkconstantsvaluenode(Pike_sp-1),
					      CDDDR(n))));
		)));
	      } else {
		ADD_NODE_REF2(CAR(n),
		ADD_NODE_REF2(*str,
		  res =
		    mkapplynode(CAR(n),
			        mknode(F_ARG_LIST, *str,
				       mkconstantsvaluenode(Pike_sp-1)));
		));
	      }
	      pop_stack();
	      return res;
	    }
	  }
	}
      }
      return NULL;
    }

#ifdef string_split_iterator_event_handler_defined
static void string_split_iterator_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_string_split_iterator_defined
  case PROG_EVENT_INIT: init_string_split_iterator_struct(); break;

#endif /* internal_init_string_split_iterator_defined */

#ifdef internal_exit_string_split_iterator_defined
  case PROG_EVENT_EXIT: exit_string_split_iterator_struct(); break;

#endif /* internal_exit_string_split_iterator_defined */
  default: break; 
  }
}

#endif /* string_split_iterator_event_handler_defined */
#line 1735 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
;

/*! @endclass
 */

/*! @endmodule
 */

/*! @decl Iterator get_iterator (object|array|mapping|multiset|string data)
 *!
 *! Creates and returns a canonical iterator for @[data].
 *!
 *! @returns
 *!   @mixed data
 *!     @type object
 *!       If @[data] is an object with @[lfun::_get_iterator] defined then
 *!       it's called in it to create the iterator.
 *!   
 *!       If @[data] is an object that lacks @[lfun::_get_iterator] then
 *!       it's assumed to already be an iterator object, and is simply
 *!       returned.
 *!     @type array
 *!       If @[data] is an array, an @[Array.Iterator] object will be
 *!       returned.
 *!     @type mapping
 *!       If @[data] is a mapping, a @[Mapping.Iterator] object will be
 *!       returned
 *!     @type multiset
 *!       If @[data] is a multiset, a @[Multiset.Iterator] object will be
 *!       returned
 *!     @type string
 *!       If @[data] is a string, a @[String.Iterator] object will be
 *!       returned
 *!   @endmixed
 *!
 *! @note
 *!   This function is used by @[foreach] to get an iterator for an
 *!   object.
 *!
 *! @seealso
 *!   @[Iterator], @[lfun::_get_iterator]
 */
#define f_get_iterator_defined
void f_get_iterator(INT32 args) {
#line 1777 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
struct svalue * data;
#line 1777 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
if(args != 1) wrong_number_of_args_error("get_iterator",args,1);
#line 1777 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
data=Pike_sp+0-1; dmalloc_touch_svalue(Pike_sp+0-1);
#line 1779 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
{
  switch(data->type)
  {
    case PIKE_T_STRING:
      push_object(clone_object(string_iterator_program, 1));
      return;

    case PIKE_T_MAPPING:
      push_object(clone_object(mapping_iterator_program,1));
      return;

    case PIKE_T_MULTISET:
      push_object(clone_object(multiset_iterator_program, 1));
      return;

    case PIKE_T_ARRAY:
      push_object(clone_object(array_iterator_program, 1));
      return;


    case PIKE_T_OBJECT: {
      int fun;

      if(!data->u.object->prog)
	SIMPLE_ARG_ERROR ("get_iterator", 1, "Got a destructed object.\n");

      fun = FIND_LFUN(data->u.object->prog, LFUN__GET_ITERATOR);
      if (fun != -1)
      {
	apply_low (data->u.object, fun, 0);
	if (sp[-1].type != T_OBJECT) {
	  /* FIXME: Ought to include what we got in the error message. */
	  pop_stack();
	  SIMPLE_ARG_ERROR ("get_iterator", 1,
			    "_get_iterator() didn't return an object.\n");
	}
	stack_pop_keep_top();
	return;
      }

      /* Assume it already is an iterator... */
      return;
    }

    default:
      SIMPLE_ARG_TYPE_ERROR("get_iterator", 1, "multiset|array|string|mapping|object");
  }
}

}
#line 1828 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
/* sp[-4] = index; sp[-2] = value */
int foreach_iterate(struct object *o, int do_step)
{
  struct program *prog = o->prog;
  int fun;

  if(!prog)
    Pike_error("foreach on destructed iterator.\n");

  if(prog->flags & PROGRAM_HAS_C_METHODS)
  {
    if(prog == mapping_iterator_program)
    {
      struct mapping_iterator_struct *i=OBJ2_MAPPING_ITERATOR(o);

      if (!i->current) return 0;
      if (do_step) {
	mi_step (i);
	if (!i->current) return 0;
      }

      if(Pike_sp[-4].type != T_INT)
	assign_lvalue(Pike_sp-4, & i->current->ind);
	
      if(Pike_sp[-2].type != T_INT)
	assign_lvalue(Pike_sp-2, & i->current->val);

      return 1;
    }

    else if(prog == string_split_iterator_program)
    {
      struct string_split_iterator_struct *i=OBJ2_STRING_SPLIT_ITERATOR(o);

      if (!i->current) return 0;
      if (do_step) {
	find_next (i);
	if (!i->current) return 0;
      }

      if(Pike_sp[-4].type != T_INT)
      {
	/* Black Magic... */
	push_int(i->index);
	Pike_sp--;
	assign_lvalue(Pike_sp-4, Pike_sp);
      }

      if(Pike_sp[-2].type != T_INT)
      {
	/* Black Magic... */
	push_string(i->current);
	dmalloc_touch_svalue(Pike_sp-1);
	Pike_sp--;
	assign_lvalue(Pike_sp-2, Pike_sp);
      }

      return 1;
    }

    else if(prog == file_line_iterator_program)
    {
      struct file_line_iterator_struct *i=OBJ2_FILE_LINE_ITERATOR(o);

      if (!i->current) return 0;
      if (do_step) {
	fl_find_next (i);
	if (!i->current) return 0;
      }

      if(Pike_sp[-4].type != T_INT)
      {
	/* Black Magic... */
	push_int(i->index);
	Pike_sp--;
	assign_lvalue(Pike_sp-4, Pike_sp);
      }

      if(Pike_sp[-2].type != T_INT)
      {
	/* Black Magic... */
	push_string(i->current);
	dmalloc_touch_svalue(Pike_sp-1);
	Pike_sp--;
	assign_lvalue(Pike_sp-2, Pike_sp);
      }

      return 1;
    }

    else if(prog == array_iterator_program)
    {
      struct array_iterator_struct *i=OBJ2_ARRAY_ITERATOR(o);

      if (i->pos < 0 || i->pos >= i->a->size) return 0;
      if (do_step)
	if (++i->pos == i->a->size) return 0;

      if(Pike_sp[-4].type != T_INT)
      {
	push_int(i->pos);
	assign_lvalue(Pike_sp-5, Pike_sp-1);
	pop_stack();
      }

      if(Pike_sp[-2].type != T_INT)
	assign_lvalue(Pike_sp-2, i->a->item + i->pos);

      return 1;
    }

    else if(prog == multiset_iterator_program)
    {
      struct multiset_iterator_struct *i=OBJ2_MULTISET_ITERATOR(o);

      struct svalue ind;

      if (i->nodepos < 0) return 0;
      if (do_step) {
	i->nodepos = multiset_next (i->l, i->nodepos);
	if (i->nodepos < 0) {
	  sub_msnode_ref (i->l);
	  return 0;
	}
      }

      if (Pike_sp[-4].type != T_INT)
	assign_lvalue (Pike_sp - 4, use_multiset_index (i->l, i->nodepos, ind));
      if (Pike_sp[-2].type != T_INT)
	assign_lvalue (Pike_sp - 2, get_multiset_value (i->l, i->nodepos));

      return 1;
    }

    else if(prog == string_iterator_program)
    {
      struct string_iterator_struct *i=OBJ2_STRING_ITERATOR(o);

      if (i->pos < 0 || i->pos >= i->s->len) return 0;
      if (do_step)
	if (++i->pos == i->s->len) return 0;

      if(Pike_sp[-4].type != T_INT)
      {
	push_int(i->pos);
	assign_lvalue(Pike_sp-5, Pike_sp-1);
	pop_stack();
      }

      if(Pike_sp[-2].type != T_INT)
      {
	push_int(index_shared_string(i->s, i->pos));
	assign_lvalue(Pike_sp-3, Pike_sp-1);
	pop_stack();
      }

      return 1;
    }
  }

  /* Generic iteration */

  if (do_step) {
    fun = FIND_LFUN (prog, LFUN_ADD_EQ);
    if (fun < 0) Pike_error ("Iterator object lacks `+=.\n");
    push_int(1);
    apply_low(o, fun, 1);
    pop_stack();
  }

#if 0
  /* We should be able to save calls to `! this way, but there are
   * iterators where index() and value() don't return UNDEFINED as
   * stipulated by the interface. */

  fun = -1;

  if(Pike_sp[-4].type != T_INT)
  {
    fun = find_identifier ("index", prog);
    if (fun < 0) Pike_error ("Iterator object lacks index().\n");
    apply_low(o, fun, 0);
    if (IS_UNDEFINED (Pike_sp - 1)) {
      Pike_sp--;
      return 0;
    }
    assign_lvalue(Pike_sp-5,Pike_sp-1);
    pop_stack();
  }

  if(Pike_sp[-2].type != T_INT)
  {
    fun = find_identifier ("value", prog);
    if (fun < 0) Pike_error ("Iterator object lacks value().\n");
    apply_low(o, fun, 0);
    if (IS_UNDEFINED (Pike_sp - 1)) {
      Pike_sp--;
      return 0;
    }
    assign_lvalue(Pike_sp-3,Pike_sp-1);
    pop_stack();
  }

  if (fun >= 0)
    /* index() and/or value() has returned a value so we know we can
     * iterate without calling `!. */
    return 1;
  else {
    int res;
    fun = FIND_LFUN (prog, LFUN_NOT);
    if (fun < 0) Pike_error ("Iterator object lacks `!.\n");
    apply_low(o, fun, 0);
    res = UNSAFE_IS_ZERO(Pike_sp-1);
    pop_stack();
    return res;
  }

#else

  fun = FIND_LFUN (o->prog, LFUN_NOT);
  if (fun < 0) Pike_error ("Iterator object lacks `!.\n");
  apply_low(o, fun, 0);
  if(UNSAFE_IS_ZERO(Pike_sp-1))
  {
    pop_stack();

    if(Pike_sp[-4].type != T_INT)
    {
      fun = find_identifier ("index", o->prog);
      if (fun < 0) Pike_error ("Iterator object lacks index().\n");
      apply_low(o, fun, 0);
      assign_lvalue(Pike_sp-5,Pike_sp-1);
      pop_stack();
    }

    if(Pike_sp[-2].type != T_INT)
    {
      fun = find_identifier ("value", o->prog);
      if (fun < 0) Pike_error ("Iterator object lacks value().\n");
      apply_low(o, fun, 0);
      assign_lvalue(Pike_sp-3,Pike_sp-1);
      pop_stack();
    }

    return 1;
  }else{
    pop_stack();
    return 0;
  }

#endif
}


void init_iterators(void)
{
  
#ifdef class_Iterator_defined

#ifdef PROG_ITERATOR_ID
#line 76 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  START_NEW_PROGRAM_ID(ITERATOR);
#else
#line 76 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  start_new_program();

#endif /* PROG_ITERATOR_ID */

#ifndef tObjImpl_ITERATOR

#undef tObjImpl_ITERATOR
#define tObjImpl_ITERATOR tObj

#endif /* tObjImpl_ITERATOR */

#ifdef THIS_ITERATOR

  Iterator_storage_offset=ADD_STORAGE(struct Iterator_struct);

#endif /* THIS_ITERATOR */

#ifdef f_Iterator_create_defined
  f_Iterator_create_fun_num =
#line 91 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("create", NULL, tFunc(tOr(tVoid,tMix),tVoid), ID_STATIC, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_create_defined */

#ifdef f_Iterator_cq__backtick_21_defined
  f_Iterator_cq__backtick_21_fun_num =
#line 101 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`!", NULL, tFunc(tNone,"\10\0\0\0\0\0\0\0\1"), ID_STATIC, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_cq__backtick_21_defined */

#ifdef f_Iterator_cq__backtick_add_defined
  f_Iterator_cq__backtick_add_fun_num =
#line 113 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+", NULL, tFunc("\10\200\0\0\0\177\377\377\377",tName("Iterator", tObjImpl_ITERATOR)), ID_STATIC, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_cq__backtick_add_defined */

#ifdef f_Iterator_cq__backtick_add_eq_defined
  f_Iterator_cq__backtick_add_eq_fun_num =
#line 145 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+=", NULL, tFunc("\10\200\0\0\0\177\377\377\377",tName("Iterator", tObjImpl_ITERATOR)), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_cq__backtick_add_eq_defined */

#ifdef f_Iterator_cq__backtick_2D_defined
  f_Iterator_cq__backtick_2D_fun_num =
#line 156 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`-", NULL, tFunc("\10\200\0\0\0\177\377\377\377","\10\0\0\0\0\0\0\0\1"), ID_STATIC|ID_OPTIONAL, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_cq__backtick_2D_defined */

#ifdef f_Iterator_index_defined
  f_Iterator_index_fun_num =
#line 169 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("index", NULL, tFunc(tNone,tMix), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_index_defined */

#ifdef f_Iterator_value_defined
  f_Iterator_value_fun_num =
#line 178 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("value", NULL, tFunc(tNone,tMix), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_value_defined */

#ifdef f_Iterator_cq__sizeof_defined
  f_Iterator_cq__sizeof_fun_num =
#line 188 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("_sizeof", NULL, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), ID_OPTIONAL, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_cq__sizeof_defined */

#ifdef f_Iterator_cq__random_defined
  f_Iterator_cq__random_fun_num =
#line 200 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("_random", NULL, tFunc(tNone,tVoid), ID_OPTIONAL, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_cq__random_defined */

#ifdef f_Iterator_first_defined
  f_Iterator_first_fun_num =
#line 220 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("first", NULL, tFunc(tNone,"\10\0\0\0\0\0\0\0\1"), ID_OPTIONAL, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_first_defined */

#ifdef f_Iterator_next_defined
  f_Iterator_next_fun_num =
#line 234 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("next", NULL, tFunc(tNone,"\10\0\0\0\0\0\0\0\1"), ID_OPTIONAL, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_next_defined */

#ifdef f_Iterator_set_index_defined
  f_Iterator_set_index_fun_num =
#line 248 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("set_index", NULL, tFunc(tZero,tVoid), ID_OPTIONAL, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Iterator_set_index_defined */
#line 76 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  Iterator_program=end_program();
#line 76 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  Iterator_program_fun_num=add_program_constant("Iterator",Iterator_program,0);

#endif /* class_Iterator_defined */

#ifdef class_mapping_iterator_defined

#ifdef PROG_MAPPING_ITERATOR_ID
#line 268 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  START_NEW_PROGRAM_ID(MAPPING_ITERATOR);
#else
#line 268 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  start_new_program();

#endif /* PROG_MAPPING_ITERATOR_ID */

#ifndef tObjImpl_MAPPING_ITERATOR

#undef tObjImpl_MAPPING_ITERATOR
#define tObjImpl_MAPPING_ITERATOR tObj

#endif /* tObjImpl_MAPPING_ITERATOR */

#ifdef THIS_MAPPING_ITERATOR

  mapping_iterator_storage_offset=ADD_STORAGE(struct mapping_iterator_struct);

#endif /* THIS_MAPPING_ITERATOR */

#ifdef mapping_iterator_event_handler_defined
  pike_set_prog_event_callback(mapping_iterator_event_handler);

#endif /* mapping_iterator_event_handler_defined */

#ifdef f_mapping_iterator_value_defined
  f_mapping_iterator_value_fun_num =
#line 276 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("value", f_mapping_iterator_value, tFunc(tNone,tMix), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_mapping_iterator_value_defined */

#ifdef f_mapping_iterator_index_defined
  f_mapping_iterator_index_fun_num =
#line 286 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("index", f_mapping_iterator_index, tFunc(tNone,tMix), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_mapping_iterator_index_defined */

#ifdef f_mapping_iterator_cq__backtick_add_defined
  f_mapping_iterator_cq__backtick_add_fun_num =
#line 317 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+", f_mapping_iterator_cq__backtick_add, tFunc("\10\0\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_mapping_iterator_cq__backtick_add_defined */

#ifdef f_mapping_iterator_cq__backtick_add_eq_defined
  f_mapping_iterator_cq__backtick_add_eq_fun_num =
#line 334 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+=", f_mapping_iterator_cq__backtick_add_eq, tFunc("\10\0\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_mapping_iterator_cq__backtick_add_eq_defined */

#ifdef f_mapping_iterator_first_defined
  f_mapping_iterator_first_fun_num =
#line 343 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("first", f_mapping_iterator_first, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_mapping_iterator_first_defined */

#ifdef f_mapping_iterator_cq__random_defined
  f_mapping_iterator_cq__random_fun_num =
#line 351 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("_random", f_mapping_iterator_cq__random, tFunc(tNone,tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_mapping_iterator_cq__random_defined */

#ifdef f_mapping_iterator_next_defined
  f_mapping_iterator_next_fun_num =
#line 375 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("next", f_mapping_iterator_next, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_mapping_iterator_next_defined */

#ifdef f_mapping_iterator_cq__backtick_21_defined
  f_mapping_iterator_cq__backtick_21_fun_num =
#line 376 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`!", f_mapping_iterator_cq__backtick_21, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_mapping_iterator_cq__backtick_21_defined */

#ifdef f_mapping_iterator_create_defined
  f_mapping_iterator_create_fun_num =
#line 378 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("create", f_mapping_iterator_create, tFunc(tMapping,tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_mapping_iterator_create_defined */
#line 268 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  mapping_iterator_program=end_program();
#line 268 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  mapping_iterator_program_fun_num=add_program_constant("mapping_iterator",mapping_iterator_program,0);

#endif /* class_mapping_iterator_defined */

#ifdef class_array_iterator_defined

#ifdef PROG_ARRAY_ITERATOR_ID
#line 427 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  START_NEW_PROGRAM_ID(ARRAY_ITERATOR);
#else
#line 427 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  start_new_program();

#endif /* PROG_ARRAY_ITERATOR_ID */

#ifndef tObjImpl_ARRAY_ITERATOR

#undef tObjImpl_ARRAY_ITERATOR
#define tObjImpl_ARRAY_ITERATOR tObj

#endif /* tObjImpl_ARRAY_ITERATOR */

#ifdef THIS_ARRAY_ITERATOR

  array_iterator_storage_offset=ADD_STORAGE(struct array_iterator_struct);

#endif /* THIS_ARRAY_ITERATOR */

#ifdef array_iterator_event_handler_defined
  pike_set_prog_event_callback(array_iterator_event_handler);

#endif /* array_iterator_event_handler_defined */

#ifdef f_array_iterator_value_defined
  f_array_iterator_value_fun_num =
#line 432 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("value", f_array_iterator_value, tFunc(tNone,tMix), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_array_iterator_value_defined */

#ifdef f_array_iterator_index_defined
  f_array_iterator_index_fun_num =
#line 442 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("index", f_array_iterator_index, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_array_iterator_index_defined */

#ifdef f_array_iterator_cq__backtick_add_defined
  f_array_iterator_cq__backtick_add_fun_num =
#line 452 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+", f_array_iterator_cq__backtick_add, tFunc("\10\200\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_array_iterator_cq__backtick_add_defined */

#ifdef f_array_iterator_cq__backtick_add_eq_defined
  f_array_iterator_cq__backtick_add_eq_fun_num =
#line 462 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+=", f_array_iterator_cq__backtick_add_eq, tFunc("\10\200\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_array_iterator_cq__backtick_add_eq_defined */

#ifdef f_array_iterator_cq__backtick_2D_defined
  f_array_iterator_cq__backtick_2D_fun_num =
    ADD_FUNCTION2("`-", f_array_iterator_cq__backtick_2D, tFunc("\10\200\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_array_iterator_cq__backtick_2D_defined */

#ifdef f_array_iterator_first_defined
  f_array_iterator_first_fun_num =
#line 477 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("first", f_array_iterator_first, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_array_iterator_first_defined */

#ifdef f_array_iterator_set_index_defined
  f_array_iterator_set_index_fun_num =
    ADD_FUNCTION2("set_index", f_array_iterator_set_index, tFunc("\10\200\0\0\0\177\377\377\377",tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_array_iterator_set_index_defined */

#ifdef f_array_iterator_cq__random_defined
  f_array_iterator_cq__random_fun_num =
#line 494 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("_random", f_array_iterator_cq__random, tFunc(tNone,tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_array_iterator_cq__random_defined */

#ifdef f_array_iterator_next_defined
  f_array_iterator_next_fun_num =
#line 503 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("next", f_array_iterator_next, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_array_iterator_next_defined */

#ifdef f_array_iterator_cq__backtick_21_defined
  f_array_iterator_cq__backtick_21_fun_num =
    ADD_FUNCTION2("`!", f_array_iterator_cq__backtick_21, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_array_iterator_cq__backtick_21_defined */

#ifdef f_array_iterator_create_defined
  f_array_iterator_create_fun_num =
#line 514 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("create", f_array_iterator_create, tFunc(tArray,tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_array_iterator_create_defined */
#line 427 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  array_iterator_program=end_program();
#line 427 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  array_iterator_program_fun_num=add_program_constant("array_iterator",array_iterator_program,0);

#endif /* class_array_iterator_defined */

#ifdef class_multiset_iterator_defined

#ifdef PROG_MULTISET_ITERATOR_ID
#line 552 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  START_NEW_PROGRAM_ID(MULTISET_ITERATOR);
#else
#line 552 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  start_new_program();

#endif /* PROG_MULTISET_ITERATOR_ID */

#ifndef tObjImpl_MULTISET_ITERATOR

#undef tObjImpl_MULTISET_ITERATOR
#define tObjImpl_MULTISET_ITERATOR tObj

#endif /* tObjImpl_MULTISET_ITERATOR */

#ifdef THIS_MULTISET_ITERATOR

  multiset_iterator_storage_offset=ADD_STORAGE(struct multiset_iterator_struct);

#endif /* THIS_MULTISET_ITERATOR */

#ifdef multiset_iterator_event_handler_defined
  pike_set_prog_event_callback(multiset_iterator_event_handler);

#endif /* multiset_iterator_event_handler_defined */

#ifdef f_multiset_iterator_value_defined
  f_multiset_iterator_value_fun_num =
#line 558 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("value", f_multiset_iterator_value, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_value_defined */

#ifdef f_multiset_iterator_index_defined
  f_multiset_iterator_index_fun_num =
#line 567 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("index", f_multiset_iterator_index, tFunc(tNone,tMix), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_index_defined */

#ifdef f_multiset_iterator_cq__backtick_add_eq_defined
  f_multiset_iterator_cq__backtick_add_eq_fun_num =
#line 616 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+=", f_multiset_iterator_cq__backtick_add_eq, tFunc("\10\200\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_cq__backtick_add_eq_defined */

#ifdef f_multiset_iterator_cq__backtick_add_defined
  f_multiset_iterator_cq__backtick_add_fun_num =
#line 623 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+", f_multiset_iterator_cq__backtick_add, tFunc("\10\200\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_cq__backtick_add_defined */

#ifdef f_multiset_iterator_cq__backtick_2D_defined
  f_multiset_iterator_cq__backtick_2D_fun_num =
#line 632 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`-", f_multiset_iterator_cq__backtick_2D, tFunc("\10\200\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_cq__backtick_2D_defined */

#ifdef f_multiset_iterator_first_defined
  f_multiset_iterator_first_fun_num =
#line 641 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("first", f_multiset_iterator_first, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_first_defined */

#ifdef f_multiset_iterator_next_defined
  f_multiset_iterator_next_fun_num =
#line 649 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("next", f_multiset_iterator_next, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_next_defined */

#ifdef f_multiset_iterator_cq__backtick_21_defined
  f_multiset_iterator_cq__backtick_21_fun_num =
#line 660 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`!", f_multiset_iterator_cq__backtick_21, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_cq__backtick_21_defined */

#ifdef f_multiset_iterator_cq__random_defined
  f_multiset_iterator_cq__random_fun_num =
#line 668 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("_random", f_multiset_iterator_cq__random, tFunc(tNone,tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_cq__random_defined */

#ifdef f_multiset_iterator_lock_index_defined
  f_multiset_iterator_lock_index_fun_num =
#line 681 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("lock_index", f_multiset_iterator_lock_index, tFunc(tNone,tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_lock_index_defined */

#ifdef f_multiset_iterator_unlock_index_defined
  f_multiset_iterator_unlock_index_fun_num =
#line 691 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("unlock_index", f_multiset_iterator_unlock_index, tFunc(tNone,tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_unlock_index_defined */

#ifdef f_multiset_iterator_create_defined
  f_multiset_iterator_create_fun_num =
#line 709 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("create", f_multiset_iterator_create, tFunc(tMultiset,tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_multiset_iterator_create_defined */
#line 552 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  multiset_iterator_program=end_program();
#line 552 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  multiset_iterator_program_fun_num=add_program_constant("multiset_iterator",multiset_iterator_program,0);

#endif /* class_multiset_iterator_defined */

#ifdef class_string_iterator_defined

#ifdef PROG_STRING_ITERATOR_ID
#line 755 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  START_NEW_PROGRAM_ID(STRING_ITERATOR);
#else
#line 755 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  start_new_program();

#endif /* PROG_STRING_ITERATOR_ID */

#ifndef tObjImpl_STRING_ITERATOR

#undef tObjImpl_STRING_ITERATOR
#define tObjImpl_STRING_ITERATOR tObj

#endif /* tObjImpl_STRING_ITERATOR */

#ifdef THIS_STRING_ITERATOR

  string_iterator_storage_offset=ADD_STORAGE(struct string_iterator_struct);

#endif /* THIS_STRING_ITERATOR */

#ifdef string_iterator_event_handler_defined
  pike_set_prog_event_callback(string_iterator_event_handler);

#endif /* string_iterator_event_handler_defined */

#ifdef f_string_iterator_value_defined
  f_string_iterator_value_fun_num =
#line 760 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("value", f_string_iterator_value, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_value_defined */

#ifdef f_string_iterator_index_defined
  f_string_iterator_index_fun_num =
#line 770 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("index", f_string_iterator_index, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_index_defined */

#ifdef f_string_iterator_cq__backtick_add_defined
  f_string_iterator_cq__backtick_add_fun_num =
#line 780 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+", f_string_iterator_cq__backtick_add, tFunc("\10\200\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_cq__backtick_add_defined */

#ifdef f_string_iterator_cq__backtick_add_eq_defined
  f_string_iterator_cq__backtick_add_eq_fun_num =
#line 789 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+=", f_string_iterator_cq__backtick_add_eq, tFunc("\10\200\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_cq__backtick_add_eq_defined */

#ifdef f_string_iterator_cq__backtick_2D_defined
  f_string_iterator_cq__backtick_2D_fun_num =
    ADD_FUNCTION2("`-", f_string_iterator_cq__backtick_2D, tFunc("\10\200\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_cq__backtick_2D_defined */

#ifdef f_string_iterator_first_defined
  f_string_iterator_first_fun_num =
#line 804 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("first", f_string_iterator_first, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_first_defined */

#ifdef f_string_iterator_set_index_defined
  f_string_iterator_set_index_fun_num =
    ADD_FUNCTION2("set_index", f_string_iterator_set_index, tFunc("\10\200\0\0\0\177\377\377\377",tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_set_index_defined */

#ifdef f_string_iterator_cq__random_defined
  f_string_iterator_cq__random_fun_num =
#line 819 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("_random", f_string_iterator_cq__random, tFunc(tNone,tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_cq__random_defined */

#ifdef f_string_iterator_next_defined
  f_string_iterator_next_fun_num =
#line 828 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("next", f_string_iterator_next, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_next_defined */

#ifdef f_string_iterator_cq__backtick_21_defined
  f_string_iterator_cq__backtick_21_fun_num =
    ADD_FUNCTION2("`!", f_string_iterator_cq__backtick_21, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_cq__backtick_21_defined */

#ifdef f_string_iterator_cq__search_defined
  f_string_iterator_cq__search_fun_num =
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("_search", f_string_iterator_cq__search, tFunc(tOr(tString,"\10\200\0\0\0\177\377\377\377") tOr("\10\200\0\0\0\177\377\377\377",tVoid),"\10\200\0\0\0\177\377\377\377"), ID_STATIC, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_cq__search_defined */

#ifdef f_string_iterator_create_defined
  f_string_iterator_create_fun_num =
#line 860 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("create", f_string_iterator_create, tFunc(tString,tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_iterator_create_defined */
#line 755 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  string_iterator_program=end_program();
#line 755 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  string_iterator_program_fun_num=add_program_constant("string_iterator",string_iterator_program,0);

#endif /* class_string_iterator_defined */

#ifdef class_file_line_iterator_defined

#ifdef PROG_FILE_LINE_ITERATOR_ID
#line 888 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  START_NEW_PROGRAM_ID(FILE_LINE_ITERATOR);
#else
#line 888 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  start_new_program();

#endif /* PROG_FILE_LINE_ITERATOR_ID */

#ifndef tObjImpl_FILE_LINE_ITERATOR

#undef tObjImpl_FILE_LINE_ITERATOR
#define tObjImpl_FILE_LINE_ITERATOR tObj

#endif /* tObjImpl_FILE_LINE_ITERATOR */

#ifdef THIS_FILE_LINE_ITERATOR

  file_line_iterator_storage_offset=ADD_STORAGE(struct file_line_iterator_struct);

#endif /* THIS_FILE_LINE_ITERATOR */

#ifdef file_line_iterator_event_handler_defined
  pike_set_prog_event_callback(file_line_iterator_event_handler);

#endif /* file_line_iterator_event_handler_defined */

#ifdef f_file_line_iterator_value_defined
  f_file_line_iterator_value_fun_num =
#line 963 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("value", f_file_line_iterator_value, tFunc(tNone,tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_file_line_iterator_value_defined */

#ifdef f_file_line_iterator_index_defined
  f_file_line_iterator_index_fun_num =
#line 972 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("index", f_file_line_iterator_index, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_file_line_iterator_index_defined */

#ifdef f_file_line_iterator_cq__backtick_add_defined
  f_file_line_iterator_cq__backtick_add_fun_num =
#line 981 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+", f_file_line_iterator_cq__backtick_add, tFunc("\10\0\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_file_line_iterator_cq__backtick_add_defined */

#ifdef f_file_line_iterator_cq__backtick_add_eq_defined
  f_file_line_iterator_cq__backtick_add_eq_fun_num =
#line 1001 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+=", f_file_line_iterator_cq__backtick_add_eq, tFunc("\10\0\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_file_line_iterator_cq__backtick_add_eq_defined */

#ifdef f_file_line_iterator_next_defined
  f_file_line_iterator_next_fun_num =
#line 1011 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("next", f_file_line_iterator_next, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_file_line_iterator_next_defined */

#ifdef f_file_line_iterator_cq__backtick_21_defined
  f_file_line_iterator_cq__backtick_21_fun_num =
    ADD_FUNCTION2("`!", f_file_line_iterator_cq__backtick_21, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_file_line_iterator_cq__backtick_21_defined */

#ifdef f_file_line_iterator_create_defined
  f_file_line_iterator_create_fun_num =
#line 1022 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("create", f_file_line_iterator_create, tFunc(tOr(tFunc(tNone,tString),tVoid),tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_file_line_iterator_create_defined */
#line 888 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  file_line_iterator_program=end_program();
#line 888 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  file_line_iterator_program_fun_num=add_program_constant("file_line_iterator",file_line_iterator_program,0);

#endif /* class_file_line_iterator_defined */

#ifdef class_string_split_iterator_defined

#ifdef PROG_STRING_SPLIT_ITERATOR_ID
#line 1089 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  START_NEW_PROGRAM_ID(STRING_SPLIT_ITERATOR);
#else
#line 1089 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  start_new_program();

#endif /* PROG_STRING_SPLIT_ITERATOR_ID */

#ifndef tObjImpl_STRING_SPLIT_ITERATOR

#undef tObjImpl_STRING_SPLIT_ITERATOR
#define tObjImpl_STRING_SPLIT_ITERATOR tObj

#endif /* tObjImpl_STRING_SPLIT_ITERATOR */

#ifdef THIS_STRING_SPLIT_ITERATOR

  string_split_iterator_storage_offset=ADD_STORAGE(struct string_split_iterator_struct);

#endif /* THIS_STRING_SPLIT_ITERATOR */

#ifdef string_split_iterator_event_handler_defined
  pike_set_prog_event_callback(string_split_iterator_event_handler);

#endif /* string_split_iterator_event_handler_defined */

#ifdef string_split_iterator_optimize_callback_defined
  pike_set_prog_optimize_callback(optimize_string_split_iterator_struct);

#endif /* string_split_iterator_optimize_callback_defined */

#ifdef f_string_split_iterator_value_defined
  f_string_split_iterator_value_fun_num =
#line 1337 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("value", f_string_split_iterator_value, tFunc(tNone,tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_split_iterator_value_defined */

#ifdef f_string_split_iterator_index_defined
  f_string_split_iterator_index_fun_num =
#line 1346 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("index", f_string_split_iterator_index, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_split_iterator_index_defined */

#ifdef f_string_split_iterator_cq__backtick_add_defined
  f_string_split_iterator_cq__backtick_add_fun_num =
#line 1355 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+", f_string_split_iterator_cq__backtick_add, tFunc("\10\0\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_split_iterator_cq__backtick_add_defined */

#ifdef f_string_split_iterator_cq__backtick_add_eq_defined
  f_string_split_iterator_cq__backtick_add_eq_fun_num =
#line 1377 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("`+=", f_string_split_iterator_cq__backtick_add_eq, tFunc("\10\0\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_split_iterator_cq__backtick_add_eq_defined */

#ifdef f_string_split_iterator_next_defined
  f_string_split_iterator_next_fun_num =
#line 1389 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("next", f_string_split_iterator_next, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_split_iterator_next_defined */

#ifdef f_string_split_iterator_cq__backtick_21_defined
  f_string_split_iterator_cq__backtick_21_fun_num =
    ADD_FUNCTION2("`!", f_string_split_iterator_cq__backtick_21, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_split_iterator_cq__backtick_21_defined */

#ifdef f_string_split_iterator_cq__sizeof_defined
  f_string_split_iterator_cq__sizeof_fun_num =
#line 1400 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("_sizeof", f_string_split_iterator_cq__sizeof, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_split_iterator_cq__sizeof_defined */

#ifdef f_string_split_iterator_create_defined
  f_string_split_iterator_create_fun_num =
#line 1496 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    ADD_FUNCTION2("create", f_string_split_iterator_create, tFunc(tString tOr3("\10\200\0\0\0\177\377\377\377",tArr("\10\200\0\0\0\177\377\377\377"),tSet("\10\200\0\0\0\177\377\377\377")) tOr("\10\200\0\0\0\177\377\377\377",tVoid) tOr(tFunc(tNone,tString),tVoid),tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_string_split_iterator_create_defined */
#line 1089 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  string_split_iterator_program=end_program();
#line 1089 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  string_split_iterator_program_fun_num=add_program_constant("string_split_iterator",string_split_iterator_program,0);

#endif /* class_string_split_iterator_defined */

#ifdef f_get_iterator_defined
#line 1777 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
  ADD_EFUN("get_iterator", f_get_iterator, tFunc(tOr5(tObj,tArray,tMapping,tMultiset,tString),tName("Iterator", tObjImpl_ITERATOR)), 0);

#endif /* f_get_iterator_defined */
#line 2084 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
;
  add_global_program ("Iterator", Iterator_program);
}

void exit_iterators(void)
{
  
#ifdef class_Iterator_defined
  if(Iterator_program) {
#line 76 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    free_program(Iterator_program);
    Iterator_program=0;
  }

#endif /* class_Iterator_defined */

#ifdef class_mapping_iterator_defined
  if(mapping_iterator_program) {
#line 268 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    free_program(mapping_iterator_program);
    mapping_iterator_program=0;
  }

#endif /* class_mapping_iterator_defined */

#ifdef class_array_iterator_defined
  if(array_iterator_program) {
#line 427 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    free_program(array_iterator_program);
    array_iterator_program=0;
  }

#endif /* class_array_iterator_defined */

#ifdef class_multiset_iterator_defined
  if(multiset_iterator_program) {
#line 552 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    free_program(multiset_iterator_program);
    multiset_iterator_program=0;
  }

#endif /* class_multiset_iterator_defined */

#ifdef class_string_iterator_defined
  if(string_iterator_program) {
#line 755 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    free_program(string_iterator_program);
    string_iterator_program=0;
  }

#endif /* class_string_iterator_defined */

#ifdef class_file_line_iterator_defined
  if(file_line_iterator_program) {
#line 888 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    free_program(file_line_iterator_program);
    file_line_iterator_program=0;
  }

#endif /* class_file_line_iterator_defined */

#ifdef class_string_split_iterator_defined
  if(string_split_iterator_program) {
#line 1089 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
    free_program(string_split_iterator_program);
    string_split_iterator_program=0;
  }

#endif /* class_string_split_iterator_defined */
#line 2091 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/iterators.cmod"
}

