2 Copyright (C) 2001-2009, Parrot Foundation.
7 src/pmc/orderedhashiterator.pmc
11 Implementation of Iterator for OrderedHash.
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.
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;
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);
63 Marks the hash as live.
70 PMC * const hash = PARROT_ORDEREDHASHITERATOR(SELF)->pmc_hash;
71 Parrot_gc_mark_PMC_alive(INTERP, hash);
87 =item C<void set_integer_native()>
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);
99 case ITERATE_FROM_START:
100 case ITERATE_FROM_START_KEYS:
103 attrs->next_entry = PARROT_ORDEREDHASH(attrs->pmc_hash)->first;
105 case ITERATE_FROM_END:
106 attrs->pos = attrs->elements;
108 attrs->next_entry = PARROT_ORDEREDHASH(attrs->pmc_hash)->last;
111 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
112 "HashIterator: unknown iterator type");
118 =item C<PMC *get_pmc()>
120 Returns this Iterator's Hash.
125 VTABLE PMC* get_pmc() {
126 return PARROT_ORDEREDHASHITERATOR(SELF)->pmc_hash;
131 =item C<INTVAL get_bool()>
133 Returns true if there is more elements to iterate over.
139 VTABLE INTVAL get_bool() {
140 return STATICSELF.elements() > 0;
145 =item C<INTVAL elements()>
147 Returns the number of remaining elements in the Hash.
153 VTABLE INTVAL elements() {
154 return PARROT_ORDEREDHASHITERATOR(SELF)->elements;
157 VTABLE INTVAL get_integer() {
158 return SELF.elements();
163 =item C<PMC *shift_pmc()>
165 Returns the HashIteratorKey for the current position and advance
172 VTABLE PMC *shift_pmc() {
173 Parrot_OrderedHashIterator_attributes * const attrs =
174 PARROT_ORDEREDHASHITERATOR(SELF);
178 if (!attrs->elements)
179 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
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);
195 =item C<PMC *pop_pmc()>
197 Returns the HashIteratorKey for the current position and advance
198 the next one for reverse iterator.
204 VTABLE PMC *pop_pmc() {
205 Parrot_OrderedHashIterator_attributes * const attrs =
206 PARROT_ORDEREDHASHITERATOR(SELF);
210 if (!attrs->elements)
211 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
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);
228 VTABLE STRING* shift_string() {
229 PMC * const key = SELF.shift_pmc();
230 return VTABLE_get_string(INTERP, key);
244 * c-file-style: "parrot"
246 * vim: expandtab shiftwidth=4: