Simple Application Framework  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Saf/Collection/List.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_LIST_H
00029 #define SAF_COLLECTION_LIST_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     {        
00073         template <class T> 
00074         class List
00075         {
00076         protected:
00077             typedef List<T> MyType;
00078 
00079         protected:
00081             class Node
00082             {
00083             public:
00085                 Node *m_next;
00087                 Node *m_prev;
00089                 T m_val;
00090 
00091             public:
00093                 Node(const T& val)
00094                     : m_val(val)
00095                 {}
00096             };
00097 
00098         public:
00100             class ConstIterator
00101             {
00102             public:
00103                 typedef T ValType;
00104                 typedef Type::IteratorCategory::BidirectionalCategory CategoryType;
00105 
00106             protected:
00108                 Node *m_node;
00109 
00110                 // The list can access the protected members
00111                 friend class List<T>;
00112 
00113             public:
00115                 ConstIterator()
00116                 {}
00117 
00119                 explicit ConstIterator(Node *node)
00120                     : m_node(node)
00121                 {}
00122 
00124                 ConstIterator(const ConstIterator& iter)
00125                     : m_node(iter.m_node)
00126                 {}
00127                     
00129                 ConstIterator& operator=(const ConstIterator& iter)
00130                 {
00131                     m_node = iter.m_node;
00132                     return *this;
00133                 }
00134 
00136                 const T& operator*() const
00137                 {
00138                     return m_node->m_val;
00139                 }
00140 
00142                 const T* operator->() const
00143                 {
00144                     return &m_node->m_val;
00145                 }
00146 
00148                 ConstIterator& operator++()
00149                 {
00150                     m_node = m_node->m_next;
00151                     return *this;
00152                 }
00153 
00155                 ConstIterator operator++(int)
00156                 {
00157                     ConstIterator ci(*this);
00158                     ++(*this);
00159                     return ci;
00160                 }
00161 
00163                 ConstIterator& operator--()
00164                 {
00165                     m_node = m_node->m_prev;
00166                     return *this;
00167                 }
00168 
00170                 ConstIterator operator--(int)
00171                 {
00172                     ConstIterator ci(*this);
00173                     --(*this);
00174                     return ci;
00175                 }
00176 
00178                 bool operator==(const ConstIterator& ci) const
00179                 {
00180                     return (m_node == ci.m_node);
00181                 }
00182 
00184                 bool operator!=(const ConstIterator& ci) const
00185                 {
00186                     return (m_node != ci.m_node);
00187                 }
00188             };
00189 
00191             class Iterator
00192                 : public ConstIterator
00193             {
00194             public:
00196                 Iterator()
00197                     : ConstIterator()
00198                 {}
00199 
00201                 explicit Iterator(Node *node)
00202                     : ConstIterator(node)
00203                 {}
00204 
00206                 Iterator(const Iterator& iter)
00207                     : ConstIterator(iter)
00208                 {}
00209                     
00211                 Iterator& operator=(const Iterator& iter)
00212                 {
00213                     ConstIterator::operator=(iter);
00214                     return *this;
00215                 }
00216 
00218                 T& operator*() const
00219                 {
00220                     return this->m_node->m_val;
00221                 }
00222 
00224                 T* operator->() const
00225                 {
00226                     return &this->m_node->m_val;
00227                 }
00228 
00230                 Iterator& operator++()
00231                 {
00232                     this->m_node = this->m_node->m_next;
00233                     return *this;
00234                 }
00235 
00237                 Iterator operator++(int)
00238                 {
00239                     Iterator it(*this);
00240                     ++(*this);
00241                     return it;
00242                 }
00243 
00245                 Iterator& operator--()
00246                 {
00247                     this->m_node = this->m_node->m_prev;
00248                     return *this;
00249                 }
00250 
00252                 Iterator operator--(int)
00253                 {
00254                     Iterator it(*this);
00255                     --(*this);
00256                     return it;
00257                 }
00258             };
00259 
00260         private:
00266             Node *m_head;
00267 
00268         private:
00270             void Init()
00271             {
00272                 Mem::OperatorNew(m_head, SAF_SOURCE_LOCATION);
00273                 m_head->m_next = m_head;
00274                 m_head->m_prev = m_head;
00275             }
00276 
00277         public:
00279             List()
00280             {
00281                 Init();
00282             }
00283 
00285             List(const MyType& list)
00286             {
00287                 Init();
00288                 *this = list;
00289             }
00290 
00292             ~List()
00293             {
00294                 Free();
00295                 Mem::OperatorDelete(m_head);
00296             }
00297 
00299             void Free()
00300             {
00301                 Node *n = m_head->m_next;
00302 
00303                 while (n != m_head)
00304                 {
00305                     n = n->m_next;
00306                     Mem::Delete(n->m_prev);
00307                 }
00308 
00309                 m_head->m_next = m_head;
00310                 m_head->m_prev = m_head;
00311             }
00312 
00314             MyType& operator=(const MyType& l)
00315             {
00316                 if (&l != this)
00317                 {
00318                     Free();
00319 
00320                     // Copy
00321                     Node *nprev = m_head, *ndst, *nsrc = l.m_head->m_next;
00322 
00323                     while (nsrc != l.m_head)
00324                     {
00325                         ndst = SAF_NEW Node(nsrc->m_val);
00326                         ndst->m_prev = nprev;
00327                         nprev->m_next = ndst;
00328                         nprev = ndst;
00329                         nsrc = nsrc->m_next;
00330                     }
00331 
00332                     nprev->m_next = m_head;
00333                     m_head->m_prev = nprev;
00334                 }
00335 
00336                 return *this;
00337             }
00338 
00344             MyType& Swap(MyType& l)
00345             {
00346                 Algo::Swap(m_head, l.m_head);
00347                 return *this;
00348             }
00349 
00355             bool IsEmpty() const
00356             {
00357                 return (m_head->m_next == m_head);
00358             }
00359 
00366             MyType& PushFront(const T &val)
00367             {
00368                 InsertBefore(Front(), val);
00369                 return *this;
00370             }
00371 
00378             MyType& PushBack(const T &val)
00379             {
00380                 InsertAfter(Back(), val);
00381                 return *this;
00382             }
00383 
00390             MyType& PopFront()
00391             {
00392                 if (!IsEmpty())
00393                 {
00394                     Erase(Front());
00395                 }
00396                 return *this;
00397             }
00398 
00405             MyType& PopBack()
00406             {
00407                 if (!IsEmpty())
00408                 {
00409                     Erase(Back());
00410                 }
00411                 return *this;
00412             }
00413 
00420             Iterator InsertAfter(Iterator iter, const T &val)
00421             {
00422                 Node *b = iter.m_node, *n = SAF_NEW Node(val);
00423 
00424                 n->m_prev = b;
00425                 n->m_next = b->m_next;
00426                 b->m_next = n;
00427                 n->m_next->m_prev = n;
00428 
00429                 return Iterator(n);
00430             }
00431 
00438             Iterator InsertBefore(Iterator iter, const T &val)
00439             {
00440                 Node *b = iter.m_node, *n = SAF_NEW Node(val);
00441 
00442                 n->m_next = b;
00443                 n->m_prev = b->m_prev;
00444                 b->m_prev = n;
00445                 n->m_prev->m_next = n;
00446 
00447                 return Iterator(n);
00448             }
00449 
00458             Iterator Erase(Iterator iter)
00459             {
00460                 Node *n = iter.m_node, *r = n->m_next;
00461 
00462                 n->m_prev->m_next = r;
00463                 r->m_prev = n->m_prev;
00464                 Mem::Delete(n);
00465 
00466                 return Iterator(r);
00467             }
00468 
00478             MyType& SpliceBefore(Iterator el, MyType& list)
00479             {
00480                 return SpliceBefore(el, list.Begin(), list.End());
00481             }
00482 
00492             MyType& SpliceBefore(Iterator el, Iterator first)
00493             {
00494                 Iterator last = first;
00495                 return SpliceBefore(el, first, ++last);
00496             }
00497 
00507             MyType& SpliceBefore(Iterator el, Iterator first, Iterator last)
00508             {
00509                 Node *nw = el.m_node;
00510                 Node *nf = first.m_node, *nl = last.m_node;
00511 
00512                 nf->m_prev->m_next = nl;
00513                 nl->m_prev->m_next = nw;
00514                 nw->m_prev->m_next = nf;
00515 
00516                 Node *nt = nw->m_prev;
00517                 nw->m_prev = nl->m_prev;
00518                 nl->m_prev = nf->m_prev;
00519                 nf->m_prev = nt;
00520 
00521                 return *this;
00522             }
00523 
00532             template <class Pred>
00533             Size RemoveIf(Pred pred)
00534             {
00535                 Node *ncur = m_head->m_next;
00536                 Size removed = 0;
00537 
00538                 while (ncur != m_head)
00539                 {
00540                     if (pred(ncur->m_val))
00541                     {
00542                         // Predicate holds -> remove element.
00543                         Node *nerase = ncur, *nprev = ncur->m_prev;
00544                         ncur = ncur->m_next;
00545 
00546                         nprev->m_next = ncur;
00547                         ncur->m_prev = nprev;
00548                         Mem::Delete(nerase);
00549 
00550                         ++removed;
00551                     }
00552                     else
00553                     {
00554                         // Advance.
00555                         ncur = ncur->m_next;
00556                     }   
00557                 }
00558 
00559                 return removed;
00560             }
00561 
00570             template <class Pred>
00571             Size Unique(Pred pred)
00572             {   
00573                 Node *nlast = m_head->m_next;
00574                 Node *ncur = nlast->m_next;
00575                 Size removed = 0;
00576 
00577                 while (ncur != m_head)
00578                 {
00579                     if (pred(nlast->m_val, ncur->m_val))
00580                     {
00581                         // Match -> remove element.
00582                         Node *nerase = ncur;
00583                         ncur = ncur->m_next;
00584 
00585                         nlast->m_next = ncur;
00586                         ncur->m_prev = nlast;
00587                         Mem::Delete(nerase);
00588 
00589                         ++removed;
00590                     }
00591                     else
00592                     {
00593                         // No match -> advance.
00594                         nlast = ncur;
00595                         ncur = ncur->m_next;
00596                     }
00597                 }
00598 
00599                 return removed;
00600             }
00601 
00613             template <class Comp>
00614             MyType& Merge(MyType& list, Comp comp)
00615             {
00616                 if (this != &list)
00617                 {
00618                     Iterator nf1 = Begin(), nl1 = End();
00619                     Iterator nf2 = list.Begin(), nl2 = list.End();
00620 
00621                     while (nf1 != nl1 && nf2 != nl2)
00622                     {
00623                         if (comp(*nf2, *nf1))
00624                         {
00625                             do
00626                             {
00627                                 ++nf2;
00628                             } while (nf2 != nl2 && comp(*nf2, *nf1));
00629 
00630                             SpliceBefore(nf1, list.Begin(), nf2);
00631                         }
00632 
00633                         ++nf1;
00634                     }
00635 
00636                     if (nf2 != nl2)
00637                     {
00638                         SpliceBefore(nl1, nf2, nl2);
00639                     }
00640                 }
00641 
00642                 return *this;
00643             }
00644 
00657             template <class Comp>
00658             MyType& Sort(Comp comp)
00659             {
00660                 // Sort only if at least two elements present
00661                 if (m_head->m_next != m_head && m_head->m_next->m_next != m_head)
00662                 {
00663                     const Size MaxBin = 40;
00664                     List<T> lcarry, lbin[MaxBin + 1];
00665                     Size lastBin = 0, curBin;
00666 
00667                     while (!IsEmpty())
00668                     {
00669                         lcarry.SpliceBefore(lcarry.Begin(), Begin());
00670 
00671                         for (curBin = 0; curBin < lastBin && !lbin[curBin].IsEmpty(); ++curBin)
00672                         {
00673                             lbin[curBin].Merge(lcarry, comp);
00674                             lbin[curBin].Swap(lcarry);
00675                         }
00676 
00677                         if (curBin == MaxBin)
00678                         {
00679                             lbin[curBin - 1].Merge(lcarry, comp);
00680                         }
00681                         else
00682                         {
00683                             lbin[curBin].Swap(lcarry);
00684                             if (curBin == lastBin)
00685                             {
00686                                 lastBin++;
00687                             }
00688                         }
00689                     }
00690 
00691                     for (curBin = 1; curBin < lastBin; ++curBin)
00692                     {
00693                         lbin[curBin].Merge(lbin[curBin - 1], comp);
00694                     }
00695 
00696                     Swap(lbin[lastBin - 1]);
00697                 }
00698 
00699                 return *this;
00700             }
00701 
00708             MyType& Reverse()
00709             {
00710                 Node *nc = m_head, *nn;
00711 
00712                 do
00713                 {
00714                     nn = nc->m_next;
00715                     nc->m_next = nc->m_prev;
00716                     nc->m_prev = nn;
00717                     nc = nn;
00718                 } while (nc != m_head);
00719 
00720                 return *this;
00721             }
00722 
00724             Iterator Begin()
00725             {
00726                 return Iterator(m_head->m_next);
00727             }
00728 
00730             ConstIterator Begin() const
00731             {
00732                 return ConstIterator(m_head->m_next);
00733             }
00734 
00736             Iterator End()
00737             {
00738                 return Iterator(m_head);
00739             }
00740 
00742             ConstIterator End() const
00743             {
00744                 return ConstIterator(m_head);
00745             }
00746 
00748             Iterator Front()
00749             {
00750                 return Begin();
00751             }
00752 
00754             ConstIterator Front() const
00755             {
00756                 return Begin();
00757             }
00758 
00760             Iterator Back()
00761             {
00762                 return Iterator(m_head->m_prev);
00763             }
00764 
00766             ConstIterator Back() const
00767             {
00768                 return ConstIterator(m_head->m_prev);
00769             }
00770         };
00771     }
00772 
00774     namespace Algo
00775     {
00776         // Swap specialization for list container.
00777         template <class T>
00778         struct SwapFunc< Collection::List<T> >
00779         {
00780             void operator()(Collection::List<T>& x, Collection::List<T>& y)
00781             {
00782                 x.Swap(y);
00783             }
00784         };
00785     }
00787 }
00788 
00789 #endif