chained.h

Go to the documentation of this file.
00001 //    sampalib.org ESL library and tools
00002 //    Copyright (C) 2007  Thierry Grellier
00003 //
00004 //    This program is free software; you can redistribute it and/or modify
00005 //    it under the terms of the GNU General Public License version 2 as
00006 //    published by the Free Software Foundation.
00007 //
00008 //    This program is distributed in the hope that it will be useful,
00009 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //    GNU General Public License for more details.
00012 //
00013 //    You should have received a copy of the GNU General Public License along
00014 //    with this program; if not, write to the Free Software Foundation, Inc.,
00015 //    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016 //
00017 //    contact: www.sampalib.org
00018 
00019 #ifndef SAMPA_CHAINED_H
00020 #define SAMPA_CHAINED_H
00021 
00022 #include "sampa/core/persistence.h"
00023 
00024 namespace Sampa {
00025 
00026   class SAMPA_PERSISTENT_CLASS(Chained) {
00027   public:
00028     class List;
00030     Chained(DefaultCtrTag);
00031     void detach();
00032     void set_prev(Chained* other);
00033     void set_next(Chained* other);
00034     Chained* get_next() const;
00035     Chained* get_prev() const;
00036     void reset();
00037     void merge(Chained*);
00038   protected:
00039     friend class List;
00040     Chained* m_next;
00041     Chained* m_prev;
00042     SAMPA_PERSISTENT(Chained);
00044   };
00045 
00046   class SAMPA_PERSISTENT_CLASS(Chained::List) {
00047   public:
00048     class Iterator {
00049     public:
00050       Iterator(DefaultCtrTag);
00051       Iterator(const Iterator&);
00052       Iterator& operator=(const Iterator&);
00053       Iterator& operator++();
00054       Chained* operator*() const;
00055       bool operator!=(const Iterator& other) const;
00057     protected:
00058       friend class List;
00059       Iterator(Chained* first); 
00060       Chained* m_curr;
00061       Chained* m_next;
00063     };
00064     Iterator begin();
00065     Iterator end(); 
00066     List(DefaultCtrTag);  
00067     List(Chained* chained);  
00068     void push_back (Chained* chained);
00069     void push_front(Chained* chained);
00070     Chained* pop_front();
00071     bool is_empty() const;
00072     Chained* get_front() const;
00073     Chained* get_back() const;
00074     void operator=(List& other);
00075     void reset();
00077   private:
00078     Chained m_list;
00079     SAMPA_PERSISTENT(List);
00081   };
00082 
00083 
00084 inline
00085 Chained::Chained(DefaultCtrTag)
00086   : m_next(this), 
00087     m_prev(this) 
00088 { 
00089 }
00090 
00091 inline
00092 void Chained::reset()
00093 { 
00094   m_prev = m_next = this; 
00095 }
00096 
00097 inline
00098 void Chained::detach()
00099 { 
00100   m_next->m_prev = m_prev;
00101   m_prev->m_next = m_next;
00102   m_prev = m_next = this; 
00103 }
00104 
00105 inline
00106 void Chained::set_prev(Chained* other)
00107 { // detach other
00108   other->m_next->m_prev = other->m_prev;
00109   other->m_prev->m_next = other->m_next;
00110   // link
00111   m_prev->m_next        = other;
00112   other->m_prev         = m_prev;
00113   m_prev                = other;
00114   other->m_next         = this; 
00115 }
00116 
00117 inline
00118 void Chained::set_next(Chained* other)
00119 { // detach other
00120   other->m_next->m_prev = other->m_prev;
00121   other->m_prev->m_next = other->m_next;
00122   // link
00123   m_next->m_prev        = other;
00124   other->m_next         = m_next;
00125   m_next                = other;
00126   other->m_prev         = this;
00127 }
00128 
00129 inline
00130 Chained* Chained::get_next() const
00131 { 
00132   return m_next; 
00133 }
00134 
00135 inline
00136 Chained* Chained::get_prev() const
00137 { 
00138   return m_prev; 
00139 }
00140 
00141 inline
00142 void Chained::merge(Chained* other) 
00143 {
00144   m_prev->m_next = other;
00145   other->m_prev->m_next = this;    
00146   Chained* prev = m_prev;
00147   m_prev = other->m_prev;
00148   other->m_prev = prev;
00149 }
00150 
00151 inline
00152 Chained::List::Iterator& Chained::List::Iterator::operator++()
00153 { m_curr = m_next; m_next = m_curr->get_next(); return *this; }
00154 
00155 inline
00156 Chained* Chained::List::Iterator::operator*() const
00157 { return m_curr; }
00158 
00159 inline
00160 bool Chained::List::Iterator::operator!=(const Chained::List::Iterator& other) const
00161 { return other.m_curr != m_curr; }
00162 
00163 inline
00164 Chained::List::Iterator::Iterator(Chained* first)
00165 : m_curr(first), m_next(first->get_next()) { } 
00166 
00167 inline
00168 Chained::List::Iterator::Iterator(const Chained::List::Iterator& other)
00169 : m_curr(other.m_curr), m_next(other.m_next) { } 
00170 
00171 inline
00172 Chained::List::Iterator::Iterator(DefaultCtrTag)
00173 : m_curr(0), m_next(0) { } 
00174 
00175 
00176 inline
00177 Chained::List::Iterator Chained::List::begin()
00178 { return Iterator(m_list.m_next); }
00179 
00180 inline
00181 Chained::List::Iterator Chained::List::end()
00182 { return Iterator(&m_list);   } 
00183 
00184 
00185 inline
00186 void Chained::List::reset()
00187 { 
00188   m_list.reset(); 
00189 }
00190 
00191 inline
00192 Chained::List::List(DefaultCtrTag t) 
00193 : m_list(t) {}  
00194 
00195 inline
00196 void Chained::List::push_back (Chained* chained) 
00197 { m_list.set_prev(chained); }
00198 
00199 inline
00200 Chained::List::List(Chained* chained)
00201 : m_list(DEFAULT_CTR) { push_back(chained); }  
00202 
00203 inline
00204 void Chained::List::push_front(Chained* chained)
00205 { m_list.set_next(chained); }
00206 
00207 inline
00208 Chained* Chained::List::pop_front()
00209 { 
00210   Chained* front = get_front();
00211   front->detach();
00212   return front;
00213 }
00214 
00215 inline
00216 bool Chained::List::is_empty() const
00217 { return m_list.m_next == &m_list; }
00218 
00219 inline
00220 Chained* Chained::List::get_front() const 
00221 { return m_list.m_next; }
00222 
00223 inline
00224 Chained* Chained::List::get_back() const 
00225 { return m_list.m_prev; }
00226 
00227 inline
00228 void Chained::List::operator=(Chained::List& other) 
00229 { // assert (!other.is_empty() && is_empty());
00230   m_list.m_next = other.m_list.m_next;
00231   m_list.m_next->m_prev = &m_list;
00232   m_list.m_prev = other.m_list.m_prev;
00233   m_list.m_prev->m_next = &m_list;
00234   // flush other list
00235   other.m_list.m_prev = other.m_list.m_next = &other.m_list; 
00236 }
00237 
00238 } // namespace Sampa
00239 
00240 
00241 #endif

Generated on Sat Feb 16 16:23:15 2008 for Sampa by  doxygen 1.5.3