/*
Copyright (C) 2001-2008, The Perl Foundation.
$Id: /mirror/trunk/src/pmc/enumerate.pmc 29983 2008-08-02T22:45:13.271765Z allison  $

=head1 NAME

src/pmc/enumerate.pmc - enumerate PMC

=head1 DESCRIPTION

This is an Iterator which returns [idx, item] tuples.

=head2 Methods

=over 4

=cut

*/

#include "parrot/parrot.h"

pmclass Enumerate extends Iterator no_ro {

    VTABLE void init_pmc(PMC *iterable) {
        SUPER(iterable);
        PMC_struct_val(SELF) = key_new_integer(INTERP, 0);
        PMC_pmc_val(SELF)    = VTABLE_get_iter(INTERP, iterable);
    }

/*

=item C<PMC *shift_pmc()>

Returns [idx, element] for the current idx/key and sets the idx/key to
the next one.

=cut

*/

    VTABLE INTVAL get_bool() {
        PMC   *key  = (PMC *)PMC_struct_val(SELF);
        PMC   *iter = PMC_pmc_val(SELF);
        INTVAL ok   = PMC_int_val(key) >= 0 && VTABLE_get_bool(INTERP, iter);

        if (!ok)
            PMC_int_val(key) = -1;

        return ok;
    }

    VTABLE PMC *shift_pmc() {
        PMC *item, *tupl, *val;
        PMC *key  = (PMC *)PMC_struct_val(SELF);
        PMC *iter = PMC_pmc_val(SELF);
        INTVAL i  = PMC_int_val(key);

        if (i == -1)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
                "StopIteration");

        item = VTABLE_shift_pmc(INTERP, iter);
        tupl = pmc_new(INTERP, enum_class_FixedPMCArray);

        ++PMC_int_val(key);
        VTABLE_set_integer_native(INTERP, tupl, 2);

        val              = pmc_new(INTERP, enum_class_Integer);
        PMC_int_val(val) = i;

        VTABLE_set_pmc_keyed_int(INTERP, tupl, 0, val);
        VTABLE_set_pmc_keyed_int(INTERP, tupl, 1, item);

        return tupl;
    }

    VTABLE PMC *get_iter() {
        return SELF;
    }

}

/*

=back

=cut

*/


/*
 * Local variables:
 *   c-file-style: "parrot"
 * End:
 * vim: expandtab shiftwidth=4:
 */
