00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 {
00108 other->m_next->m_prev = other->m_prev;
00109 other->m_prev->m_next = other->m_next;
00110
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 {
00120 other->m_next->m_prev = other->m_prev;
00121 other->m_prev->m_next = other->m_next;
00122
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 {
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
00235 other.m_list.m_prev = other.m_list.m_next = &other.m_list;
00236 }
00237
00238 }
00239
00240
00241 #endif