Taquis - PC Base FFT Spectrum Analyzers, Oscilloscopes, Data Analysis, Data Acquisition, and Application Frameworks   AtOne Application Framework
"A Framework working with you, not against you..."

 
Home
Features
Programming
License
Downloads
Directions

Contact
info@taquis.com


 
 

Generic Classes

AtOne provides a range of useful and efficient macro defined template classes including Lists, Queues, Stacks and Hash Tables. By using in-house containers rather than STL, AtOne maintains a consistent performance indepedent of the compiler in which the library is complied. This can be a very important feature in minimising the likelihood of port problems when switching to a different compiler and/or operating system. Macro based template classes are used to minimize compiled code image size and avoid various compiler to compiler quirks with regard to C++ templates. On a personal note, although harder to debug, I prefer the look and feel of code using macro based templates over that of C++ templates. The macros implementing these generic classes are defined in contain.hpp.
 

Generic Linked Lists

A linked list of a given class is declared using the declList(OfType) macro, where OfType is the class of object in the list. This macro should typically only be used in a header file. Linked lists require no further definition (ie. there is no corresponding implementation macro). As an example declList(OsiString) would create the following,

typedef bool  *CiStringListForAllDoCallback)(OsiString* pThis, void* pData);
typedef int   (*OsiStringListCompareCallback)(const OsiString* pItemA, const OsiString* pItemB);
typedef void  (*OsiStringListRemovedCallback)(OsiString* pItem);

class OsiStringList : public OsiList
{
public:
  OsiStringList();

  OsiString* forAllDo(OsiStringListForAllDoCallback pCallback, void* pData = 0) const;
  bool       insert(OsiString* pObj);
  bool       append(OsiString* pObj);
  bool       remove(OsiString* pObj);
  OsiString* removeFirst();
  OsiString* removeLast();
  OsiString* first() const;
  OsiString* last() const;
  void       sort(OsiStringListCompareCallback pCompareCallback, OsiStringListRemovedCallback pRemoveCallback = 0);
};

class OsiStringListIter : public OsiListIter
{
public:
  OsiStringListIter(OsiStringList& aList);
  OsiStringListIter(OsiStringList* aList);
  OsiStringListIter(const OsiStringList& aList);
  OsiStringListIter(const OsiStringList* aList);
  OsiStringListIter(const OsiStringListIter& rListIter);

  bool       find(OsiString* pObj) const;
  OsiString* remove();
  OsiString* replace(OsiString* pObj);
  bool       insert(OsiString* pObj);
  OsiString* first() const;
  OsiString* last() const;
  OsiString* next() const;
  OsiString* prev() const;
  OsiString* operator ++() const;
  OsiString* operator ++(int) const;
  OsiString* operator --() const;
  OsiString* operator --(int) const;
             operator OsiString*() const;
};

Useage of these classes is essentially self explanatory. If in doubt see the AtOne source code as linked lists are used extensively. OsiStringListIter is an iterator class that can be use to conveniently step through the contents of a given linked list. Iterators in AtOne are multi-instance safe meaning that if two or more iterators point to the same linked list then modification of the list by one of the iterators will not disrupt the other iterators. However, it should be noted that lists are not multi-thread safe and will require protection if multiple threads are going to access the same list at the same time. 
 

Generic Queues

A queue of a given class is declared using the declQueue(OfType) macro, where OfType is the class of object in the queue. This macro should typically only be used in a header file. Queues require no further definition (ie. there is no corresponding implementation macro). As an example declQueue(OsiString) would create the following,

class OsiStringQueue : public OsiQueue
{
public:
  OsiStringQueue();

  bool       enqueue(OsiString* pObj);
  OsiString* dequeue();
};

Useage of this class is self explanatory. It should be noted that AtOne queues are not multi-thread safe and will require protection if multiple threads are going to access the same queue at the same time. 

Generic Stacks

A stack of a given class is declared using the declStack(OfType) macro, where OfType is the class of object in the stack. This macro should typically only be used in a header file. Stacks require no further definition (ie. there is no corresponding implementation macro). As an example declStack(OsiString) would create the following,

