TDPList.hh
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:6k
源码类别:

DVD

开发平台:

Unix_Linux

  1. // -*- C++ -*-
  2. /*
  3.    File: TDPList.hh
  4.    Template based Double linked Pointer List
  5.    By Alex Th. de Jong
  6.    March 1995
  7. */
  8. #pragma interface
  9. #ifndef __TDPList_hh__
  10. #define __TDPList_hh__
  11. // Error codes:
  12. #define E_TDP_NOERROR     0
  13. #define E_TDP_OUTOFRANGE  1
  14. #define E_TDP_NULL        2
  15. /* 
  16.    Template item class which is a placeholder for the 
  17.    pointer to the actual item stored in the list
  18. */
  19. template<class TDPItem>
  20. class TDPListItem {
  21.  protected:
  22.   friend class TDPList<TDPItem>;
  23.   friend class TDPListIter<TDPItem>;
  24.   TDPItem* item;
  25.   TDPListItem<TDPItem>* next;
  26.   TDPListItem<TDPItem>* prev; 
  27.   TDPListItem(TDPItem* ti){ item=ti, next=0, prev=0; }
  28.   ~TDPListItem(){ delete item; }
  29. };
  30. /* 
  31.    Template for a list iterator
  32. */
  33. template <class TDPItem>
  34. class TDPListIter {
  35.  protected:
  36.   const TDPList<TDPItem>* ptl;
  37.   TDPListItem<TDPItem>* pti;
  38.   int dn;
  39.  public:
  40.   TDPListIter(const TDPList<TDPItem>& tl){ ptl=&tl; pti=ptl->head; dn=(pti==0) ? 1 : 0; }
  41.   TDPListIter(){ ptl=0, pti=0, dn=0; }
  42.   int set(const TDPList<TDPItem>& tl){ ptl=&tl; pti=ptl->head; return (dn=(pti==0) ? 1 :0); }
  43.   int reset() { pti=(ptl!=0) ? ptl->head : 0;  return (dn=(pti==0) ? 1 :0); }
  44.   int resetToTail() { pti=(ptl!=0) ? ptl->tail : 0; return (dn=(pti==0) ? 1 :0); }
  45.   int done(){ return dn; }
  46.   TDPListIter& operator++(){ if ((pti=pti->next)==0) dn=1; return *this; }  // prefix
  47.   TDPListIter& operator--(){ if ((pti=pti->prev)==0) dn=1; return *this; }
  48.   TDPListIter& operator++(int){ if ((pti=pti->next)==0) dn=1; return *this; }  // postfix
  49.   TDPListIter& operator--(int){ if ((pti=pti->prev)==0) dn=1; return *this; }
  50.   TDPItem* value(){ return pti->item; }
  51. };
  52. /* 
  53.    Template list
  54.    
  55.    N.B. An iterator should be used to access list items
  56. */
  57. template<class TDPItem>
  58. class TDPList {
  59.  protected:
  60.   friend class TDPListIter<TDPItem>;
  61.   TDPListItem<TDPItem>* head;
  62.   TDPListItem<TDPItem>* tail;
  63.   int size;
  64.  public:
  65. // Default constructor
  66.   TDPList() { size=0, head=0, tail=0; }
  67. // Constructor that takes the first item for the list
  68.   TDPList(TDPItem* ti) { head=tail=new TDPListItem<TDPItem>(ti); size=1; }
  69. // Destructor
  70.   ~TDPList() { clear(); }
  71. // Inserts an item in the list before the item at the given index
  72.   int insert(int, TDPItem*);
  73. // Appends an item after the item at the given index
  74.   int append(int, TDPItem*);
  75. // Appends an item to the end of the list
  76.   int append(TDPItem*);
  77. // Removes the item at the given index
  78.   int remove(int);
  79. // Removes the item at tail
  80.   int removeTail();
  81. // Removes the item with the corresponding item pointer
  82.   int remove(TDPItem*);
  83. // Return the number of items in list
  84.   int length() const { return size; }
  85. // Clears the list and resets its members
  86.   void clear(); 
  87. };
  88. /* 
  89.    Implementation of template list member functions
  90.    N.B. these functions should be placed here in order
  91.    for the compiler to generate code when templates are
  92.    initiated. 
  93. */
  94. #ifdef TEMPLATE_IMPL
  95. template <class TDPItem>
  96. int TDPList<TDPItem>::remove(int index){
  97.   if (index>=0 && index<size){
  98.     TDPListItem<TDPItem>* tli=head;
  99.     for (int i=0; i<index; i++) tli=tli->next;
  100.     if (tli!=0){
  101.       if (tli->prev!=0) tli->prev->next=tli->next;
  102.       else head=tli->next;
  103.       if (tli->next!=0) tli->next->prev=tli->prev;
  104.       else tail=tli->prev;
  105.       delete tli;
  106.       size--;
  107.       return E_TDP_NOERROR;
  108.     }
  109.   }
  110.   return E_TDP_OUTOFRANGE;
  111. }
  112. template <class TDPItem>
  113. int TDPList<TDPItem>::removeTail(){
  114.   if (tail){
  115.     TDPListItem<TDPItem>* tli=tail;
  116.     tail=tail->prev;
  117.     if (tail) tail->next=0;
  118.     else head=0;
  119.     tli->prev=0;
  120.     delete tli;
  121.     size--;
  122.     return E_TDP_NOERROR;
  123.   }
  124.   return E_TDP_OUTOFRANGE;
  125. }
  126. template <class TDPItem>
  127. int TDPList<TDPItem>::remove(TDPItem* ti){
  128.   if (ti==0) return E_TDP_NULL;
  129.   else {
  130.     TDPListItem<TDPItem>* tli=head;
  131.     while (tli!=0){
  132.       if (tli->item==ti){
  133.         if (tli->prev!=0) tli->prev->next=tli->next;
  134.         else head=tli->next;
  135.         if (tli->next!=0) tli->next->prev=tli->prev;
  136.         else tail=tli->prev;
  137.         delete tli;
  138.         size--;
  139.         return E_TDP_NOERROR;
  140.       }
  141.       tli=tli->next;
  142.     }
  143.   }
  144.   return E_TDP_OUTOFRANGE;
  145. }
  146. template <class TDPItem>
  147. int TDPList<TDPItem>::insert(int index, TDPItem* ti){
  148.   if (ti==0) return E_TDP_NULL; 
  149.   if ((index>0)&&(index<size)){
  150.     TDPListItem<TDPItem>* tli=head;
  151.     TDPListItem<TDPItem>* tliNew=new TDPListItem<TDPItem>(ti);
  152.     for (int i=0; i<index; i++) tli=tli->next;
  153.     if (tli->prev!=0) tli->prev->next=tliNew;
  154.     else head=tliNew;
  155.     tliNew->prev=tli->prev;
  156.     tliNew->next=tli;
  157.     tli->prev = tliNew;
  158.     size++;
  159.     return E_TDP_NOERROR;
  160.   }
  161.   return E_TDP_OUTOFRANGE;
  162. }
  163. template <class TDPItem>
  164. int TDPList<TDPItem>::append(int index, TDPItem* ti){
  165.   if (ti==0) return E_TDP_NULL; 
  166.   if ((index>=0)&&(index<size)){
  167.     TDPListItem<TDPItem>* tli=head;
  168.     TDPListItem<TDPItem>* tliNew=new TDPListItem<TDPItem>(ti);
  169.     for (int i=0; i<index; i++) tli=tli->next;
  170.     if (tli->next!=0) tli->next->prev=tliNew;
  171.     else tail=tliNew;
  172.     tliNew->next=tli->next;
  173.     tliNew->prev=tli;
  174.     tli->next=tliNew;
  175.     size++;
  176.     return E_TDP_NOERROR;
  177.   }
  178.   if (index==size) return append(ti);
  179.   return E_TDP_OUTOFRANGE;
  180. }
  181. template <class TDPItem>
  182. int TDPList<TDPItem>::append(TDPItem* ti){
  183.   if (ti==0) return E_TDP_NULL; 
  184.   TDPListItem<TDPItem>* tli=new TDPListItem<TDPItem>(ti);
  185.   if (tail!=0){
  186.     tail->next=tli;
  187.     tli->prev=tail;
  188.     tail=tail->next;
  189.   }
  190.   else head=tail=tli;
  191.   size++;  
  192.   return E_TDP_NOERROR;
  193. }
  194. template <class TDPItem>
  195. void TDPList<TDPItem>::clear(){
  196.   for (TDPListItem<TDPItem>* tli=tail; tli!=0; tli=tli->prev) delete tli->next;
  197.   delete head;
  198.   head=tail=0;
  199.   size=0;
  200. }
  201. #endif
  202. #endif