Indexed.xcc

Benoit Dupont de Dinechin (Benoit.Dupont-de-Dinechin@st.com).

Copyright 2007 STMicroelectronics.

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 Indexed object contains two fields: an immutable IDENTITY and a mutable INDEX. The IDENTITY is unique and can be used as a key for the object. The INDEX is managed by a client who needs to attach information Indexed objects by means of an array.

union Indexed_ {
  int64_t INT64;                        // Force int64_t aligment.
  struct {
    uint32_t IDENTITY;                  // Identity of this Indexed.
    int32_t INDEX;                      // Index of this Indexed.
  } STRUCT_;
};
typedef union Indexed_ Indexed_, *Indexed;
typedef const union Indexed_ *const_Indexed;
#define Indexed_IDENTITY(this)  (this->STRUCT_.IDENTITY)
#define Indexed__IDENTITY(this) (&this->STRUCT_.IDENTITY)
#define Indexed_INDEX(this)     (this->STRUCT_.INDEX)
#define Indexed__INDEX(this)    (&this->STRUCT_.INDEX)
#define Indexed_Ctor(this, factory) { \
  *Indexed__IDENTITY(this) = IndexedFactory_makeIdentity(factory); \
  *Indexed__INDEX(this) = -1; \
}

An IndexedFactory Manages the IDENTITY(ies) of Indexed(s).

struct IndexedFactory_ {
  //@args       
  uint32_t COUNTER;                     // IDENTITY for the next Indexed object.
  uint32_t MAXCOUNT;                    // Record of maximum COUNTER value reached.
};
IndexedFactory_maxCount— This IndexedFactory MAXCOUNT value.
static inline uint32_t
IndexedFactory_maxCount(const_IndexedFactory this)
{
  return IndexedFactory_MAXCOUNT(this);
}
IndexedFactory_makeIdentity— Make an IDENTITY for the next Indexed object.
static inline int32_t
IndexedFactory_makeIdentity(IndexedFactory this)
{
  int32_t identity = (*IndexedFactory__COUNTER(this))++;
  if (IndexedFactory_MAXCOUNT(this) < IndexedFactory_COUNTER(this)) {
    *IndexedFactory__MAXCOUNT(this) = IndexedFactory_COUNTER(this);
  }
  return identity;
}
IndexedFactory_reset— Reset this IndexedFactory COUNTER.
static inline void
IndexedFactory_reset(IndexedFactory this)
{
  *IndexedFactory__COUNTER(this) = 0;
}
IndexedTable— Table of Indexed objects banaged by INDEX.

The IndexedTable has two purposes: 1) manage the INDEX fields of Indexed(s) that belong to it; 2) provide the ground set for IndexedSparse subsets.

struct IndexedTable_ {
  //@args       Memory memory, int32_t estimate
  PtrSeq_ __;
  //@access MEMORY      PtrSeq_memory(IndexedTable____(this))
  //@access COUNT       PtrSeq_count(IndexedTable____(this))
  //@access BASE        (Indexed *)PtrSeq_base(IndexedTable____(this))
};
IndexedTable_empty— Empty this IndexedTable.
static inline void
IndexedTable_empty(IndexedTable this)
{
  PtrSeq_empty(IndexedTable____(this));
}
IndexedTable_base— Direct access to this IndexedTable Indexed array.
static inline const Indexed *
IndexedTable_base(const_IndexedTable this) {
  return IndexedTable_BASE(this);
}
IndexedTable_FOREACH_Indexed— Iterator this IndexedTable Indexed(ies).
#define IndexedTable_FOREACH_Indexed(this, Type, object) { \
  const Indexed *IndexedTable_BASE = IndexedTable_base(this); \
  int32_t IndexedTable_COUNT = IndexedTable_count(this), IndexedTable_INDEX = 0; \
  for (; IndexedTable_INDEX < IndexedTable_COUNT; IndexedTable_INDEX++) { \
    Type object = (Type)IndexedTable_BASE[IndexedTable_INDEX];
#define IndexedTable_ENDEACH_Indexed \
  } \
}
IndexedTable_CONTAINS— Macro used in IndexedTable_contains.

