File indexing completed on 2025-08-03 08:19:37
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef SYMLIST_H
0010 #define SYMLIST_H
0011
0012 #include <GTL/GTL.h>
0013
0014 #include <cassert>
0015
0016 __GTL_BEGIN_NAMESPACE
0017
0018
0019
0020
0021 template <class T>
0022 struct symnode
0023 {
0024
0025
0026
0027 symnode()
0028 {
0029 }
0030
0031
0032
0033
0034 symnode(const T& n) : data(n)
0035 {
0036 }
0037
0038
0039
0040
0041 symnode* adj[2];
0042
0043
0044
0045
0046 T data;
0047 };
0048
0049
0050
0051
0052 template <class T, class Ref>
0053 struct symlist_iterator
0054 {
0055
0056
0057
0058 typedef symlist_iterator<T, Ref> self;
0059
0060
0061
0062
0063 typedef symnode<T>* linktype;
0064
0065
0066
0067
0068 symlist_iterator() : act (0)
0069 {
0070 }
0071
0072
0073
0074
0075 symlist_iterator(const self& it) : act(it.act), dir(it.dir)
0076 {
0077 }
0078
0079
0080
0081
0082 symlist_iterator(linktype _act, int _dir) : act(_act), dir(_dir)
0083 {
0084 }
0085
0086
0087
0088
0089 symlist_iterator(linktype _act, linktype _prev) :
0090 act(_act),
0091 dir (where_not (_act, _prev))
0092 {
0093 }
0094
0095
0096
0097
0098 self& operator=(const self& it)
0099 {
0100 act = it.act;
0101 dir = it.dir;
0102 return *this;
0103 }
0104
0105
0106
0107
0108 bool operator==(const self& it) const
0109 {
0110 return act == it.act;
0111 }
0112
0113
0114
0115
0116 bool operator!=(const self& it) const
0117 {
0118 return act != it.act;
0119 }
0120
0121
0122
0123
0124 Ref operator*()
0125 {
0126 return act->data;
0127 }
0128
0129
0130
0131
0132 self& operator++();
0133
0134
0135
0136
0137 self& operator--();
0138
0139
0140
0141
0142 static int where(linktype _act, linktype _prev)
0143 {
0144 return _prev == _act->adj[0] ? 0 : 1;
0145 }
0146
0147
0148
0149
0150 static int where_not(linktype _act, linktype _prev)
0151 {
0152 return _prev == _act->adj[1] ? 0 : 1;
0153 }
0154
0155
0156
0157
0158 void reverse()
0159 {
0160 dir = 1 - dir;
0161 }
0162
0163
0164
0165
0166 linktype& next()
0167 {
0168 return act->adj[dir];
0169 }
0170
0171
0172
0173
0174 linktype& prev()
0175 {
0176 return act->adj[1 - dir];
0177 }
0178
0179
0180
0181
0182 linktype act;
0183
0184
0185
0186
0187 int dir;
0188 };
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208 template <class T>
0209 class symlist
0210 {
0211 public:
0212
0213
0214
0215 typedef symlist_iterator<T, T&> iterator;
0216
0217
0218
0219
0220 typedef symlist_iterator<T, const T&> const_iterator;
0221
0222
0223
0224
0225 symlist()
0226 {
0227 link = new symnode<T>;
0228 link->adj[0] = link->adj[1] = link;
0229 }
0230
0231
0232
0233
0234
0235
0236 symlist(const symlist<T>& li);
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 symlist<T>& operator=(const symlist<T>& li);
0248
0249
0250
0251
0252 ~symlist();
0253
0254
0255
0256
0257
0258
0259
0260
0261 bool empty() const
0262 {
0263 return link->adj[0] == link && link->adj[1] == link;
0264 }
0265
0266
0267
0268
0269
0270
0271
0272
0273 T& front()
0274 {
0275 return link->adj[0]->data;
0276 }
0277
0278
0279
0280
0281
0282
0283
0284
0285 T& back()
0286 {
0287 return link->adj[1]->data;
0288 }
0289
0290
0291
0292
0293
0294
0295 iterator begin()
0296 {
0297 return ++end();
0298 }
0299
0300
0301
0302
0303
0304
0305 iterator end()
0306 {
0307 return iterator(link, 0);
0308 }
0309
0310
0311
0312
0313
0314
0315 const_iterator begin() const
0316 {
0317 return ++end();
0318 }
0319
0320
0321
0322
0323
0324
0325 const_iterator end () const
0326 {
0327 return const_iterator (link, 0);
0328 }
0329
0330
0331
0332
0333
0334
0335 iterator rbegin()
0336 {
0337 return ++rend();
0338 }
0339
0340
0341
0342
0343
0344
0345 iterator rend()
0346 {
0347 return iterator (link, 1);
0348 }
0349
0350
0351
0352
0353
0354
0355 const_iterator rbegin() const
0356 {
0357 return ++rend();
0358 }
0359
0360
0361
0362
0363
0364
0365 const_iterator rend() const
0366 {
0367 return const_iterator(link, 1);
0368 }
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378 iterator insert (iterator pos, const T& data);
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391 void splice (iterator pos, iterator it);
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405 void splice (iterator pos, iterator it, iterator end);
0406
0407
0408
0409
0410
0411
0412
0413
0414 iterator erase (iterator pos);
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424 iterator erase (iterator it, iterator end);
0425
0426
0427
0428
0429 void attach_sublist (iterator, iterator);
0430
0431
0432
0433
0434 void detach_sublist ();
0435
0436
0437
0438
0439
0440
0441 void reverse ();
0442 private:
0443
0444
0445
0446 symnode<T>* link;
0447
0448
0449
0450
0451
0452
0453 iterator _prev;
0454
0455
0456
0457
0458
0459
0460 iterator _next;
0461 };
0462
0463
0464
0465
0466 template <class T, class Ref>
0467 symlist_iterator<T, Ref>& symlist_iterator<T, Ref>::operator++()
0468 {
0469 symnode<T>* prev = act;
0470 act = act->adj[dir];
0471 dir = where_not(act, prev);
0472 return *this;
0473 }
0474
0475
0476 template <class T, class Ref>
0477 symlist_iterator<T, Ref>& symlist_iterator<T, Ref>::operator--()
0478 {
0479 symnode<T>* prev = act;
0480 act = act->adj[1 - dir];
0481 dir = where(act, prev);
0482 return *this;
0483 }
0484
0485
0486 template <class T>
0487 symlist<T>::symlist (const symlist<T>& l)
0488 {
0489 link = new symnode<T>;
0490 link->adj[0] = link->adj[1] = link;
0491
0492 const_iterator it = l.begin();
0493 const_iterator e = l.end();
0494
0495 while (it != e)
0496 {
0497 insert(end(), *it);
0498 ++it;
0499 }
0500 }
0501
0502
0503 template <class T>
0504 symlist<T>::~symlist()
0505 {
0506 if (_next == iterator())
0507 {
0508 erase (begin(), end());
0509 }
0510 else
0511 {
0512 detach_sublist();
0513 }
0514
0515 delete link;
0516 }
0517
0518
0519 template <class T>
0520 symlist<T>& symlist<T>::operator=(const symlist<T>& l)
0521 {
0522 erase(begin(), end());
0523
0524 const_iterator it = l.begin();
0525 const_iterator e = l.end();
0526
0527 while (it != e)
0528 {
0529 insert(end(), *it);
0530 ++it;
0531 }
0532
0533 return *this;
0534 }
0535
0536
0537 template <class T>
0538 symlist_iterator<T, T&> symlist<T>::insert(
0539 symlist_iterator<T,T&> pos,
0540 const T& ins)
0541 {
0542 iterator prev = pos;
0543 --prev;
0544 symnode<T>* n = new symnode<T>(ins);
0545 n->adj[0] = pos.act;
0546 n->adj[1] = prev.act;
0547
0548 if (pos == prev)
0549 {
0550 pos = prev;
0551 }
0552
0553 pos.prev() = n;
0554 prev.next() = n;
0555
0556 return iterator(n, 0);
0557 }
0558
0559
0560 template <class T>
0561 void symlist<T>::splice(symlist_iterator<T, T&> pos,
0562 symlist_iterator<T, T&> beg,
0563 symlist_iterator<T, T&> end)
0564 {
0565 if (beg != end)
0566 {
0567 iterator prev = beg;
0568 --prev;
0569 iterator last = end;
0570 --last;
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581 if (prev == end)
0582 {
0583 prev = end;
0584 }
0585
0586 prev.next() = end.act;
0587 end.prev() = prev.act;
0588
0589 prev = pos;
0590 --prev;
0591
0592 if (pos == prev)
0593 {
0594 pos = prev;
0595 }
0596
0597 if (last == beg)
0598 {
0599 last = beg;
0600 }
0601
0602 prev.next() = beg.act;
0603 beg.prev() = prev.act;
0604 pos.prev() = last.act;
0605 last.next() = pos.act;
0606 }
0607 }
0608
0609
0610 template <class T>
0611 void symlist<T>::splice(symlist_iterator<T,T&> pos,
0612 symlist_iterator<T,T&> beg)
0613 {
0614 iterator tmp = beg;
0615 ++tmp;
0616 splice(pos, beg, tmp);
0617 }
0618
0619
0620 template <class T>
0621 symlist_iterator<T,T&> symlist<T>::erase(symlist_iterator<T,T&> pos)
0622 {
0623 assert (pos.act != link);
0624 iterator prev = pos;
0625 --prev;
0626 iterator next = pos;
0627 ++next;
0628
0629 if (next == prev)
0630 {
0631 next = prev;
0632 }
0633
0634 next.prev() = prev.act;
0635 prev.next() = next.act;
0636
0637 delete (pos.act);
0638
0639 return next;
0640 }
0641
0642 template <class T>
0643 symlist_iterator<T,T&> symlist<T>::erase(symlist_iterator<T,T&> beg,
0644 symlist_iterator<T,T&> end)
0645 {
0646 iterator prev = beg;
0647 --prev;
0648 iterator it = beg;
0649 symnode<T>* act;
0650
0651 while (it != end)
0652 {
0653 assert (it.act != link);
0654 act = it.act;
0655 ++it;
0656 delete (act);
0657 }
0658
0659 if (prev == end)
0660 {
0661 prev = end;
0662 }
0663
0664 end.prev() = prev.act;
0665 prev.next() = end.act;
0666
0667 return end;
0668 }
0669
0670
0671 template <class T>
0672 void symlist<T>::attach_sublist(symlist_iterator<T,T&> it,
0673 symlist_iterator<T,T&> end)
0674 {
0675 assert (empty());
0676 iterator last = end;
0677 --last;
0678 _prev = it;
0679 --_prev;
0680 _next = end;
0681
0682 if (it == last)
0683 {
0684 it = last;
0685 }
0686
0687 link->adj[0] = it.act;
0688 it.prev() = link;
0689 link->adj[1] = last.act;
0690 last.next() = link;
0691 }
0692
0693
0694 template <class T>
0695 void symlist<T>::detach_sublist()
0696 {
0697 if (_next != iterator())
0698 {
0699 iterator it(begin());
0700 iterator e(end());
0701
0702 --e;
0703
0704 if (e == it)
0705 {
0706 e = it;
0707 }
0708
0709 _prev.next() = it.act;
0710 it.prev() = _prev.act;
0711 _next.prev() = e.act;
0712 e.next() = _next.act;
0713 link->adj[0] = link->adj[1] = link;
0714
0715 _next = iterator();
0716 _prev = iterator();
0717 }
0718 }
0719
0720
0721 template <class T>
0722 inline void symlist<T>::reverse()
0723 {
0724 symnode<T>* tmp = link->adj[0];
0725 link->adj[0] = link->adj[1];
0726 link->adj[1] = tmp;
0727 }
0728
0729
0730
0731 __GTL_END_NAMESPACE
0732
0733 #endif
0734
0735
0736
0737