Simple Application Framework  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Saf/Collection/ForwardList.h
Go to the documentation of this file.
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