IQueue.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 IQueue implements a double-ended queue of inlined items. storage. This is the traditional double-ended queue ADT.

IQueue— Queue of inlined items in contiguous storage.

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

struct IQueue_ {
  //@args       Memory memory, size_t itemSize, int32_t maxCount
  Memory MEMORY;        // Where the IQueue items are allocated.
  size_t ITEMSIZE;
  int32_t MAXCOUNT;
  //@access WRAPSIZE    ((IQueue_MAXCOUNT(this) + 1)*IQueue_ITEMSIZE(this))
  IQueueItem_ *BASE;
  //@access WRAPITEM    ((char *)IQueue_BASE(this) + IQueue_WRAPSIZE(this))
  IQueueItem_ *PAST;
  IQueueItem_ *FIRSTITEM;
};
IQueue_resize— Resize this IQueue.
maxCount
The new maxCount. After IQueue_resize, IQueue may have moved in memory.
void
IQueue_resize(IQueue this, int32_t maxCount);
IQueue_empty— Empty this IQueue.
void
IQueue_empty(IQueue this, IQueueItemRelease release);
IQueue_memory— This IQueue memory.
static inline Memory
IQueue_memory(const_IQueue this)
{
  return IQueue_MEMORY(this);
}
IQueue_itemSize— Size in bytes of an IQueue item.
static inline size_t
IQueue_itemSize(const_IQueue this)
{
  return IQueue_ITEMSIZE(this);
}
IQueue_maxCount— This IQueue maximum count.
static inline int32_t
IQueue_maxCount(const_IQueue this)
{
  return IQueue_MAXCOUNT(this);
}
IQueue_base— This IQueue base item.
static inline IQueueItem_ *
IQueue_base(const_IQueue this)
{
  return IQueue_BASE(this);
}
IQueue_wrapSize— Needed by IQueue_FOREACH and friends.
static inline size_t
IQueue_wrapSize(const_IQueue this)
{
  return IQueue_WRAPSIZE(this);
}
IQueue_past— This IQueue past item.
static inline IQueueItem_ *
IQueue_past(const_IQueue this)
{
  return IQueue_PAST(this);
}
IQueue_firstItem— This IQueue first item.
static inline IQueueItem_ *
IQueue_firstItem(const_IQueue this)
{
  return IQueue_FIRSTITEM(this);
}
IQueue_usedSize— Size in bytes used by this IQueue items.
static inline size_t
IQueue_usedSize(const_IQueue this)
{
  size_t wrapSize = IQueue_WRAPSIZE(this);
  char *firstItem = IQueue_FIRSTITEM(this);
  char *past = IQueue_PAST(this);
  if (past < firstItem) past += wrapSize;
  return (past - firstItem);
}
IQueue_isEmpty— True iff this IQueue is empty.
static inline bool
IQueue_isEmpty(const_IQueue this)
{
  char *firstItem = IQueue_FIRSTITEM(this);
  char *past = IQueue_PAST(this);
  return past == firstItem;
}
IQueue_isSingle— True iff this IQueue has a single entry.
static inline bool
IQueue_isSingle(const_IQueue this)
{
  size_t wrapSize = IQueue_WRAPSIZE(this);
  size_t itemSize = IQueue_ITEMSIZE(this);
  char *firstItem = IQueue_FIRSTITEM(this);
  char *past = IQueue_PAST(this);
  char *lastItem = past - itemSize;
  return firstItem == lastItem ||
      firstItem == lastItem + wrapSize;
}
IQueue_isFull— True iff this IQueue is full.
static inline bool
IQueue_isFull(const_IQueue this)
{
  size_t wrapSize = IQueue_WRAPSIZE(this);
  size_t itemSize = IQueue_ITEMSIZE(this);
  char *firstItem = IQueue_FIRSTITEM(this);
  char *past = IQueue_PAST(this);
  char *prevItem = firstItem - itemSize;
  return past == prevItem ||
      past == prevItem + wrapSize;
}
IQueue_count— Count items in the IQueue.
Return
The count of items in the IQueue.
static inline int32_t
IQueue_count(const_IQueue this)
{
  size_t usedSize = IQueue_usedSize(this);
  size_t itemSize = IQueue_ITEMSIZE(this);
  return usedSize/itemSize;
}
IQueue_lastItem— Last item of the IQueue.
Return
Pointer to the last item.
static inline IQueueItem_ *
IQueue_lastItem(const_IQueue this)
{
  size_t wrapSize = IQueue_WRAPSIZE(this);
  size_t itemSize = IQueue_ITEMSIZE(this);
  char *past = IQueue_PAST(this);
  char *base = IQueue_BASE(this);
  char *lastItem = past - itemSize;
  Except_REQUIRE(!IQueue_isEmpty(this));
  if (lastItem < base) lastItem += wrapSize;
  return lastItem;
}
IQueue_BOT— Dereference bottom (first) item of this IQueue.
#define IQueue_BOT(this, Type) *(Type *)IQueue_firstItem(this)
IQueue_TOP— Dereference top (last) item of this IQueue.
#define IQueue_TOP(this, Type) *(Type *)IQueue_lastItem(this)
IQueue_wrapItem— Needed by IQueue_FOREACH and friends.
static inline IQueueItem_ *
IQueue_wrapItem(const_IQueue this)
{
  return IQueue_WRAPITEM(this);
}
IQueue_FOREACH— Iterates from first to last IQueue item.

