IDList.xcc
Benoit Dupont de Dinechin (Benoit.Dupont-de-Dinechin@st.com)
Copyright 2007 STMicroelectronics. Copyright 1995 - 1998 Commissariat a l'Energie Atomique.
This program is free software; you can redistribute it and/or modify it under the terms of either (at your option): the GNU General Public License (GPL) version 2; the GNU Lesser General Public License (LGPL) version 2.1; any later version of these licences as published by the Free Software Foundation.
An Inline Double List is a double-linked list, meaning that there is a prev and a next pointer per list item, and these pointers are stored next to the item. Precisely, the pointers are in a List_Item_ object that is inlined below the item. List pointers point to items, not to the List_Item_ objects.
IDListItem— Pseudo type for IDList items.
typedef void *IDListItem; typedef const void *const_IDListItem; typedef void (*IDListItemRelease)(IDListItem); typedef int (*IDListItemCompare)(const_IDListItem, const_IDListItem);
IDListItem_CELL— Access to the IDListItemCell under this
item.
#define IDListItem_CELL(this) ((IDListItemCell)(this) - 1)
IDListItem_NEXT— Access to the next item in the IDList.
#define IDListItem_NEXT(this) IDListItemCell_NEXT(IDListItem_CELL(this))
IDListItem_PREV— Access to the previous item in the IDList.
#define IDListItem_PREV(this) IDListItemCell_PREV(IDListItem_CELL(this))
IDListItemCell— List item cell inlined below the IDListItem(s).
IDListItemCell is exported for use in IDList_FOREACH.
struct IDListItemCell_ { //@args size_t itemSize IDListItem NEXT; // The next IDListItem. IDListItem PREV; // The previous IDListItem. //@access ITEM ((IDListItem)((IDListItemCell)(this) + 1)) };
IDList_empty— Empty this IDList.
void IDList_empty(IDList this, IDListItemRelease release);
IDList_memory— This IDList memory.
static inline Memory IDList_memory(const_IDList this) { return IDList_MEMORY(this); }
IDList_isEmpty -- True iff this IDList is empty. IDList_isSingle -- True iff this IDList has a single entry.
#define IDList_isEmpty(this) (IDList_count(this) == 0) #define IDList_isSingle(this) (IDList_count(this) == 1)
IDList_count— Count items in the IDList.
- Return
- The count of items in the IDList.
static inline int32_t IDList_count(const_IDList this) { return IDList_COUNT(this); }
IDList_firstItem— First item of the IDList.
- Return
- Pointer to the firstItem.
static inline IDListItem IDList_firstItem(const_IDList this) { return IDList_FIRSTITEM(this); }
IDList_BOT— Dereference bottom (firstItem) item of this IDList.
#define IDList_BOT(this, Type) *(Type *)IDList_firstItem(this)
IDList_lastItem— Last item of the IDList.
- Return
- Pointer to the lastItem.
static inline IDListItem IDList_lastItem(const_IDList this) { return IDList_LASTITEM(this); }
IDList_TOP— Dereference top (lastItem) item of this IDList.
#define IDList_TOP(this, Type) *(Type *)IDList_lastItem(this)
IDList_FOREACH— Iterate from firstItem to lastItem IDList item.
Exiting IDList_FOREACH with break
or return
is allowed.
Type
- Type of the inlined items.
iter
- Type* pointer set to each item.
#define IDList_FOREACH(this, Type, iter) { \ IDListItem IDList_NEXT = NULL; \ Type *(iter) = (Type *)IDList_firstItem(this); \ for (; iter != NULL; iter = IDList_NEXT) { \ IDListItemCell IDList_ITER = IDListItem_CELL(iter); \ IDList_FOREACH_SYNC; #define IDList_FOREACH_SYNC \ IDList_NEXT = IDListItemCell_NEXT(IDList_ITER) #define IDList_ENDEACH \ } \ }
IDList_FORBACK— Iterate from lastItem to firstItem IDList item.
Exiting IDList_FORBACK with break
or return
is allowed.
Type
- Type of the inlined items.
iter
- Type* pointer set to each item.
#define IDList_FORBACK(this, Type, iter) { \ IDListItem IDList_PREV = NULL; \ Type *(iter) = (Type *)IDList_lastItem(this); \ for (; iter != NULL; iter = IDList_PREV) { \ IDListItemCell IDList_ITER = IDListItem_CELL(iter); \ IDList_FORBACK_SYNC; #define IDList_FORBACK_SYNC \ IDList_PREV = IDListItemCell_PREV(IDList_ITER) #define IDList_ENDBACK \ } \ }
IDList_makeItem— Make a new IDListItem.
static inline IDListItem IDList_makeItem(IDList this, size_t itemSize) { IDList_NEWCELL(this, itemSize, cell); return IDListItemCell_ITEM(cell); }
IDList_push_— Push an allocated item as lastItem on the IDList.
item
- The IDListItem to push.
- Return
- The pushed IDListItem.
static inline IDListItem IDList_push_(IDList this, IDListItem item) { IDListItemCell cell = IDListItem_CELL(item); IDListItem firstItem = IDList_FIRSTITEM(this); IDListItem lastItem = IDList_LASTITEM(this); IDListItemCell last_cell = IDListItem_CELL(lastItem); Except_REQUIRE(IDListItemCell_PREV(cell) == NULL); Except_REQUIRE(IDListItemCell_NEXT(cell) == NULL); if (lastItem != NULL) *IDListItemCell__NEXT(last_cell) = item; if (firstItem == NULL) *IDList__FIRSTITEM(this) = item; *IDListItemCell__PREV(cell) = lastItem; *IDListItemCell__NEXT(cell) = NULL; *IDList__LASTITEM(this) = item; ++*IDList__COUNT(this); //Except_DEBUG(IDList_check(this, item)); return item; }
IDList_push— Make and push an item as lastItem on the IDList.
itemSize
- The item size in bytes.
- Return
- The pushed IDListItem.
IDListItem IDList_push(IDList this, size_t itemSize);
IDList_PUSH— Macro used to IDList_push value types.
#define IDList_PUSH(this, Type, value) \ (*(Type *)IDList_push(this, sizeof(Type)) = (value))
IDList_put_— Put an allocated item as firstItem on the IDList.
item
- The IDListItem to put.
- Return
- The put IDListItem.
static inline IDListItem IDList_put_(IDList this, IDListItem item) { IDListItemCell cell = IDListItem_CELL(item); IDListItem firstItem = IDList_FIRSTITEM(this); IDListItem lastItem = IDList_LASTITEM(this); IDListItemCell first_cell = IDListItem_CELL(firstItem); Except_REQUIRE(IDListItemCell_PREV(cell) == NULL); Except_REQUIRE(IDListItemCell_NEXT(cell) == NULL); if (firstItem != NULL) *IDListItemCell__PREV(first_cell) = item; if (lastItem == NULL) *IDList__LASTITEM(this) = item; *IDListItemCell__NEXT(cell) = firstItem; *IDListItemCell__PREV(cell) = NULL; *IDList__FIRSTITEM(this) = item; ++*IDList__COUNT(this); //Except_DEBUG(IDList_check(this, item)); return item; }
IDList_put— Make and put an item as firstItem on the IDList.
itemSize
- The item size in bytes.
- Return
- The put IDListItem.
IDListItem IDList_put(IDList this, size_t itemSize);
IDList_PUT— Macro used to IDList_put value types.
#define IDList_PUT(this, Type, value) \ (*(Type *)IDList_put(this, sizeof(Type)) = (value))
IDList_insert_— Insert an allocated item before item on the IDList.
before
- The item to insert before.
item
- The IDListItem to insert.
- Return
- The inserted IDListItem.
static inline IDListItem IDList_insert_(IDList this, IDListItem before, IDListItem item) { Except_REQUIRE(before != NULL); if (before == IDList_FIRSTITEM(this)) { return IDList_put_(this, item); } else { IDListItemCell cell = IDListItem_CELL(item); IDListItemCell before_cell = IDListItem_CELL(before); IDListItem prev = IDListItemCell_PREV(before_cell); IDListItemCell prev_cell = IDListItem_CELL(prev); Except_REQUIRE(IDListItemCell_PREV(cell) == NULL); Except_REQUIRE(IDListItemCell_NEXT(cell) == NULL); *IDListItemCell__NEXT(cell) = before; *IDListItemCell__PREV(cell) = prev; *IDListItemCell__PREV(before_cell) = item; *IDListItemCell__NEXT(prev_cell) = item; ++*IDList__COUNT(this); //Except_DEBUG(IDList_check(this, item)); return item; } }
IDList_insert— Make and insert an item before a given item on the IDList.
before
- The item to insert before.
itemSize
- The item size in bytes.
- Return
- The inserted IDListItem.
IDListItem IDList_insert(IDList this, IDListItem before, size_t itemSize);
IDList_append_— Append an allocated item after a given item on the IDList.
after
- The item to append after.
item
- The IDListItem to append.
- Return
- The inserted IDListItem.
static inline IDListItem IDList_append_(IDList this, IDListItem after, IDListItem item) { Except_REQUIRE(after != NULL); if (after == IDList_LASTITEM(this)) { return IDList_push_(this, item); } else { IDListItemCell cell = IDListItem_CELL(item); IDListItemCell after_cell = IDListItem_CELL(after); IDListItem next = IDListItemCell_NEXT(after_cell); IDListItemCell next_cell = IDListItem_CELL(next); Except_REQUIRE(IDListItemCell_PREV(cell) == NULL); Except_REQUIRE(IDListItemCell_NEXT(cell) == NULL); *IDListItemCell__PREV(cell) = after; *IDListItemCell__NEXT(cell) = next; *IDListItemCell__NEXT(after_cell) = item; *IDListItemCell__PREV(next_cell) = item; ++*IDList__COUNT(this); //Except_DEBUG(IDList_check(this, item)); return item; } }
IDList_append— Make and append an item after a given item on the IDList.
after
- The item to append after.
itemSize
- The item size in bytes.
- Return
- The inserted IDListItem.
IDListItem IDList_append(IDList this, IDListItem after, size_t itemSize);
IDList_pop_— Pop without releasing the lastItem IDList item.
- Return
- True iff items remain in this IDList.
static inline void IDList_pop_(IDList this) { IDListItem lastItem = IDList_LASTITEM(this); IDListItemCell last_cell = IDListItem_CELL(lastItem); IDListItem prev = IDListItemCell_PREV(last_cell); Except_CHECK(lastItem != NULL); *IDList__LASTITEM(this) = prev; if (prev == NULL) { *IDList__FIRSTITEM(this) = NULL; } else { IDListItemCell prev_cell = IDListItem_CELL(prev); *IDListItemCell__NEXT(prev_cell) = NULL; } *IDListItemCell__PREV(last_cell) = NULL; *IDListItemCell__NEXT(last_cell) = NULL; --*IDList__COUNT(this); //Except_DEBUG(IDList_check(this, NULL)); }
IDList_POP - Macro used to IDList_pop value types.
#define IDList_POP(this, Type, value) \ ((value) = *(Type *)IDList_lastItem(this), IDList_pop_(this))
IDList_pop— Pop and release the lastItem IDList item.
- Return
- True iff items remain in this IDList.
void IDList_pop(IDList this, IDListItemRelease release);
IDList_drop_— Drop without releasing the firstItem IDList item.
- Return
- True iff items remain in this IDList.
static inline void IDList_drop_(IDList this) { IDListItem firstItem = IDList_FIRSTITEM(this); IDListItemCell first_cell = IDListItem_CELL(firstItem); IDListItem next = IDListItemCell_NEXT(first_cell); Except_CHECK(firstItem != NULL); *IDList__FIRSTITEM(this) = next; if (next == NULL) { *IDList__LASTITEM(this) = NULL; } else { IDListItemCell next_cell = IDListItem_CELL(next); *IDListItemCell__PREV(next_cell) = NULL; } *IDListItemCell__PREV(first_cell) = NULL; *IDListItemCell__NEXT(first_cell) = NULL; --*IDList__COUNT(this); //Except_DEBUG(IDList_check(this, NULL)); }
IDList_DROP - Macro used to IDList_drop value types.
#define IDList_DROP(this, Type, value) \ ((value) = *(Type *)IDList_firstItem(this), IDList_drop_(this))
IDList_drop— Drop and release the firstItem IDList item.
- Return
- True iff items remain in this IDList.
void IDList_drop(IDList this, IDListItemRelease release);
IDList_remove_— Remove without releasing an item from this IDList.
static inline void IDList_remove_(IDList this, IDListItem item) { if (item == IDList_FIRSTITEM(this)) IDList_drop_(this); else if (item == IDList_LASTITEM(this)) IDList_pop_(this); else { IDListItemCell cell = IDListItem_CELL(item); IDListItem prev = IDListItemCell_PREV(cell); IDListItem next = IDListItemCell_NEXT(cell); IDListItemCell prev_cell = IDListItem_CELL(prev); IDListItemCell next_cell = IDListItem_CELL(next); //Except_DEBUG(IDList_check(this, item)); *IDListItemCell__PREV(next_cell) = prev; *IDListItemCell__NEXT(prev_cell) = next; *IDListItemCell__PREV(cell) = NULL; *IDListItemCell__NEXT(cell) = NULL; --*IDList__COUNT(this); } }
IDList_remove— Remove and release an item from this IDList.
static inline void IDList_remove(IDList this, IDListItem item, IDListItemRelease release) { Memory memory = IDList_MEMORY(this); IDListItemCell cell = IDListItem_CELL(item); IDList_remove_(this, item); if (release != NULL) { (*release)(item); } Memory_free_(memory, cell); }
IDList_rotate— Rotate the list so that item at index
becomes firstItem (index 0).
void IDList_rotate(IDList this, int32_t index);
IDList_contains— Test if this IDList contains the given IDListItem.
bool IDList_contains(const_IDList this, IDListItem item);
IDList_containsSame— Test if this IDList contains the item same as the given object.
compare
- The compare function, returns zero if its two arguments compare the same.
- Return
- The firstItem IDList item that was found the same as the given object.
IDListItem IDList_containsSame(const_IDList this, int (*compare)(IDListItem, IDListItem), IDListItem object);
IDList_grep— Grep this IDList according to a given keep function.
keep
- Pointer to the item keep function, returns true for the items to keep.
that
- The filtered out items are pushed on that IDList.
- Return
- The number of items filtered out.
int IDList_grep(IDList this, IDList that, bool (*keep)(IDListItem, va_list), ...);
IDList_transfer— Transfer all items from this IDList at the end of that IDList.
void IDList_transfer(IDList this, IDList that);
IDList_sort— Sort this IDList according to the compare
compare function.
- Return
- False iff this IDList was already sorted.
bool IDList_sort(IDList this, IDListItemCompare compare);