www.pudn.com > cjbtaskbarapplet.zip > LinkedClass.hpp
#ifndef __LINKED_CLASS__
#define __LINKED_CLASS__
///////////////////////////////////////////////////////////////////////////////
//
// File : $Workfile: LinkedClass.hpp $
// Version : $Revision: 1.0 $
// Function :
//
// Author : $Author: Len $
// Date : $Date: Dec 28 1997 12:16:10 $
//
// Notes : A template base class for classes whos instances are all
// linked into a list that can be used to affect all of them
// at run time.
//
// Modifications :
//
// $Log: D:/Documents/Len/Sources/Stuff/TaskBarApplet/TaskBarLib/PVCS/LinkedClass.hpv $
//
// Rev 1.0 Dec 28 1997 12:16:10 Len
// Initial revision.
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright 1997 JetByte Limited.
//
// JetByte Limited grants you ("Licensee") a non-exclusive, royalty free,
// licence to use, modify and redistribute this software in source and binary
// code form, provided that i) this copyright notice and licence appear on all
// copies of the software; and ii) Licensee does not utilize the software in a
// manner which is disparaging to JetByte Limited.
//
// This software is provided "AS IS," without a warranty of any kind. ALL
// EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
// ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
// OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBYTE LIMITED AND ITS LICENSORS
// SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
// USING, MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO
// EVENT WILL JETBYTE LIMITED BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
// OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
// DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING
// OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF JETBYTE LIMITED
// HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
//
// This software is not designed or intended for use in on-line control of
// aircraft, air traffic, aircraft navigation or aircraft communications; or in
// the design, construction, operation or maintenance of any nuclear
// facility. Licensee represents and warrants that it will not use or
// redistribute the Software for such purposes.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Namespace: JetByteTools
///////////////////////////////////////////////////////////////////////////////
namespace JetByteTools {
///////////////////////////////////////////////////////////////////////////////
// Templates defined in this file...
///////////////////////////////////////////////////////////////////////////////
template class TLinkedClass;
template class TLinkedClassIterator;
///////////////////////////////////////////////////////////////////////////////
// TLinkedClass
///////////////////////////////////////////////////////////////////////////////
template class TLinkedClass
{
public :
friend class TLinkedClassIterator; // So we can access GetNext()
// Exceptions we throw...
class BadIndex {};
// Construction and destruction
TLinkedClass();
virtual ~TLinkedClass();
protected :
// Iteration
typedef TLinkedClassIterator Iterator;
static Iterator Begin();
static Iterator End();
// Iterator interface
T *GetNext() const;
// Derived class interface
const int m_nObjectIndex;
static int GetObjectCount();
static T *GetObjectByIndex(const int nIndex);
private :
TLinkedClass *m_pNext;
static TLinkedClass *s_pListHead; // Head of the list of all objects
static int s_nObjectCount; // How many objects in existance
// It's just not right to copy these around...
// Don't implement them!
TLinkedClass(const TLinkedClass &rhs);
TLinkedClass operator=(const TLinkedClass &rhs);
};
///////////////////////////////////////////////////////////////////////////////
// Static variables
///////////////////////////////////////////////////////////////////////////////
template TLinkedClass *TLinkedClass::s_pListHead = 0;
template int TLinkedClass::s_nObjectCount = 0;
///////////////////////////////////////////////////////////////////////////////
// Construction and destruction
///////////////////////////////////////////////////////////////////////////////
template TLinkedClass::TLinkedClass()
: m_nObjectIndex(s_nObjectCount++)
{
m_pNext = s_pListHead; // Add ourselves to the static list of all
s_pListHead = this; // CTaskBarApplet derived objects.
}
template TLinkedClass::~TLinkedClass()
{
TLinkedClass *pObject = s_pListHead;
TLinkedClass **ppLastLink = &s_pListHead;
while (pObject)
{
if (pObject == this)
{
*ppLastLink = m_pNext;
pObject = 0;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// Iteration
///////////////////////////////////////////////////////////////////////////////
template TLinkedClass::Iterator TLinkedClass::Begin()
{
return Iterator(s_pListHead);
}
template TLinkedClass::Iterator TLinkedClass::End()
{
return Iterator(0);
}
///////////////////////////////////////////////////////////////////////////////
// Iterator interface
///////////////////////////////////////////////////////////////////////////////
template T *TLinkedClass::GetNext() const
{
return (T*)m_pNext;
}
///////////////////////////////////////////////////////////////////////////////
// Derived class interface
///////////////////////////////////////////////////////////////////////////////
template int TLinkedClass::GetObjectCount()
{
return s_nObjectCount;
}
template T *TLinkedClass::GetObjectByIndex(int nIndex)
{
bool found = false;
Iterator it = Begin();
while (!found && it != End())
{
if (it->m_nObjectIndex != nIndex)
{
it++;
}
else
{
found = true;
}
}
if (!found)
{
throw BadIndex();
}
return ⁢
}
///////////////////////////////////////////////////////////////////////////////
// TLinkedClassIterator
///////////////////////////////////////////////////////////////////////////////
template class TLinkedClassIterator
{
public :
// Exceptions we throw...
class NullIterator {};
// Construction and destruction
TLinkedClassIterator(TLinkedClass *pLink);
~TLinkedClassIterator();
// Operators
TLinkedClassIterator &operator++();
TLinkedClassIterator operator++(int);
T* operator->();
T* operator&();
bool operator!=(const TLinkedClassIterator &rhs);
bool operator==(const TLinkedClassIterator &rhs);
private :
// Helper function used by operator++
void Advance();
TLinkedClass *m_pLink;
};
///////////////////////////////////////////////////////////////////////////////
// Construction and destruction
///////////////////////////////////////////////////////////////////////////////
template
TLinkedClassIterator::TLinkedClassIterator(TLinkedClass *pLink)
: m_pLink(pLink)
{
}
template TLinkedClassIterator::~TLinkedClassIterator()
{
m_pLink = 0;
}
///////////////////////////////////////////////////////////////////////////////
// Operators
///////////////////////////////////////////////////////////////////////////////
// Prefix ++: ++it
template
TLinkedClassIterator &TLinkedClassIterator::operator++()
{
Advance();
return *this;
}
// Postfix ++: it++
template
TLinkedClassIterator TLinkedClassIterator::operator++(int)
{
TLinkedClassIterator oldThis = *this;
Advance();
return oldThis;
}
template
T* TLinkedClassIterator::operator->()
{
// Defer the work to operator&
return &(*this);
}
template
T* TLinkedClassIterator::operator&()
{
if (!m_pLink)
{
throw NullIterator();
}
return (T*)m_pLink;
}
template
bool TLinkedClassIterator::operator!=(const TLinkedClassIterator &rhs)
{
return !(*this == rhs);
}
template
bool TLinkedClassIterator::operator==(const TLinkedClassIterator &rhs)
{
return (m_pLink == rhs.m_pLink);
}
///////////////////////////////////////////////////////////////////////////////
// Helper function for operator ++
///////////////////////////////////////////////////////////////////////////////
template
void TLinkedClassIterator::Advance()
{
if (m_pLink)
{
m_pLink = m_pLink->GetNext();
}
}
///////////////////////////////////////////////////////////////////////////////
// Namespace: JetByteTools
///////////////////////////////////////////////////////////////////////////////
} // End of namespace JetByteTools
#endif // __LINKED_CLASS__
///////////////////////////////////////////////////////////////////////////////
// End of file
///////////////////////////////////////////////////////////////////////////////