Exiting IQueue_FOREACH with break or return is allowed.

this
The IQueue.
Type
Type of the inlined items.
iter
Type* pointer set to each item.
#define IQueue_FOREACH(this, Type, iter) { \
  if (!IQueue_isEmpty(this)) { \
    Type *IQueue_FIRSTITEM = (Type *)IQueue_firstItem(this); \
    Type *IQueue_LASTITEM = (Type *)IQueue_lastItem(this); \
    Type *IQueue_WRAPITEM = (Type *)IQueue_wrapItem(this), *(iter); \
    size_t IQueue_WRAPSIZE = IQueue_wrapSize(this); \
    Except_CHECK(sizeof(Type) == IQueue_itemSize(this)); \
    if (IQueue_LASTITEM < IQueue_FIRSTITEM) \
      IQueue_LASTITEM = (Type *)((char *)IQueue_LASTITEM + IQueue_WRAPSIZE); \
    for (iter = IQueue_FIRSTITEM; iter <= IQueue_LASTITEM; ++(iter)) { \
      if (iter >= IQueue_WRAPITEM) { \
        iter = (Type *)((char *)(iter) - IQueue_WRAPSIZE); \
        IQueue_LASTITEM = (Type *)((char *)(IQueue_LASTITEM) - IQueue_WRAPSIZE); \
      } \
      {
#define IQueue_ENDEACH \
      } \
    } \
  } \
}
IQueue_FORBACK— Iterates from last to first IQueue item.

Exiting IQueue_FORBACK with break or return is allowed.

