00001 // LICENSE: (Please see the file COPYING for details) 00002 // 00003 // NUS - Nemesis Utilities System: A C++ application development framework 00004 // Copyright (C) 2006, 2008 Otavio Rodolfo Piske 00005 // 00006 // This file is part of NUS 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Lesser General Public 00010 // License as published by the Free Software Foundation version 2.1 00011 // of the License. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Lesser General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Lesser General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 // 00022 #ifndef NLIST_HPP 00023 #define NLIST_HPP 00024 00035 template<typename T> 00036 class NList { 00037 public: 00038 class iterator; 00039 00043 typedef const iterator const_iterator; 00044 00048 NList(void); 00049 00053 NList(const T &val); 00054 00058 NList(const NList<T> &other); 00059 00064 virtual ~NList(void); 00065 00070 nuint64 count(void) const; 00071 00080 nuint64 count(const T &obj) const; 00081 00082 00088 nuint64 size(void) const; 00093 bool isEmpty(void) const; 00094 00100 NList<T> &append(const T &val); 00101 00109 NList<T> &insert(const T &val, nuint64 pos); 00110 00117 NList<T> &removeAt(nuint64 pos); 00118 00125 const T &at(nuint64 pos) const; 00126 00133 T value(nuint64 pos) const; 00134 00139 T &first(void); 00140 00145 T &last(void); 00146 00152 T takeFirst(void); 00153 00159 T takeLast(void); 00160 00167 T takeAt(nuint64 pos); 00168 00172 void clear(void); 00173 00178 NList<T> ©(const NList<T> &other); 00179 00184 bool hasNext(void) const; 00185 00190 bool hasPrevious(void) const; 00191 00196 bool contains(const T &val) const; 00197 00203 NList<T> &operator=(const NList<T> &rhs); 00204 00205 00212 iterator begin(void); 00213 00220 const_iterator constBegin(void) const; 00221 00228 iterator end(void); 00229 00236 const_iterator constEnd(void) const; 00237 00238 protected: 00239 mutable NListNode<T> *m_first; 00240 mutable NListNode<T> *m_node; 00242 nuint64 m_count; 00247 void gotoFirst() const; 00248 00253 void gotoPos(nuint64 pos) const; 00254 }; 00255 00256 template<typename T> 00257 NList<T>::NList(void) 00258 : m_first(NULL), 00259 m_node(NULL), 00260 m_count(0) 00261 { 00262 00263 } 00264 00265 00266 template<typename T> 00267 NList<T>::NList(const T &val) 00268 : m_first(NULL), 00269 m_node(NULL), 00270 m_count(0) 00271 { 00272 append(val); 00273 } 00274 00275 00276 template<typename T> 00277 NList<T>::NList(const NList<T> &other) 00278 : m_first(NULL), 00279 m_node(NULL), 00280 m_count(0) 00281 { 00282 copy(other); 00283 } 00284 00285 00286 template<typename T> 00287 NList<T>::~NList(void) { 00288 clear(); 00289 } 00290 00291 00292 template<typename T> 00293 bool NList<T>::isEmpty(void) const { 00294 if (m_count == 0) { 00295 return true; 00296 } 00297 00298 return false; 00299 } 00300 00301 00302 template<typename T> 00303 nuint64 NList<T>::count(void) const { 00304 return m_count; 00305 } 00306 00307 template<typename T> 00308 nuint64 NList<T>::count(const T &obj) const { 00309 nuint64 ret = 0; 00310 00311 gotoFirst(); 00312 for (nint32 i = 0; i < size(); i++) { 00313 if (obj == at(i)) { 00314 ret++; 00315 } 00316 } 00317 00318 return ret; 00319 } 00320 00321 00322 template<typename T> 00323 nuint64 NList<T>::size(void) const { 00324 return count(); 00325 } 00326 00327 00328 template<typename T> 00329 NList<T> &NList<T>::append(const T &val) { 00330 NListNode<T> *node = NULL; 00331 00332 node = new NListNode<T>; 00333 node->data = val; 00334 00335 if (isEmpty()) { 00336 m_first = node; 00337 } 00338 else { 00339 m_node->next = node; 00340 node->previous = m_node; 00341 } 00342 m_node = node; 00343 m_count++; 00344 00345 return *this; 00346 } 00347 00348 00349 template<typename T> 00350 void NList<T>::gotoFirst(void) const { 00351 m_node = m_first; 00352 } 00353 00354 00355 template<typename T> 00356 void NList<T>::gotoPos(nuint64 pos) const { 00357 00358 assert(pos < size()); 00359 00360 gotoFirst(); 00361 for (nuint64 i = 0; i < pos; i++) { 00362 if (m_node && m_node->next) { 00363 m_node = m_node->next; 00364 } 00365 } 00366 } 00367 00368 00369 template<typename T> 00370 NList<T> &NList<T>::insert(const T &val, nuint64 pos) { 00371 NListNode<T> *node = NULL; 00372 00373 gotoPos(pos); 00374 node = new NListNode<T>; 00375 node->data = val; 00376 00377 if (!isEmpty()) { 00378 node->previous = m_node->previous; 00379 m_node->previous = node; 00380 00381 // Sets the 'next' pointer, only if it exists. 00382 if (node->previous) { 00383 node->previous->next = node; 00384 } 00385 node->next = m_node; 00386 } 00387 00388 m_node = node; 00389 m_count++; 00390 00391 return *this; 00392 } 00393 00394 00395 template<typename T> 00396 NList<T> &NList<T>::removeAt(nuint64 pos) { 00397 NListNode<T> *previous = NULL; 00398 NListNode<T> *next = NULL; 00399 00400 gotoPos(pos); 00401 00402 previous = m_node->previous; 00403 next = m_node->next; 00404 00405 delete m_node; 00406 m_node = NULL; 00407 00408 if (previous) { 00409 previous->next = next; 00410 m_node = previous; 00411 } 00412 else { 00413 m_first = next; 00414 m_node = m_first; 00415 } 00416 00417 if (next) { 00418 next->previous = previous; 00419 m_node = next; 00420 } 00421 00422 m_count--; 00423 if (count() == 0) { 00424 m_first = NULL; 00425 m_node = NULL; 00426 } 00427 00428 return *this; 00429 } 00430 00431 00432 template<typename T> 00433 const T &NList<T>::at(nuint64 pos) const { 00434 gotoPos(pos); 00435 00436 return m_node->data; 00437 } 00438 00439 00440 template<typename T> 00441 T NList<T>::value(nuint64 pos) const { 00442 T ret; 00443 00444 this->gotoPos(pos); 00445 ret = m_node->data; 00446 00447 return ret; 00448 } 00449 00450 00451 template<typename T> 00452 T &NList<T>::first(void) { 00453 gotoPos(0); 00454 return m_node->data; 00455 } 00456 00457 00458 template<typename T> 00459 T &NList<T>::last(void) { 00460 gotoPos(size() - 1); 00461 return m_node->data; 00462 } 00463 00464 00465 template<typename T> 00466 void NList<T>::clear(void) { 00467 for (nint32 i = size() - 1; i >= 0; i--) { 00468 removeAt(i); 00469 } 00470 00471 } 00472 00473 00474 template<typename T> 00475 NList<T> &NList<T>::copy(const NList<T> &other) { 00476 clear(); 00477 for (nuint64 i = 0; i < other.size(); i++) { 00478 append(other.value(i)); 00479 } 00480 00481 return *this; 00482 } 00483 00484 00485 template<typename T> 00486 bool NList<T>::hasNext(void) const { 00487 if (m_node && m_node->next) { 00488 return true; 00489 } 00490 00491 return false; 00492 } 00493 00494 00495 template<typename T> 00496 bool NList<T>::hasPrevious(void) const { 00497 if (m_node && m_node->previous) { 00498 return true; 00499 } 00500 00501 return false; 00502 } 00503 00504 00505 template <typename T> 00506 T NList<T>::takeFirst(void) { 00507 return takeAt(0); 00508 } 00509 00510 00511 template <typename T> 00512 T NList<T>::takeLast(void) { 00513 return takeAt(size() - 1); 00514 } 00515 00516 00517 template<typename T> 00518 T NList<T>::takeAt(nuint64 pos) { 00519 T ret; 00520 00521 ret = value(pos); 00522 removeAt(pos); 00523 return ret; 00524 } 00525 00526 00527 template<typename T> 00528 NList<T> &NList<T>::operator=(const NList<T> &rhs) { 00529 return copy(rhs); 00530 } 00531 00532 00533 template <typename T> 00534 bool NList<T>::contains(const T &val) const { 00535 T tmp; 00536 00537 for (nuint64 i = 0; i < size(); i++) { 00538 tmp = at(i); 00539 if (val == tmp) { 00540 return true; 00541 } 00542 } 00543 00544 return false; 00545 } 00546 00547 00551 template <typename T> 00552 class NList<T>::iterator { 00553 public: 00558 iterator(NListNode<T> *node) 00559 : m_node(node) 00560 {} 00561 00566 iterator(const iterator &other): m_node(NULL) { 00567 m_node = other.m_node; 00568 } 00569 00573 ~iterator(void) {} 00574 00580 iterator &operator=(const iterator &rhs) { 00581 m_node = rhs.m_node; 00582 00583 return *this; 00584 } 00585 00586 00592 bool operator!=(const iterator &rhs) const { 00593 if (!m_node || !rhs.m_node) { 00594 if (!m_node && !rhs.m_node) { 00595 return false; 00596 } 00597 00598 return true; 00599 } 00600 00601 if (m_node->data != rhs.m_node->data) { 00602 return true; 00603 } 00604 00605 return false; 00606 } 00607 00608 00614 bool operator==(const iterator &rhs) const { 00615 if (!m_node || !rhs.m_node) { 00616 if (!m_node && !rhs.m_node) { 00617 return true; 00618 } 00619 00620 return false; 00621 } 00622 00623 if (m_node->data == rhs.m_node->data) { 00624 return true; 00625 } 00626 00627 return false; 00628 } 00629 00634 iterator operator++(int) { 00635 iterator tmp(*this); 00636 00637 inc(); 00638 return tmp; 00639 } 00640 00645 const iterator &operator++(void) const { 00646 iterator tmp(*this); 00647 00648 m_node = m_node->next; 00649 return *this; 00650 } 00651 00652 00657 const iterator operator++(int) const { 00658 iterator tmp(*this); 00659 00660 ++(*this); 00661 return tmp; 00662 } 00663 00668 T& operator*(void) { 00669 return m_node->data; 00670 } 00671 00676 const T& operator*(void) const { 00677 return m_node->data; 00678 } 00679 00684 T* operator->(void) { 00685 return &m_node->data; 00686 } 00687 00692 const T* operator->(void) const { 00693 return &m_node->data; 00694 } 00695 00696 00697 private: 00698 mutable NListNode<T> *m_node; 00699 00700 iterator inc(void) { 00701 iterator tmp(*this); 00702 00703 m_node = m_node->next; 00704 return tmp; 00705 } 00706 }; 00707 00708 00709 template <typename T> 00710 typename NList<T>::iterator NList<T>::begin(void) { 00711 typename NList<T>::iterator i(m_first); 00712 00713 return i; 00714 } 00715 00716 00717 template <typename T> 00718 NLISTITERATOR_CONST NList<T>::constBegin(void) const { 00719 typename NList<T>::const_iterator i(m_first); 00720 00721 return i; 00722 } 00723 00724 00725 template <typename T> 00726 typename NList<T>::iterator NList<T>::end(void) { 00727 return typename NList<T>::iterator(NULL); 00728 } 00729 00730 00731 00732 template <typename T> 00733 NLISTITERATOR_CONST NList<T>::constEnd(void) const { 00734 return typename NList<T>::const_iterator(NULL); 00735 } 00736 00737 #endif // NLIST_HPP