void exampleArrayList() { ArrayList* l = newArrayList(4); alist_add(l, "Aye"); alist_add(l, "Bee"); alist_add(l, "Sea"); alist_add(l, "Dee"); alist_add(l, "Eee"); alist_add(l, "Eff"); alist_add(l, "Gee"); alist_add(l, "Ach"); alist_add(l, "Eye"); alist_add(l, "Jay"); alist_add(l, "Kay"); alist_add(l, "Ell"); printf("Size: %d\n", l->size); alist_traverseForward(l, &process); printf("\n"); printf("Remove 'Sea'\n"); alist_remove(l, "Sea", equals); alist_traverseForward(l, &process); printf("\n"); printf("Remove at 0\n"); alist_removeAt(l, 0); alist_traverseForward(l, &process); printf("\n"); printf("Remove at size\n"); alist_removeAt(l, l->size - 1); alist_traverseForward(l, &process); printf("\n"); printf("Insert 'Aye' at 0\n"); alist_insert(l, "Aye", 0); alist_traverseForward(l, &process); printf("\n"); printf("Insert 'Ell' at size\n"); alist_insert(l, "Ell", l->size); alist_traverseForward(l, &process); printf("\n"); printf("Insert 'Sea' at 3\n"); alist_insert(l, "Sea", 2); alist_traverseForward(l, &process); printf("\n"); printf("0: '%s'\n", (char*)alist_get(l, 0)); printf("3: '%s'\n", (char*)alist_get(l, 3)); alist_free(l); }
/** * \brief Merge two association lists together. * * Add all data elements from an association list to another association * list, replacing the value of all existing elements with the same key. * * \note * This function is \f$ O(n \cdot m) \f$ with \f$ n \f$ the length of * \p base and \f$ m \f$ the length of \p rest. * * \param base The association list to insert the data in. * \param rest The association list to be merged into \p base. * \param eq The equals predicate for two keys. * \param free_key The function used to free the \p rest list's key data, * or \c NULL if the data does not need to be freed. * \param free_value The function used to free the \p base value's data if it * needs to be replaced, or \c NULL if the data does not * need to be freed. * * \return The \p base alist, merged with \p rest, or NULL in case of error. * If an error occurred, the \p base list is still valid, but * it is undefined which items from the \p rest list will have been * merged into the list and which haven't. The \p rest list will * not be valid after the function has finished. * * \par Errno values: * - \b ENOMEM if out of memory. * * \sa alist_insert alist_delete alist_merge_uniq */ alist alist_merge(alist base, alist rest, eq_func eq, free_func free_key, free_func free_value) { sll l; alist_entry e; assert(base != NULL); assert(rest != NULL); l = rest->list; while (!sll_empty(l)) { e = sll_get_data(l).ptr; base = alist_insert(base, e->key, e->value, eq, free_key, free_value); /* * HACK: We are cheating here, since we're assuming the alist * implementation is a pointer to a container struct for the * list itself. If this implementation would ever change, this * function would simple not work. (Imagine an error happening * in sll_append in the middle of appending. What should be * returned? Not NULL, since we have memory leakage then) */ if (base == NULL) return NULL; l = sll_remove_head(l, free); } free(rest); return base; }
void frame_setson_ext(framestruc *fr, framestruc *parent, framestruc *where) { framestruc *pold, **rr; if (!fr) return; pold = FRPARENT(fr); if (pold) { /* removing from the son-list of its old parent */ if (!FRSONS(pold)) rr = NULL; else for (rr=FRSONS(pold); *rr && *rr!=fr; rr++) ; if (rr?(*rr==fr):0) { alist_delete(rr); FRNUMSONS(pold)--; } else {PROGERROR("Probably broken list of sons (%p) in the parent %p.",fr,pold);} } FRPARENT(fr) = parent; if (parent) { /* the new parent */ if (!where) { FRSONS_XD(parent) = alist_append(FRSONS(parent),fr); } else { if (!FRSONS(parent)) rr = NULL; else for (rr=FRSONS(parent); *rr && *rr!=where; rr++) ; if (rr?(*rr!=where):1) {PROGERROR("Nonexistent \"where\" position given.");} FRSONS_XD(parent) = alist_insert(FRSONS(parent),rr,fr); } FRNUMSONS(parent)++; } }
/* * Append a value to a list. These are convenience wrappers on top * of the insert operation. See the description of those routine above * for details. */ void * alist_append(Alist **lpp, const void *datap, size_t size, Aliste init_arritems) { Aliste ndx = ((*lpp) == NULL) ? 0 : (*lpp)->al_nitems; return (alist_insert(lpp, datap, size, init_arritems, ndx)); }
void * alist_insert_by_offset(Alist **lpp, const void *datap, size_t size, Aliste init_arritems, Aliste off) { Aliste idx; if (*lpp == NULL) { ASSERT(off == ALIST_OFF_DATA); idx = 0; } else { idx = (off - ALIST_OFF_DATA) / (*lpp)->al_size; } return (alist_insert(lpp, datap, size, init_arritems, idx)); }
Enemy *create_enemy_p(EnemyList *enemies, complex pos, float hp, EnemyVisualRule visual_rule, EnemyLogicRule logic_rule, complex a1, complex a2, complex a3, complex a4) { if(IN_DRAW_CODE) { log_fatal("Tried to spawn an enemy while in drawing code"); } // FIXME: some code relies on the insertion logic (which?) Enemy *e = alist_insert(enemies, enemies->first, (Enemy*)objpool_acquire(stage_object_pools.enemies)); // Enemy *e = alist_append(enemies, (Enemy*)objpool_acquire(stage_object_pools.enemies)); e->moving = false; e->dir = 0; e->birthtime = global.frames; e->pos = pos; e->pos0 = pos; e->pos0_visual = pos; e->spawn_hp = hp; e->hp = hp; e->alpha = 1.0; e->logic_rule = logic_rule; e->visual_rule = visual_rule; e->args[0] = a1; e->args[1] = a2; e->args[2] = a3; e->args[3] = a4; e->ent.draw_layer = LAYER_ENEMY; e->ent.draw_func = ent_draw_enemy; e->ent.damage_func = ent_damage_enemy; fix_pos0_visual(e); ent_register(&e->ent, ENT_ENEMY); e->logic_rule(e, EVENT_BIRTH); return e; }
int main(void) { alist al; char *t1 = "def", *t2 = "abc", *t3 = "xyz"; char *s; al = alist_new(); assert(alist_count(al) == 0); assert(alist_current(al) == NULL); assert(alist_current_idx(al) == -1); alist_append(al, t1); assert(alist_count(al) == 1); assert(alist_current(al) == t1); assert(alist_current_idx(al) == 0); alist_append(al, t2); assert(alist_count(al) == 2); assert(alist_current(al) == t2); assert(alist_current_idx(al) == 1); s = alist_first(al); assert(s == t1); assert(alist_current(al) == t1); assert(alist_current_idx(al) == 0); s = alist_next(al); assert(s == t2); assert(alist_current(al) == t2); assert(alist_current_idx(al) == 1); s = alist_next(al); assert(s == NULL); assert(alist_current(al) == NULL); assert(alist_current_idx(al) == -1); alist_prepend(al, t3); assert(alist_count(al) == 3); assert(alist_current(al) == t3); assert(alist_current_idx(al) == 0); printf("elements:\n"); for (s = alist_first(al); s != NULL; s = alist_next(al)) printf("element %d: %s\n", alist_current_idx(al), s); alist_sort(al, sorter); printf("sorted elements:\n"); for (s = alist_first(al); s != NULL; s = alist_next(al)) printf("element %d: %s\n", alist_current_idx(al), s) ; assert(alist_at(al, 0) == t2); assert(alist_at(al, 1) == t1); assert(alist_at(al, 2) == t3); alist_clear(al); assert(alist_count(al) == 0); assert(alist_current(al) == NULL); assert(alist_current_idx(al) == -1); alist_insert(al, 5, t1); assert(alist_count(al) == 1); assert(alist_current(al) == t1); assert(alist_current_idx(al) == 0); alist_insert(al, 0, t2); assert(alist_count(al) == 2); assert(alist_current(al) == t2); assert(alist_current_idx(al) == 0); alist_insert(al, 1, t3); assert(alist_count(al) == 3); assert(alist_at(al, 0) == t2); assert(alist_at(al, 1) == t3); assert(alist_at(al, 2) == t1); assert(alist_current(al) == t3); assert(alist_current_idx(al) == 1); alist_delete(al); printf("alist test successful.\n"); return 0; }