00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef MORE_GEN_RING_H
00031 #define MORE_GEN_RING_H
00032
00033 #include <more/gen/memory.h>
00034 #include <stdexcept>
00035 #include <iterator>
00036
00037
00038 namespace more {
00039 namespace gen {
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 template< typename T, typename Alloc = more::gen::allocator<T> >
00072 struct ring {
00073
00074
00075 typedef T value_type;
00076 typedef Alloc allocator_type;
00077 typedef typename allocator_type::pointer pointer;
00078 typedef typename allocator_type::const_pointer const_pointer;
00079 typedef typename allocator_type::reference reference;
00080 typedef typename allocator_type::const_reference const_reference;
00081 typedef typename allocator_type::size_type size_type;
00082 typedef typename allocator_type::difference_type difference_type;
00083
00084
00085 private:
00086 struct node {
00087 node() {}
00088 node(T const& v) : value(v) {}
00089 node(node const& x) : value(x.value) {}
00090
00091 node* prev;
00092 node* next;
00093 T value;
00094 };
00095
00096 typedef typename allocator_type::template rebind<node>::other
00097 real_allocator_type;
00098
00099 public:
00100
00101 struct iterator
00102 {
00103 typedef std::ptrdiff_t difference_type;
00104 typedef T value_type;
00105 typedef value_type& reference;
00106 typedef value_type* pointer;
00107 typedef std::bidirectional_iterator_tag iterator_category;
00108
00109 iterator() {}
00110 iterator(iterator const& it) : x(it.x) {}
00111 explicit iterator(node* x_) : x(x_) {}
00112 iterator& operator++() { x = x->next; return *this; }
00113 iterator operator++(int) {
00114 iterator tmp = *this;
00115 ++*this;
00116 return tmp;
00117 }
00118 iterator& operator--() { x = x->prev; return *this; }
00119 iterator operator--(int) {
00120 iterator tmp = *this;
00121 --*this;
00122 return tmp;
00123 }
00124 bool operator==(iterator const& rhs) const {
00125 return x = rhs.x;
00126 }
00127 bool operator!=(iterator const& rhs) const {
00128 return x != rhs.x;
00129 }
00130 iterator& operator=(iterator const& rhs) {
00131 x = rhs.x;
00132 return *this;
00133 }
00134 reference operator*() { return x->value; }
00135 pointer operator->() { return &x->value; }
00136 private:
00137 node* x;
00138 friend class ring;
00139 };
00140
00141
00142
00143 struct const_iterator
00144 {
00145 typedef std::ptrdiff_t difference_type;
00146 typedef T const value_type;
00147 typedef value_type const& reference;
00148 typedef value_type const* pointer;
00149 typedef std::bidirectional_iterator_tag iterator_category;
00150
00151 const_iterator() {}
00152 const_iterator(const_iterator const& it) : x(it.x) {}
00153 const_iterator(iterator const& it) : x(it.x) {}
00154 explicit const_iterator(node const* x_) : x(x_) {}
00155 const_iterator& operator++() { x = x->next; return *this; }
00156 const_iterator operator++(int) {
00157 const_iterator tmp = *this;
00158 ++*this;
00159 return tmp;
00160 }
00161 const_iterator& operator--() { x = x->prev; return *this; }
00162 const_iterator operator--(int) {
00163 const_iterator tmp = *this;
00164 --*this;
00165 return tmp;
00166 }
00167 bool operator==(const_iterator const& rhs) const {
00168 return x = rhs.x;
00169 }
00170 bool operator!=(const_iterator const& rhs) const {
00171 return x != rhs.x;
00172 }
00173 const_iterator& operator=(const_iterator const& rhs) {
00174 x = rhs.x;
00175 return *this;
00176 }
00177 reference operator*() { return x->value; }
00178 pointer operator->() { return &x->value; }
00179 private:
00180 node const* x;
00181 friend class ring;
00182 };
00183
00184
00185
00186
00187 ring() : a_node(0), m_size(0) {}
00188
00189
00190 ring(ring const& r)
00191 : alloc(r.alloc), a_node(0), m_size(r.m_size) {
00192 if (r.size()) {
00193 const_iterator it = r.principal();
00194 while (--it != r.principal())
00195 push_front(*it);
00196 push_front(*it);
00197 }
00198 }
00199
00200
00201 ~ring() { clear(); }
00202
00203
00204 ring& operator=(ring const& x) {
00205 this->~ring();
00206 new(this) ring(x);
00207 return *this;
00208 }
00209
00210
00211 size_type size() const { return m_size; }
00212
00213
00214 bool empty() const { return m_size == 0; }
00215
00216
00217 iterator principal() {
00218 #ifndef MORE_NDEBUG
00219 if (!a_node)
00220 throw std::logic_error(
00221 "A ring with no nodes has no valid iterator.");
00222 #endif
00223 return iterator(a_node);
00224 }
00225
00226
00227 const_iterator principal() const {
00228 #ifndef MORE_NDEBUG
00229 if (!a_node)
00230 throw std::logic_error(
00231 "A ring with no nodes has no valid iterator.");
00232 #endif
00233 return const_iterator(a_node);
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 void clear() {
00247 m_size = 0;
00248 node* x = a_node;
00249 if (x)
00250 for(;;) {
00251 node* y = x->next;
00252 alloc.destroy(x);
00253 alloc.deallocate(x, 1);
00254 if (y == a_node) break;
00255 x = y;
00256 }
00257 }
00258
00259
00260
00261
00262
00263
00264
00265 iterator erase(iterator it) {
00266 --m_size;
00267 node* y = it.x->next;
00268 y->prev = it.x->prev;
00269 it.x->prev->next = y;
00270 if (it.x == a_node) {
00271 if (y == a_node)
00272 a_node = 0;
00273 else
00274 a_node = y;
00275 }
00276 alloc.destroy(it.x);
00277 alloc.deallocate(it.x, 1);
00278 return iterator(y);
00279 }
00280
00281
00282 iterator insert(iterator it, value_type const& val) {
00283 ++m_size;
00284 node* x = alloc.allocate(1);
00285 a.construct(x, node(val));
00286 x->next = it.x;
00287 x->prev = it.x->prev;
00288 it.x->prev->next = x;
00289 it.x->prev = x;
00290 return iterator(x);
00291 }
00292
00293
00294
00295
00296 iterator insert(iterator it) {
00297 ++m_size;
00298 node* x = alloc.allocate(1);
00299 alloc.construct(x);
00300 x->next = it.x;
00301 x->prev = it.x->prev;
00302 it.x->prev->next = x;
00303 it.x->prev = x;
00304 return iterator(x);
00305 }
00306
00307
00308
00309
00310 void push_front(value_type const& val) {
00311 ++m_size;
00312 node* x = alloc.allocate(1);
00313 alloc.construct(x, node(val));
00314 if (a_node) {
00315 x->prev = a_node->prev;
00316 x->next = a_node;
00317 x->prev->next = x;
00318 a_node->prev = x;
00319 }
00320 else {
00321 x->next = x;
00322 x->prev = x;
00323 }
00324 a_node = x;
00325 }
00326
00327
00328
00329
00330
00331 void push_front() {
00332 ++m_size;
00333 node* x = alloc.allocate(1);
00334 alloc.construct(x);
00335 if (a_node) {
00336 x->prev = a_node->prev;
00337 x->next = a_node;
00338 x->prev->next = x;
00339 a_node->prev = x;
00340 }
00341 else {
00342 x->next = x;
00343 x->prev = x;
00344 }
00345 a_node = x;
00346 }
00347
00348
00349
00350
00351 void push_back(value_type const& val) {
00352 ++m_size;
00353 node* x = alloc.allocate(1);
00354 alloc.construct(x, node(val));
00355 if (a_node) {
00356 x->prev = a_node;
00357 x->next = a_node->next;
00358 x->next->prev = x;
00359 a_node->next = x;
00360 }
00361 else {
00362 x->next = x;
00363 x->prev = x;
00364 }
00365 a_node = x;
00366 }
00367
00368
00369
00370
00371
00372 void push_back() {
00373 ++m_size;
00374 node* x = alloc.allocate(1);
00375 alloc.construct(x);
00376 if (a_node) {
00377 x->prev = a_node;
00378 x->next = a_node->next;
00379 x->next->prev = x;
00380 a_node->next = x;
00381 }
00382 else {
00383 x->next = x;
00384 x->prev = x;
00385 }
00386 a_node = x;
00387 }
00388
00389
00390
00391 void pop_front() { erase(iterator(a_node)); }
00392
00393
00394
00395 void pop_back() {
00396 erase(iterator(a_node));
00397 if (a_node) a_node = a_node->prev;
00398 }
00399
00400
00401
00402
00403
00404
00405 void rotate_counterclockwise() {
00406 #ifndef MORE_NDEBUG
00407 if (!a_node)
00408 throw std::logic_error("No ring to rotate.");
00409 #endif
00410 a_node = a_node->next;
00411 }
00412
00413
00414
00415
00416 void rotate_clockwise() {
00417 #ifndef MORE_NDEBUG
00418 if (!a_node)
00419 throw std::logic_error("No ring to rotate.");
00420 #endif
00421 a_node = a_node->prev;
00422 }
00423
00424
00425 allocator_type get_allocator() const { return alloc; }
00426
00427 private:
00428 real_allocator_type alloc;
00429 node* a_node;
00430 size_type m_size;
00431 };
00432 }}
00433
00434 #endif