fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / pmc / orderedhashiterator.pmc
blob5cec03c94052ececb7280b777f1c5e77f18bf8fb
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/orderedhashiterator.pmc
9 =head1 DESCRIPTION
11 Implementation of Iterator for OrderedHash.
13 =head1 METHODS
15 =over 4
17 =cut
21 #include "pmc/pmc_orderedhash.h"
22 #include "pmc/pmc_hashiteratorkey.h"
24 /* HEADERIZER HFILE: none */
25 /* HEADERIZER BEGIN: static */
26 /* HEADERIZER END: static */
28 pmclass OrderedHashIterator extends Iterator no_ro auto_attrs {
29     ATTR PMC        *pmc_hash;      /* the Hash which this Iterator iterates */
30     ATTR PMC        *next_entry;    /* Next entry to shift/pop */
31     ATTR INTVAL      pos;           /* */
32     ATTR INTVAL      elements;      /* How many elements left to iterate over */
33     ATTR INTVAL      reverse;       /* Direction of iteration. 1 - for reverse iteration */
37 =item C<void init_pmc(PMC *initializer)>
39 Initializes the iterator with an aggregate PMC.
40 Defaults iteration mode to iterate from start.
42 =cut
46     VTABLE void init_pmc(PMC *hash) {
47         Parrot_OrderedHashIterator_attributes * const attrs =
48            (Parrot_OrderedHashIterator_attributes *) PMC_data(SELF);
50         attrs->pmc_hash         = hash;
51         attrs->pos              = 0;
52         attrs->elements         = VTABLE_elements(INTERP, hash);
53         attrs->next_entry       = PARROT_ORDEREDHASH(hash)->first;
54         PMC_data(SELF)          = attrs;
56         PObj_custom_mark_SET(SELF);
57     }
61 =item C<void mark()>
63 Marks the hash as live.
65 =cut
69     VTABLE void mark() {
70         PMC * const hash = PARROT_ORDEREDHASHITERATOR(SELF)->pmc_hash;
71         Parrot_gc_mark_PMC_alive(INTERP, hash);
72     }
76 =item C<PMC *clone()>
78 =cut
81     VTABLE PMC* clone() {
82         return PMCNULL;
83     }
87 =item C<void set_integer_native()>
89 =cut
92     VTABLE void set_integer_native(INTVAL value) {
93         Parrot_OrderedHashIterator_attributes * const attrs =
94                 PARROT_ORDEREDHASHITERATOR(SELF);
96         /* Restart iterator */
97         attrs->elements = VTABLE_elements(INTERP, attrs->pmc_hash);
98         switch (value) {
99           case ITERATE_FROM_START:
100           case ITERATE_FROM_START_KEYS:
101             attrs->pos          = 0;
102             attrs->reverse      = 0;
103             attrs->next_entry   = PARROT_ORDEREDHASH(attrs->pmc_hash)->first;
104             break;
105           case ITERATE_FROM_END:
106             attrs->pos          = attrs->elements;
107             attrs->reverse      = 1;
108             attrs->next_entry   = PARROT_ORDEREDHASH(attrs->pmc_hash)->last;
109             break;
110           default:
111             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
112                     "HashIterator: unknown iterator type");
113         }
114     };
118 =item C<PMC *get_pmc()>
120 Returns this Iterator's Hash.
122 =cut
125     VTABLE PMC* get_pmc() {
126         return PARROT_ORDEREDHASHITERATOR(SELF)->pmc_hash;
127     }
131 =item C<INTVAL get_bool()>
133 Returns true if there is more elements to iterate over.
135 =cut
139     VTABLE INTVAL get_bool() {
140         return STATICSELF.elements() > 0;
141     }
145 =item C<INTVAL elements()>
147 Returns the number of remaining elements in the Hash.
149 =cut
153     VTABLE INTVAL elements() {
154         return PARROT_ORDEREDHASHITERATOR(SELF)->elements;
155     }
157     VTABLE INTVAL get_integer() {
158         return SELF.elements();
159     }
163 =item C<PMC *shift_pmc()>
165 Returns the HashIteratorKey for the current position and advance
166 the next one.
168 =cut
172     VTABLE PMC *shift_pmc() {
173         Parrot_OrderedHashIterator_attributes * const attrs =
174                 PARROT_ORDEREDHASHITERATOR(SELF);
176         PMC        *ret;
178         if (!attrs->elements)
179             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
180                 "StopIteration");
182         /* Get bucket and move to next bucket */
183         ret               = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
184                 ORDERED_HASH_ITEM_KEY);
185         attrs->next_entry = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
186                 ORDERED_HASH_ITEM_NEXT);
187         ++attrs->pos;
188         --attrs->elements;
190         return ret;
191     }
195 =item C<PMC *pop_pmc()>
197 Returns the HashIteratorKey for the current position and advance
198 the next one for reverse iterator.
200 =cut
204     VTABLE PMC *pop_pmc() {
205         Parrot_OrderedHashIterator_attributes * const attrs =
206                 PARROT_ORDEREDHASHITERATOR(SELF);
208         PMC        *ret;
210         if (!attrs->elements)
211             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
212                 "StopIteration");
214         ret               = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
215                 ORDERED_HASH_ITEM_KEY);
216         attrs->next_entry = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
217                 ORDERED_HASH_ITEM_PREV);
218         --attrs->pos;
219         --attrs->elements;
221         return ret;
222     }
228     VTABLE STRING* shift_string() {
229         PMC * const key = SELF.shift_pmc();
230         return VTABLE_get_string(INTERP, key);
231     }
236 =back
238 =cut
243  * Local variables:
244  *   c-file-style: "parrot"
245  * End:
246  * vim: expandtab shiftwidth=4:
247  */