class OsiStringStack : public OsiStack
{
public:
  OsiStringStack();

  bool       push(OsiString* pObj);
  OsiString* pop();
  OsiString* top() const;
};

Useage of this class is self explanatory. It should be noted that AtOne stacks are not multi-thread safe and will require protection if multiple threads are going to access the same stack at the same time. 

Generic Hash Tables

A hash table of a given class is declared using the declHashTable(OfType) macro, where OfType is the class of object in the hash table. This macro should typically only be used in a header file. Hash tables require no further definition (ie. there is no corresponding implementation macro). As an example declHashTable(OsiString) would create the following,

typedef bool  (*OsiStringHashTableForAllDoCallback)(OsiString* pThis, void* pData);

class OsiStringHashTable : public OsiHashTable
{
public:
  OsiStringHashTable(bool bIsUniqueKey, int nSize);

  OsiString* forAllDo(OsiStringHashTableForAllDoCallback pCallback, void* pData = 0) const;
  OsiString* forAllDo(OsiStringHashTableForAllDoCallback pCallback, const OsiHashTableKey& rKey, void* pData = 0) const;
  bool       insert(OsiString* pObj, const OsiHashTableKey& rKey);
  bool       remove(OsiString* pObj, const OsiHashTableKey& rKey);
  bool       find(OsiString* pObj, const OsiHashTableKey& rKey) const;
  OsiString* remove(const OsiHashTableKey& rKey);
  OsiString* find(const OsiHashTableKey& rKey) const;
};

class OsiStringHashTableIter : public OsiHashTableIter
{
public:
  OsiStringHashTableIter(OsiStringHashTable& aTable, const OsiHashTableKey& rKey);
  OsiStringHashTableIter(const OsiStringHashTable& aTable, const OsiHashTableKey& rKey);
  OsiStringHashTableIter(const OsiStringHashTable* aTable, const OsiHashTableKey& rKey);
  OsiStringHashTableIter(const OsiStringHashTableIter& rIter);

  OsiString*  first() const;
  OsiString*  first(const OsiHashTableKey& rKey) const;
  OsiString*  last() const;
  OsiString*  last(const OsiHashTableKey& rKey) const;

  bool    find(OsiString* pObj) const;
  OsiString*  remove();
  OsiString*  next() const;
  OsiString*  prev() const;
  OsiString*  operator ++() const;
  OsiString*  operator ++(int) const;
  OsiString*  operator --() const;
  OsiString*  operator --(int) const;
              operator OsiString*() const;
};

class OsiStringKeylessHashTableIter : public OsiKeylessHashTableIter
{
public:
  OsiStringKeylessHashTableIter(OsiStringHashTable& aTable);
  OsiStringKeylessHashTableIter(OsiStringHashTable* aTable);
  OsiStringKeylessHashTableIter(OsiStringKeylessHashTableIter& rIter);

  OsiString*  first() const;
  OsiString*  last() const;
  bool        find(OsiString* pObj) const;
  OsiString*  remove();
  OsiString*  next() const;
  OsiString*  prev() const;
  OsiString*  operator ++() const;
  OsiString*  operator ++(int) const;
  OsiString*  operator --() const;
  OsiString*  operator --(int) const;
              operator OsiString*() const;
};

Useage of these classes is essentially self explanatory. If in doubt see the AtOne source code as hash tables are used extensively. OsiStringHashTableIter is an iterator class that can be use to conveniently step through the contents of a given hashe table using a given key. OsiStringKeylessHashTableIter is an iterator class that iterates through the entire hash table rather than just those with the same key. Iterators in AtOne are multi-instance safe meaning that if two or more iterators point to the same hash table then modification of the hash table by one of the iterators will not disrupt the other iterators. However, it should be noted that hash tables are not multi-thread safe and will require protection if multiple threads are going to access the same hash table at the same time. 
 

The Main Application


"We use Zeus for Windows and Watcom C/C++ 11.0 as our development environment of choice..."

Paavo Jumppanen
Creator of AtOne Application Framework


This document was last modified on 1st September, 2001
Copyright (C) 2001, Paavo Jumppanen
All rights reserved.