IStack.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.

The IStack implements a FIFO stack of inlined items over sequential storage. This is the traditional push-down stack ADT.

IStack— Stack of inlined items in contiguous storage.

If maxCount is zero, no memory is allocated at construction time.

struct IStack_ {
  //@args       Memory memory, size_t itemSize, int32_t maxCount
  Memory MEMORY;        // Where the IStack items are allocated.
  size_t ITEMSIZE;
  int32_t MAXCOUNT;
  //@access MAXSIZE     (IStack_MAXCOUNT(this)*IStack_ITEMSIZE(this))
  IStackItem_ *BASE;
  IStackItem_ *PAST;
  //@access USEDSIZE    ((char*)IStack_PAST(this) - (char*)IStack_BASE(this))
  void *POINTER;
};
IStack_resize— Resize this IStack.
maxCount
The new maxCount. After IStack_resize, IStack may have moved in memory so any pointer obtained though IStack_access() will be dangling.
void
IStack_resize(IStack this, int32_t maxCount);
IStack_empty— Empty this IStack.
void
IStack_empty(IStack this, IStackItemRelease release);
IStack_memory— This IStack memory.
static inline Memory
IStack_memory(const_IStack this)
{
  return IStack_MEMORY(this);
}
IStack_itemSize— This IStack item size.
static inline size_t
IStack_itemSize(const_IStack this)
{
  return IStack_ITEMSIZE(this);
}
IStack_maxCount— This IStack maximum count.
static inline int32_t
IStack_maxCount(const_IStack this)
{
  return IStack_MAXCOUNT(this);
}
IStack_base— This IStack base item.
static inline IStackItem_ *
IStack_base(const_IStack this)
{
  return IStack_BASE(this);
}
IStack_past— This IStack past item.
static inline IStackItem_ *
IStack_past(const_IStack this)
{
  return IStack_PAST(this);
}
IStack_maxSize— Maximum size in bytes used by this IStack items.
static inline size_t
IStack_maxSize(const_IStack this)
{
  return IStack_MAXSIZE(this);
}
IStack_usedSize— Size in bytes used by this IStack items.
static inline size_t
IStack_usedSize(const_IStack this)
{
  return IStack_USEDSIZE(this);
}
IStack_isEmpty— True iff this IStack is empty.
static inline bool
IStack_isEmpty(const_IStack this)
{
  char *base = IStack_BASE(this);
  char *past = IStack_PAST(this);
  return past == base;
}
IStack_isSingle— True iff this IStack has a single entry.
static inline bool
IStack_isSingle(const_IStack this)
{
  char *base = IStack_BASE(this);
  char *past = IStack_PAST(this);
  size_t itemSize = IStack_ITEMSIZE(this);
  return past - base == itemSize;
}
IStack_isFull— True iff this IStack is full.
static inline bool
IStack_isFull(const_IStack this)
{
  size_t usedSize = IStack_USEDSIZE(this);
  size_t maxSize = IStack_MAXSIZE(this);
  return usedSize == maxSize;
}
IStack_count— Count items in the IStack.
Return
The count of items in the IStack.
static inline int32_t
IStack_count(const_IStack this)
{
  size_t usedSize = IStack_USEDSIZE(this);
  size_t itemSize = IStack_ITEMSIZE(this);
  return usedSize/itemSize;
}
IStack_firstItem— First item of the IStack.
Return
Pointer to the first item.
static inline IStackItem_ *
IStack_firstItem(const_IStack this)
{
  Except_REQUIRE(!IStack_isEmpty(this));
  return (IStackItem)IStack_BASE(this);
}
IStack_BOT— Dereference bottom (first) item of this IStack.
#define IStack_BOT(this, Type) *(Type *)IStack_firstItem(this)
IStack_lastItem— Last item of the IStack.
Return
Pointer to the last item.
static inline IStackItem_ *
IStack_lastItem(const_IStack this)
{
  char *past = IStack_PAST(this);
  size_t itemSize = IStack_ITEMSIZE(this);
  Except_REQUIRE(!IStack_isEmpty(this));
  return (IStackItem_ *)(past - itemSize);
}
IStack_TOP— Dereference top (last) item of this IStack.
#define IStack_TOP(this, Type) *(Type *)IStack_lastItem(this)
IStack_FOREACH— Iterates from first to last IStack item.