For use in cases IndexedTable_base is constant.

#define IndexedTable_CONTAINS(object) ( \
  Indexed_INDEX((const_Indexed)(object)) >= 0 && \
  Indexed_INDEX((const_Indexed)(object)) < IndexedTable_COUNT && \
  IndexedTable_BASE[Indexed_INDEX((const_Indexed)(object))] == \
      (const_Indexed)(object) \
)
IndexedTable_contains— Test that this IndexedTable contains a Indexed.
static inline bool
IndexedTable_contains(const_IndexedTable this, const_Indexed object)
{
  int32_t count = IndexedTable_COUNT(this);
  int32_t index = Indexed_INDEX(object);
  const Indexed *base = IndexedTable_BASE(this);
  if (index >= 0 && index < count) {
    return base[index] == object;
  }
  return false;
}
IndexedTable_insert— Insert an object into this IndexedTable if not there.
table
IndexedTable already initialized.
object
Indexed object to add to the table.
static inline bool
IndexedTable_insert(IndexedTable this, Indexed object)
{
  int32_t count = IndexedTable_COUNT(this);
  int32_t index = Indexed_INDEX(object);
  Indexed *base = IndexedTable_BASE(this);
  if (index >= 0 && index < count) {
    if (base[index] == object) return false;
  }
  PtrSeq_push2(IndexedTable____(this), object);
  *Indexed__INDEX(object) = count;
  return true;
}
IndexedTable_removeHigh— Remove a Indexed with high INDEX from IndexedTable.
Warning
The INDEX of some other Indexed object will change.
bool
IndexedTable_removeHigh(IndexedTable this, const_Indexed object, int32_t high);
IndexedTable_remove— Remove a Indexed from IndexedTable.
Warning
The INDEX of some other Indexed will change.
static inline bool
IndexedTable_remove(IndexedTable this, const_Indexed object)
{
  return IndexedTable_removeHigh(this, object, 0);
}
IndexedSparse— Sparse set of Indexed objects based on INDEX Sparse set.
struct IndexedSparse_ {
  //@args       Memory memory, IndexedTable table
  Sparse_ __;           // A IndexedSparse_ ISA Sparse_.
  //@access MEMORY      Sparse_MEMORY(IndexedSparse____(this))
  IndexedTable TABLE;           // The IndexedTable this IndexedSparse refers to.
  //@access BASE        IndexedTable_base(IndexedSparse_TABLE(this))
};
IndexedSparse_table— The IndexedTable this IndexedSparse refers to.
static inline IndexedTable
IndexedSparse_table(IndexedSparse this) {
  return IndexedSparse_TABLE(this);
}
static inline const_IndexedTable
IndexedSparse_table_const(const_IndexedSparse this) {
  return IndexedSparse_TABLE(this);
}
IndexedSparse_base— For use by IndexedSparse_FOREACH_Indexed.
static inline const Indexed *
IndexedSparse_base(const_IndexedSparse this) {
  return IndexedSparse_BASE(this);
}
IndexedSparse_FOREACH_Indexed— Iterate over this IndexedSparse objects.
#define IndexedSparse_FOREACH_Indexed(this, Type, object) { \
  const Indexed *IndexedSparse_BASE = IndexedSparse_base(this); \
  const_Sparse IndexedSparse____ = IndexedSparse__const(this); \
  Sparse_FOREACH(IndexedSparse____, IndexedSparse_INDEX) { \
    int32_t IndexedSparse_POSITION = Sparse_POSITION; \
    Type object = (Type)IndexedSparse_BASE[IndexedSparse_INDEX];
#define IndexedSparse_ENDEACH_Indexed \
  } Sparse_ENDEACH \
}