00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef __SEAL_LIST_H__
00030 #define __SEAL_LIST_H__
00031
00032 #include "collection.h"
00033 #include "node.h"
00034 #include "dataptr.h"
00035
00036 namespace seal
00037 {
00038
00042 template <typename T>
00043 class List : public Collection<T>
00044 {
00045 public:
00046
00049 List(void);
00050
00053 virtual void pushBack(const T element) = 0;
00054
00057 virtual void popBack(void) = 0;
00058
00061 virtual void pushFront(const T element) = 0;
00062
00065 virtual void popFront(void) = 0;
00066
00072 virtual void insert(const T element, unsigned int index) = 0;
00073
00078 virtual void remove(unsigned int index) = 0;
00079
00080 };
00081
00082 template <typename T>
00083 List<T>::List(void) : Collection<T>() {}
00084
00087
00090 template <typename T>
00091 class LinkedList : public List<T>
00092 {
00093 public:
00096 class Iterator : public AbstractIterator<T>
00097 {
00098
00099 friend class LinkedList<T>;
00100
00101 public:
00104 Iterator(void) : AbstractIterator<T>(), _firstNodePtr(NULL), _lastNodePtr(NULL)
00105 { _currNodePtr = NULL; }
00106
00109 virtual bool hasNext(void);
00110
00115 virtual T next(void) throw (OutOfBoundsException);
00116
00120 virtual void reset(void);
00121
00122 private:
00125 Iterator(ListNode<T> *fnp, ListNode<T> *lnp) : AbstractIterator<T>(), _firstNodePtr(fnp), _lastNodePtr(lnp)
00126 { _currNodePtr = _firstNodePtr; }
00127
00128 ListNode<T> *_currNodePtr;
00129 ListNode<T> *_firstNodePtr;
00130 ListNode<T> *_lastNodePtr;
00131 };
00132
00133 public:
00136 LinkedList(void);
00137
00140 LinkedList(const LinkedList<T> &l);
00141
00144 virtual ~LinkedList();
00145
00148 virtual bool isEmpty(void) const;
00149
00152 virtual unsigned int size(void) const { return *_sizePtr; }
00153
00158 virtual AbstractIterator<T>* iteratorPtr(void) const
00159 { return new typename LinkedList<T>::Iterator(_firstNodePtr->data, _lastNodePtr->data); }
00160
00164 virtual typename LinkedList<T>::Iterator iterator(void) const
00165 { return typename LinkedList<T>::Iterator(_firstNodePtr->data, _lastNodePtr->data); }
00166
00169 inline virtual void purge(void);
00170
00175 virtual void pushBack(const T element);
00176
00179 virtual void popBack(void);
00180
00185 virtual void pushFront(const T element);
00186
00189 virtual void popFront(void);
00190
00198 virtual void insert(const T element, unsigned int index);
00199
00206 virtual void remove(unsigned int index);
00207
00211 void operator=(const LinkedList<T> &l);
00212
00215 virtual T& first(void) throw (EmptyCollectionException);
00216
00219 virtual T& last(void) throw (EmptyCollectionException);
00220
00223 virtual const T& first(void) const throw (EmptyCollectionException);
00224
00227 virtual const T& last(void) const throw (EmptyCollectionException);
00228
00231 bool contains(const T element) const;
00232
00236 bool removeFirstMatch(const T match);
00237
00242 bool replace(int i, const T element);
00243
00248 bool replaceAll(const T match, const T e);
00249
00254 bool replaceFirst(const T match, const T e);
00255
00256 private:
00257 unsigned int *_sizePtr, *_refCountPtr;
00258 DataPtr< ListNode<T> > *_firstNodePtr;
00259 DataPtr< ListNode<T> > *_lastNodePtr;
00260 };
00261
00263
00265
00266 template <typename T>
00267 LinkedList<T>::LinkedList(void)
00268 : List<T>()
00269 {
00270 _sizePtr = new unsigned int; *_sizePtr = 0;
00271 _refCountPtr = new unsigned int; *_refCountPtr = 1;
00272
00273 _firstNodePtr = new DataPtr< ListNode<T> >();
00274 _firstNodePtr->data = NULL;
00275
00276 _lastNodePtr = new DataPtr< ListNode<T> >();
00277 _lastNodePtr->data = NULL;
00278 }
00279
00280 template <typename T>
00281 LinkedList<T>::LinkedList(const LinkedList<T> &l)
00282 : List<T>(),
00283 _sizePtr(l._sizePtr),
00284 _refCountPtr(l._refCountPtr),
00285 _firstNodePtr(l._firstNodePtr),
00286 _lastNodePtr(l._lastNodePtr)
00287 {
00288 (*_refCountPtr)++;
00289 }
00290
00291 template <typename T>
00292 LinkedList<T>::~LinkedList()
00293 {
00294 if (*_refCountPtr <= 1)
00295 {
00296 delete _sizePtr;
00297 delete _refCountPtr;
00298 delete _firstNodePtr;
00299 delete _lastNodePtr;
00300 }
00301 else
00302 (*_refCountPtr)--;
00303 }
00304
00305 template <typename T>
00306 bool LinkedList<T>::isEmpty() const
00307 {
00308 if (*_sizePtr == 0)
00309 return true;
00310 else
00311 return false;
00312 }
00313
00314 template <typename T>
00315 void LinkedList<T>::purge(void)
00316 {
00317 while (*_sizePtr != 0)
00318 popBack();
00319 }
00320
00321 template <typename T>
00322 void LinkedList<T>::pushBack(const T element)
00323 {
00324
00325 ListNode<T> *newNodePtr = new ListNode<T>();
00326 newNodePtr->data = element;
00327
00328 if (*_sizePtr == 0)
00329 {
00330
00331
00332
00333 _firstNodePtr->data = newNodePtr;
00334 _lastNodePtr->data = newNodePtr;
00335 }
00336 else
00337 {
00338
00339
00340 _lastNodePtr->data->nextPtr = newNodePtr;
00341
00342
00343
00344 newNodePtr->prevPtr = _lastNodePtr->data;
00345
00346
00347
00348 _lastNodePtr->data = newNodePtr;
00349 }
00350
00351
00352
00353 (*_sizePtr)++;
00354 }
00355
00356 template <typename T>
00357 void LinkedList<T>::popBack()
00358 {
00359 if (*_sizePtr == 0)
00360 return;
00361
00362 if (*_sizePtr == 1)
00363 {
00364 delete _lastNodePtr->data;
00365 _lastNodePtr->data = NULL;
00366 _firstNodePtr->data = NULL;
00367 }
00368 else
00369 {
00370 _lastNodePtr->data = _lastNodePtr->data->prevPtr;
00371 delete _lastNodePtr->data->nextPtr;
00372 _lastNodePtr->data->nextPtr = NULL;
00373 }
00374
00375
00376
00377 (*_sizePtr)--;
00378 }
00379
00380 template <typename T>
00381 void LinkedList<T>::pushFront(const T element)
00382 {
00383
00384 ListNode<T> *newNodePtr = new ListNode<T>();
00385 newNodePtr->data = element;
00386
00387 if (*_sizePtr == 0)
00388 {
00389
00390
00391
00392 _firstNodePtr->data = newNodePtr;
00393 _lastNodePtr->data = newNodePtr;
00394 }
00395 else
00396 {
00397
00398
00399 _firstNodePtr->data->prevPtr = newNodePtr;
00400
00401
00402
00403 newNodePtr->nextPtr = _firstNodePtr->data;
00404
00405
00406
00407 _firstNodePtr->data = newNodePtr;
00408 }
00409
00410
00411
00412 (*_sizePtr)++;
00413 }
00414
00415 template <typename T>
00416 void LinkedList<T>::popFront()
00417 {
00418 if (*_sizePtr == 0)
00419 return;
00420
00421 if (*_sizePtr == 1)
00422 {
00423 delete _firstNodePtr->data;
00424 _lastNodePtr->data = NULL;
00425 _firstNodePtr->data = NULL;
00426 }
00427 else
00428 {
00429 _firstNodePtr->data = _firstNodePtr->data->nextPtr;
00430 delete _firstNodePtr->data->prevPtr;
00431 _firstNodePtr->data->prevPtr = NULL;
00432 }
00433
00434
00435
00436 (*_sizePtr)--;
00437 }
00438
00439 template <typename T>
00440 void LinkedList<T>::insert(const T element, unsigned int index)
00441 {
00442 if (index == 0)
00443 pushFront(element);
00444 else if (index >= *_sizePtr)
00445 pushBack(element);
00446 else
00447 {
00448 ListNode<T> *nextNodePtr = _firstNodePtr->data;
00449 for (int i = 0; i < index; i++)
00450 nextNodePtr = nextNodePtr->nextPtr;
00451
00452 ListNode<T> *newNodePtr = new ListNode<T>();
00453 newNodePtr->data = element;
00454
00455 newNodePtr->nextPtr = nextNodePtr;
00456 newNodePtr->prevPtr = nextNodePtr->prevPtr;
00457 newNodePtr->prevPtr->nextPtr = newNodePtr;
00458 newNodePtr->nextPtr->prevPtr = newNodePtr;
00459
00460 (*_sizePtr)++;
00461 }
00462 }
00463
00464 template <typename T>
00465 void LinkedList<T>::remove(unsigned int index)
00466 {
00467 if (index >= *_sizePtr)
00468 return;
00469 else if (index == 0)
00470 popFront();
00471 else if (index == (*_sizePtr)-1)
00472 popBack();
00473 else
00474 {
00475 ListNode<T> *listNodePtr = _firstNodePtr->data;
00476 for (int i = 0; i < index; i++)
00477 listNodePtr = listNodePtr->nextPtr;
00478
00479
00480 listNodePtr->prevPtr->nextPtr = listNodePtr->nextPtr;
00481 listNodePtr->nextPtr->prevPtr = listNodePtr->prevPtr;
00482
00483 delete listNodePtr;
00484
00485 (*_sizePtr)--;
00486 }
00487 }
00488
00489 template <typename T>
00490 void LinkedList<T>::operator=(const LinkedList<T> &rhs)
00491 {
00492 if (_refCountPtr == rhs._refCountPtr)
00493 return;
00494
00495 if (rhs._sizePtr == _sizePtr)
00496 return;
00497
00498 if (*_refCountPtr > 1)
00499 {
00500 (*_refCountPtr)--;
00501
00502 _refCountPtr = rhs._refCountPtr;
00503 _sizePtr = rhs._sizePtr;
00504 _firstNodePtr = rhs._firstNodePtr;
00505 _lastNodePtr = rhs._lastNodePtr;
00506
00507 (*_refCountPtr)++;
00508 }
00509 else
00510 {
00511 delete _refCountPtr;
00512 delete _sizePtr;
00513 delete _firstNodePtr;
00514 delete _lastNodePtr;
00515
00516 _refCountPtr = rhs._refCountPtr;
00517 _sizePtr = rhs._sizePtr;
00518 _firstNodePtr = rhs._firstNodePtr;
00519 _lastNodePtr = rhs._lastNodePtr;
00520
00521 (*_refCountPtr)++;
00522 }
00523 }
00524
00525 template <typename T>
00526 const T& LinkedList<T>::first(void) const throw (EmptyCollectionException)
00527 {
00528 if (*_sizePtr == 0)
00529 throw EmptyCollectionException();
00530
00531 return _firstNodePtr->data->data;
00532 }
00533
00534 template <typename T>
00535 const T& LinkedList<T>::last(void) const throw (EmptyCollectionException)
00536 {
00537 if (*_sizePtr == 0)
00538 throw EmptyCollectionException();
00539
00540 return _lastNodePtr->data->data;
00541 }
00542
00543 template <typename T>
00544 T& LinkedList<T>::first(void) throw (EmptyCollectionException)
00545 {
00546 if (*_sizePtr == 0)
00547 throw EmptyCollectionException();
00548
00549 return _firstNodePtr->data->data;
00550 }
00551
00552 template <typename T>
00553 T& LinkedList<T>::last(void) throw (EmptyCollectionException)
00554 {
00555 if (*_sizePtr == 0)
00556 throw EmptyCollectionException();
00557
00558 return _lastNodePtr->data->data;
00559 }
00560
00561 template <typename T>
00562 bool LinkedList<T>::contains (const T e) const
00563 {
00564 ListNode<T> *nodePtr = _firstNodePtr->data;
00565 while (nodePtr != NULL)
00566 {
00567 if (nodePtr->data == e)
00568 break;
00569
00570 nodePtr = nodePtr->nextPtr;
00571 }
00572
00573 if (nodePtr == NULL)
00574 return false;
00575 else
00576 return true;
00577 }
00578
00579 template <typename T>
00580 bool LinkedList<T>::removeFirstMatch(const T e)
00581 {
00582 ListNode<T> *nodePtr = _firstNodePtr->data;
00583 while (nodePtr != NULL)
00584 {
00585 if (nodePtr->data == e)
00586 break;
00587
00588 nodePtr = nodePtr->nextPtr;
00589 }
00590
00591 if (nodePtr == NULL)
00592 return false;
00593 else
00594 {
00595 if (nodePtr->prevPtr == NULL)
00596 popFront();
00597 else if (nodePtr->nextPtr == NULL)
00598 popBack();
00599 else
00600 {
00601
00602 nodePtr->prevPtr->nextPtr = nodePtr->nextPtr;
00603 nodePtr->nextPtr->prevPtr = nodePtr->prevPtr;
00604
00605 delete nodePtr;
00606
00607 (*_sizePtr)--;
00608 }
00609
00610 return true;
00611 }
00612 }
00613
00614 template <typename T>
00615 bool LinkedList<T>::replace(int i, const T element)
00616 {
00617 if (i < 0 || i >= *_sizePtr)
00618 return false;
00619
00620 ListNode<T> *nodePtr = _firstNodePtr->data;
00621 for (int l = 0; l < i; l++)
00622 nodePtr = nodePtr->nextPtr;
00623
00624 nodePtr->data = element;
00625 return true;
00626 }
00627
00628 template <typename T>
00629 bool LinkedList<T>::replaceAll(const T element, const T match)
00630 {
00631 int matchCount = 0;
00632 ListNode<T> *nodePtr = _firstNodePtr->data;
00633
00634 while (nodePtr != NULL)
00635 {
00636 if (nodePtr->data == element)
00637 {
00638 nodePtr->data = match;
00639 matchCount++;
00640 }
00641
00642 nodePtr = nodePtr->nextPtr;
00643 }
00644
00645 if (matchCount > 0)
00646 return true;
00647 else
00648 return false;
00649 }
00650
00651 template <typename T>
00652 bool LinkedList<T>::replaceFirst(const T element, const T match)
00653 {
00654 ListNode<T> *nodePtr = _firstNodePtr->data;
00655
00656 while (nodePtr != NULL)
00657 {
00658 if (nodePtr->data == element)
00659 {
00660 nodePtr->data = match;
00661 return true;
00662 }
00663
00664 nodePtr = nodePtr->nextPtr;
00665 }
00666
00667 return false;
00668 }
00669
00671
00673
00674 template <typename T>
00675 bool LinkedList<T>::Iterator::hasNext(void)
00676 {
00677 if (_currNodePtr != NULL)
00678 return true;
00679 else
00680 return false;
00681 }
00682
00683 template <typename T>
00684 T LinkedList<T>::Iterator::next(void) throw (OutOfBoundsException)
00685 {
00686 if (_currNodePtr == NULL)
00687 throw OutOfBoundsException();
00688 else
00689 {
00690 T data = _currNodePtr->data;
00691 _currNodePtr = _currNodePtr->nextPtr;
00692
00693 return data;
00694 }
00695 }
00696
00697 template <typename T>
00698 void LinkedList<T>::Iterator::reset(void)
00699 {
00700 _currNodePtr = _firstNodePtr;
00701 }
00702
00703 }
00704
00705 #endif // __SEAL_LIST_H__
00706