this
The IQueue.
Type
Type of the inlined items.
iter
Type* pointer set to each item.
#define IQueue_FORBACK(this, Type, iter) { \
  if (!IQueue_isEmpty(this)) { \
    Type *IQueue_FIRSTITEM = (Type *)IQueue_firstItem(this); \
    Type *IQueue_LASTITEM = (Type *)IQueue_lastItem(this); \
    Type *BASE = (Type *)IQueue_base(this), *(iter); \
    size_t IQueue_WRAPSIZE = IQueue_wrapSize(this); \
    Except_CHECK(sizeof(Type) == IQueue_itemSize(this)); \
    if (IQueue_LASTITEM < IQueue_FIRSTITEM) \
      IQueue_FIRSTITEM = (Type *)((char *)IQueue_FIRSTITEM - IQueue_WRAPSIZE); \
    for (iter = IQueue_LASTITEM; iter >= IQueue_FIRSTITEM; --(iter)) { \
      if (iter < BASE) { \
        iter = (Type *)((char *)(iter) + IQueue_WRAPSIZE); \
        IQueue_FIRSTITEM = (Type *)((char *)(IQueue_FIRSTITEM) + IQueue_WRAPSIZE); \
      } \
      {
#define IQueue_ENDBACK \
      } \
    } \
  } \
}
IQueue_push— Push as last item on the IQueue.
Return
The pushed IQueueItem.
static inline IQueueItem_ *
IQueue_push(IQueue this)
{
  size_t wrapSize = IQueue_WRAPSIZE(this);
  size_t itemSize = IQueue_ITEMSIZE(this);
  char *past = IQueue_PAST(this);
  char *wrapItem = IQueue_WRAPITEM(this);
  IQueueItem_ *newItem = (IQueueItem_ *)past;
  Except_REQUIRE(!IQueue_isFull(this));
  past += itemSize;
  if (past >= wrapItem) past -= wrapSize;
  *IQueue__PAST(this) = past;
  return newItem;
}

IQueue_PUSH - Macro used to IQueue_push value types.

#define IQueue_PUSH(this, Type, value) \
  (*(Type *)IQueue_push(this) = (value))
IQueue_put— Put as first item on the IQueue.
Return
The put IQueueItem.
static inline IQueueItem_ *
IQueue_put(IQueue this)
{
  size_t wrapSize = IQueue_WRAPSIZE(this);
  size_t itemSize = IQueue_ITEMSIZE(this);
  char *firstItem = IQueue_FIRSTITEM(this);
  char *base = IQueue_BASE(this);
  Except_REQUIRE(!IQueue_isFull(this));
  firstItem -= itemSize;
  if (firstItem < base) firstItem += wrapSize;
  *IQueue__FIRSTITEM(this) = firstItem;
  return firstItem;
}

IQueue_PUT - Macro used to IQueue_put value types.

#define IQueue_PUT(this, Type, value) \
  (*(Type *)IQueue_put(this) = (value))
IQueue_pop— Pop the last IQueue item.
Return
True iff items remain in this IQueue.
static inline void
IQueue_pop(IQueue this, IQueueItemRelease release)
{
  size_t wrapSize = IQueue_WRAPSIZE(this);
  size_t itemSize = IQueue_ITEMSIZE(this);
  char *past = IQueue_PAST(this);
  char *base = IQueue_BASE(this);
  Except_REQUIRE(!IQueue_isEmpty(this));
  past -= itemSize;
  if (past < base) past += wrapSize;
  if (release != NULL) {
    (*release)(past);
  }
  *IQueue__PAST(this) = past;
}

IQueue_POP - Macro used to IQueue_pop value types.

#define IQueue_POP(this, Type, value) \
  ((value) = *(Type *)IQueue_lastItem(this), IQueue_pop_(this))
IQueue_drop— Drop the first IQueue item.
Return
True iff items remain in this IQueue.
static inline void
IQueue_drop(IQueue this, IQueueItemRelease release)
{
  size_t wrapSize = IQueue_WRAPSIZE(this);
  size_t itemSize = IQueue_ITEMSIZE(this);
  char *firstItem = IQueue_FIRSTITEM(this);
  char *wrapItem = IQueue_WRAPITEM(this);
  Except_REQUIRE(!IQueue_isEmpty(this));
  if (release != NULL) {
    (*release)(firstItem);
  }
  firstItem += itemSize;
  if (firstItem >= wrapItem) firstItem -= wrapSize;
  *IQueue__FIRSTITEM(this) = firstItem;
}

IQueue_DROP - Macro used to IQueue_drop value types.

#define IQueue_DROP(this, Type, value) \
  ((value) = *(Type *)IQueue_firstItem(this), IQueue_drop_(this))