Exiting IStack_FOREACH with break or return is allowed.

this
The IStack.
Type
Type of the inlined items.
iter
Type* pointer set to each item.
#define IStack_FOREACH(this, Type, iter) { \
  Type *IStack_BASE = (Type *)IStack_base(this); \
  Type *IStack_PAST = (Type *)IStack_past(this), *(iter); \
  Except_CHECK(IStack_BASE == NULL || sizeof(Type) == IStack_itemSize(this)); \
  for (iter = IStack_BASE; iter < IStack_PAST; ++(iter)) {
#define IStack_ENDEACH \
  } \
}
IStack_FORBACK— Iterates from last to first IStack item.

Exiting IStack_FORBACK with break or return is allowed.

this
The IStack.
Type
Type of the inlined items.
iter
Type* pointer set to each item.
#define IStack_FORBACK(this, Type, iter) { \
  Type *IStack_BASE = (Type *)IStack_base(this); \
  Type *IStack_PAST = (Type *)IStack_past(this), *(iter); \
  Except_CHECK(IStack_BASE == NULL || sizeof(Type) == IStack_itemSize(this)); \
  for (iter = IStack_PAST - 1; iter >= IStack_BASE; --(iter)) {
#define IStack_ENDBACK \
  } \
}
IStack_access— Access the IStack by index.
index
The index.
Return
Pointer to the corresponding item.
static inline IStackItem
IStack_access(const_IStack this, int32_t index)
{
  char *base = IStack_BASE(this);
  size_t itemSize = IStack_ITEMSIZE(this);
  size_t offset = itemSize*index;
  Except_REQUIRE(index >= 0 && offset < IStack_USEDSIZE(this));
  return base + offset;
}
IStack_push— Push as last item on the IStack.
Return
The pushed IStackItem, or NULL if stack storage is exhausted.
static inline IStackItem
IStack_push(IStack this)
{
  size_t itemSize = IStack_ITEMSIZE(this);
  char *past = IStack_PAST(this);
  if (IStack_isFull(this)) return NULL;
  *IStack__PAST(this) = past + itemSize;
  return past;
}

IStack_PUSH - Macro used to IStack_push value types.

#define IStack_PUSH(this, Type, value) \
  (*(Type *)IStack_push(this) = (value))
IStack_push2— Push as last item on the IStack, resizing the IStack if necessary.
Return
The pushed IStackItem. As the IStack may be resized, it is an error to maintain pointers to existing items.
IStackItem
IStack_push2(IStack this);

IStack_PUSH2 - Macro used to IStack_push2 value types.

#define IStack_PUSH2(this, Type, value) \
  (*(Type *)IStack_push2(this) = (value))
IStack_pop_— Specialized IStack_pop
static inline void
IStack_pop_(IStack this)
{
  size_t itemSize = IStack_ITEMSIZE(this);
  char *past = IStack_PAST(this);
  Except_CHECK(!IStack_isEmpty(this));
  *IStack__PAST(this) = (past -= itemSize);
}

IStack_POP - Macro used to IStack_pop value types.

#define IStack_POP(this, Type, value) \
  ((value) = *(Type *)IStack_lastItem(this), IStack_pop_(this))
IStack_pop— Pop the last IStack item.
Return
True iff items remain in this IStack.
static inline void
IStack_pop(IStack this, IStackItemRelease release)
{
  IStackItem lastItem = IStack_lastItem(this);
  Except_REQUIRE(!IStack_isEmpty(this));
  if (release != NULL) {
    (*release)(lastItem);
  }
  *IStack__PAST(this) = lastItem;
}