Simple Application Framework
1
|
00001 /* 00002 This file is part of Simple Application Framework (Saf) library. 00003 Copyright (C) 2010 - 2012 Ondrej Danek <ondrej.danek@gmail.com> 00004 00005 This library is free software: you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published 00007 by the Free Software Foundation, either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 Saf is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with Simple Application Framework library. If not, 00017 see <http://www.gnu.org/licenses/>. 00018 */ 00019 00028 #ifndef SAF_COLLECTION_FORWARDLIST_H 00029 #define SAF_COLLECTION_FORWARDLIST_H 00030 00031 #include "../Type.h" 00032 #include "../Mem/Alloc.h" 00033 #include "../Algo/Swap.h" 00034 #include "../Type/IteratorCategory.h" 00035 00036 namespace Saf 00037 { 00038 namespace Collection 00039 { 00074 template <class T> 00075 class ForwardList 00076 { 00077 protected: 00078 typedef ForwardList<T> MyType; 00079 00080 protected: 00082 class Node 00083 { 00084 public: 00086 Node *m_next; 00088 T m_val; 00089 00090 public: 00092 Node(const T& val) 00093 : m_val(val) 00094 {} 00095 }; 00096 00097 public: 00099 class ConstIterator 00100 { 00101 public: 00102 typedef T ValType; 00103 typedef Type::IteratorCategory::ForwardCategory CategoryType; 00104 00105 protected: 00107 Node *m_node; 00108 00109 // The list can access the protected members 00110 friend class ForwardList<T>; 00111 00112 public: 00114 ConstIterator() 00115 {} 00116 00118 explicit ConstIterator(Node *node) 00119 : m_node(node) 00120 {} 00121 00123 ConstIterator(const ConstIterator& iter) 00124 : m_node(iter.m_node) 00125 {} 00126 00128 ConstIterator& operator=(const ConstIterator& iter) 00129 { 00130 m_node = iter.m_node; 00131 return *this; 00132 } 00133 00135 const T& operator*() const 00136 { 00137 return m_node->m_val; 00138 } 00139 00141 const T* operator->() const 00142 { 00143 return &m_node->m_val; 00144 } 00145 00147 ConstIterator& operator++() 00148 { 00149 m_node = m_node->m_next; 00150 return *this; 00151 } 00152 00154 ConstIterator operator++(int) 00155 { 00156 ConstIterator ci(*this); 00157 ++(*this); 00158 return ci; 00159 } 00160 00162 bool operator==(const ConstIterator& ci) 00163 { 00164 return (m_node == ci.m_node); 00165 } 00166 00168 bool operator!=(const ConstIterator& ci) 00169 { 00170 return (m_node != ci.m_node); 00171 } 00172 }; 00173 00175 class Iterator 00176 : public ConstIterator 00177 { 00178 public: 00180 Iterator() 00181 : ConstIterator() 00182 {} 00183 00185 explicit Iterator(Node *node) 00186 : ConstIterator(node) 00187 {} 00188 00190 Iterator(const Iterator& iter) 00191 : ConstIterator(iter) 00192 {} 00193 00195 Iterator& operator=(const Iterator& iter) 00196 { 00197 ConstIterator::operator=(iter); 00198 return *this; 00199 } 00200 00202 T& operator*() const 00203 { 00204 return this->m_node->m_val; 00205 } 00206 00208 T* operator->() const 00209 { 00210 return &this->m_node->m_val; 00211 } 00212 00214 Iterator& operator++() 00215 { 00216 this->m_node = this->m_node->m_next; 00217 return *this; 00218 } 00219 00221 Iterator operator++(int) 00222 { 00223 Iterator it(*this); 00224 ++(*this); 00225 return it; 00226 } 00227 }; 00228 00229 private: 00235 Node *m_head; 00237 Node *m_last; 00238 00239 private: 00241 void Init() 00242 { 00243 Mem::OperatorNew(m_head, SAF_SOURCE_LOCATION); 00244 m_head->m_next = nullptr; 00245 m_last = m_head; 00246 } 00247 00248 public: 00250 ForwardList() 00251 { 00252 Init(); 00253 } 00254 00256 ForwardList(const MyType& list) 00257 { 00258 Init(); 00259 *this = list; 00260 } 00261 00263 ~ForwardList() 00264 { 00265 Free(); 00266 Mem::OperatorDelete(m_head); 00267 } 00268 00270 void Free() 00271 { 00272 Node *n = m_head->m_next, *nprev; 00273 00274 while (n != nullptr) 00275 { 00276 nprev = n; 00277 n = n->m_next; 00278 Mem::Delete(nprev); 00279 } 00280 00281 m_head->m_next = nullptr; 00282 m_last = m_head; 00283 } 00284 00286 MyType& operator=(const MyType& l) 00287 { 00288 if (&l != this) 00289 { 00290 Free(); 00291 00292 // Copy 00293 Node *nprev = m_head, *ndst, *nsrc = l.m_head->m_next; 00294 00295 while (nsrc != nullptr) 00296 { 00297 ndst = SAF_NEW Node(nsrc->m_val); 00298 nprev->m_next = ndst; 00299 nprev = ndst; 00300 nsrc = nsrc->m_next; 00301 } 00302 00303 nprev->m_next = nullptr; 00304 m_last = nprev; 00305 } 00306 00307 return *this; 00308 } 00309 00315 MyType& Swap(MyType& fl) 00316 { 00317 Algo::Swap(m_head, fl.m_head); 00318 Algo::Swap(m_last, fl.m_last); 00319 00320 return *this; 00321 } 00322 00328 bool IsEmpty() const 00329 { 00330 return (m_head->m_next == nullptr); 00331 } 00332 00339 MyType& PushFront(const T &val) 00340 { 00341 InsertAfter(BeforeBegin(), val); 00342 return *this; 00343 } 00344 00351 MyType& PushBack(const T &val) 00352 { 00353 InsertAfter(Back(), val); 00354 return *this; 00355 } 00356 00363 MyType& PopFront() 00364 { 00365 if (!IsEmpty()) 00366 { 00367 EraseAfter(BeforeBegin()); 00368 } 00369 00370 return *this; 00371 } 00372 00381 Iterator InsertAfter(Iterator iter, const T &val) 00382 { 00383 Node *b = iter.m_node, *n = SAF_NEW Node(val); 00384 00385 n->m_next = b->m_next; 00386 b->m_next = n; 00387 00388 if (b == m_last) 00389 { 00390 m_last = n; 00391 } 00392 00393 return Iterator(n); 00394 } 00395 00404 Iterator EraseAfter(Iterator iter) 00405 { 00406 Node *n = iter.m_node, *nsucc = n->m_next; 00407 00408 if (nsucc == m_last) 00409 { 00410 m_last = n; 00411 } 00412 00413 n->m_next = nsucc->m_next; 00414 Mem::Delete(nsucc); 00415 00416 return Iterator(n->m_next); 00417 } 00418 00428 MyType& SpliceAfter(Iterator el, MyType& list) 00429 { 00430 return SpliceAfter(el, list, list.BeforeBegin(), list.Back()); 00431 } 00432 00441 MyType& SpliceAfter(Iterator el, MyType& list, Iterator first) 00442 { 00443 Iterator last = first; 00444 return SpliceAfter(el, list, first, ++last); 00445 } 00446 00456 MyType& SpliceAfter(Iterator el, MyType& list, 00457 Iterator first, Iterator last) 00458 { 00459 Node *nw = el.m_node, *nws = nw->m_next; 00460 Node *nf = first.m_node, *nl = last.m_node; 00461 00462 nw->m_next = nf->m_next; 00463 nf->m_next = nl->m_next; 00464 nl->m_next = nws; 00465 00466 if (nl == list.m_last) 00467 { 00468 list.m_last = nf; 00469 } 00470 00471 if (nw == m_last) 00472 { 00473 m_last = nl; 00474 } 00475 00476 return *this; 00477 } 00478 00487 template <class Pred> 00488 Size RemoveIf(Pred pred) 00489 { 00490 Node *ncur = m_head->m_next, *nlast = m_head; 00491 Size removed = 0; 00492 00493 while (ncur != nullptr) 00494 { 00495 if (pred(ncur->m_val)) 00496 { 00497 // Predicate holds -> remove element. 00498 nlast->m_next = ncur->m_next; 00499 Mem::Delete(ncur); 00500 ncur = nlast->m_next; 00501 00502 ++removed; 00503 } 00504 else 00505 { 00506 // Advance. 00507 nlast = ncur; 00508 ncur = ncur->m_next; 00509 } 00510 } 00511 00512 m_last = nlast; 00513 00514 return removed; 00515 } 00516 00525 template <class Pred> 00526 Size Unique(Pred pred) 00527 { 00528 Size removed = 0; 00529 00530 if (!IsEmpty()) 00531 { 00532 Node *nlast = m_head->m_next; 00533 Node *ncur = nlast->m_next; 00534 00535 while (ncur != nullptr) 00536 { 00537 if (pred(nlast->m_val, ncur->m_val)) 00538 { 00539 // Match -> remove element. 00540 nlast->m_next = ncur->m_next; 00541 Mem::Delete(ncur); 00542 ncur = nlast->m_next; 00543 00544 ++removed; 00545 } 00546 else 00547 { 00548 // No match -> advance. 00549 nlast = ncur; 00550 ncur = ncur->m_next; 00551 } 00552 } 00553 00554 m_last = nlast; 00555 } 00556 00557 return removed; 00558 } 00559 00571 template <class Comp> 00572 MyType& Merge(MyType& list, Comp comp) 00573 { 00574 if (this != &list) 00575 { 00576 Iterator nb1 = BeforeBegin(), nc1 = Begin(), ne1 = End(); 00577 Iterator nc2 = list.Begin(), ne2 = list.End(); 00578 00579 while (nc1 != ne1 && nc2 != ne2) 00580 { 00581 if (comp(*nc2, *nc1)) 00582 { 00583 Iterator nb2 = list.BeforeBegin(); 00584 00585 do 00586 { 00587 ++nb2; 00588 ++nc2; 00589 } while (nc2 != ne2 && comp(*nc2, *nc1)); 00590 00591 SpliceAfter(nb1, list, list.BeforeBegin(), nb2); 00592 nb1 = nb2; 00593 } 00594 00595 ++nb1; 00596 ++nc1; 00597 } 00598 00599 if (nc2 != ne2) 00600 { 00601 SpliceAfter(nb1, list); 00602 } 00603 } 00604 00605 return *this; 00606 } 00607 00620 template <class Comp> 00621 MyType& Sort(Comp comp) 00622 { 00623 // Sort only if at least two elements present 00624 if (m_head->m_next != nullptr && m_head->m_next->m_next != nullptr) 00625 { 00626 const Size MaxBin = 40; 00627 ForwardList<T> lcarry, lbin[MaxBin + 1]; 00628 Size lastBin = 0, curBin; 00629 00630 while (!IsEmpty()) 00631 { 00632 lcarry.SpliceAfter(lcarry.BeforeBegin(), *this, BeforeBegin()); 00633 00634 for (curBin = 0; curBin < lastBin && !lbin[curBin].IsEmpty(); ++curBin) 00635 { 00636 lbin[curBin].Merge(lcarry, comp); 00637 lbin[curBin].Swap(lcarry); 00638 } 00639 00640 if (curBin == MaxBin) 00641 { 00642 lbin[curBin - 1].Merge(lcarry, comp); 00643 } 00644 else 00645 { 00646 lbin[curBin].Swap(lcarry); 00647 if (curBin == lastBin) 00648 { 00649 lastBin++; 00650 } 00651 } 00652 } 00653 00654 for (curBin = 1; curBin < lastBin; ++curBin) 00655 { 00656 lbin[curBin].Merge(lbin[curBin - 1], comp); 00657 } 00658 00659 Swap(lbin[lastBin - 1]); 00660 } 00661 00662 return *this; 00663 } 00664 00671 MyType& Reverse() 00672 { 00673 if (!IsEmpty()) 00674 { 00675 Node *nprev = nullptr, *nc = m_head->m_next, *nn; 00676 00677 m_last = nc; 00678 00679 while (nc != nullptr) 00680 { 00681 nn = nc->m_next; 00682 nc->m_next = nprev; 00683 nprev = nc; 00684 nc = nn; 00685 } 00686 00687 m_head->m_next = nprev; 00688 } 00689 00690 return *this; 00691 } 00692 00694 Iterator Begin() 00695 { 00696 return Iterator(m_head->m_next); 00697 } 00698 00700 ConstIterator Begin() const 00701 { 00702 return ConstIterator(m_head->m_next); 00703 } 00704 00706 Iterator End() 00707 { 00708 return Iterator(nullptr); 00709 } 00710 00712 ConstIterator End() const 00713 { 00714 return ConstIterator(nullptr); 00715 } 00716 00718 Iterator Front() 00719 { 00720 return Begin(); 00721 } 00722 00724 ConstIterator Front() const 00725 { 00726 return Begin(); 00727 } 00728 00730 Iterator Back() 00731 { 00732 return Iterator(m_last); 00733 } 00734 00736 ConstIterator Back() const 00737 { 00738 return ConstIterator(m_last); 00739 } 00740 00742 Iterator BeforeBegin() 00743 { 00744 return Iterator(m_head); 00745 } 00746 00748 ConstIterator BeforeBegin() const 00749 { 00750 return ConstIterator(m_head); 00751 } 00752 }; 00753 } 00754 00756 namespace Algo 00757 { 00758 // Swap specialization for forward list container. 00759 template <class T> 00760 struct SwapFunc< Collection::ForwardList<T> > 00761 { 00762 void operator()(Collection::ForwardList<T>& x, Collection::ForwardList<T>& y) 00763 { 00764 x.Swap(y); 00765 } 00766 }; 00767 } 00769 } 00770 00771 #endif