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 
///////////////////////////////////////////////////////////////////////////////