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);