Loading...
Searching...
No Matches
nchainIteration.hpp
Go to the documentation of this file.
1
9 BY(CLASS(nchainIteration, iteration))
10 friend class tnchain;
11
12public:
13 nchainIteration(tnchain* iteratingChain, const K* key, nbool isReversed):
14 me(iteratingChain, key, isReversed, false, true) {}
15
16 nchainIteration(tnchain* iteratingChain, const K* key, nbool isReversed, nbool isBoundary, nbool isAutoAdvance):
17 super(isReversed),
18 _chainIter(iteratingChain),
19 _key(key ? *key : _getDummyKey()),
20 _isDummyKey(!key),
21 _iter(_makeContainerIter(false)),
22 _isBoundary(isBoundary) {
23 if(isAutoAdvance && !_iter) {
24 next(1);
25 _setBoundary(isBoundary);
26 }
27 }
28
29 nbool isEnd() const override {
30 WHEN(_getNextContainer()) .ret(false);
31 return !_iter;
32 }
33
34 void rel() override {
35 _iter.rel();
36 _chainIter.rel();
37 }
38
39 nbool isBoundary() const { return _isBoundary; }
40
41 ncnt next(ncnt step) override { return _step(super::NEXT, step); }
42
43 ncnt prev(ncnt step) override { return _step(super::PREV, step); }
44
45 ncnt stepForward(ncnt step) override { return _step(super::FORWARD, step); }
46
47 ncnt stepBackward(ncnt step) override { return _step(super::BACKWARD, step); }
48
49 using super::getContainer;
50
51 tbicontainable<K, V>* getContainer() override {
52 WHEN(!_chainIter) .ret(nullptr);
53 return _chainIter.get();
54 }
55
56 const K* getKey() const override { return _iter.getKey(); }
57
58 using super::getVal;
59
60 V* getVal() override { return _iter.getVal(); }
61
62 using super::setVal;
63
64 void setVal(const V& new1) override { _iter.setVal(new1); }
65
66protected:
67 nbool _onSame(const typeProvidable& rhs) const override {
68 const me& cast = (const me&) rhs;
69 return (isEnd() && cast.isEnd()) || _iter == cast._iter;
70 }
71
72private:
73 ncnt _step(typename super::iterationType type, ncnt step) {
74 ncnt remain = step;
75
76 // if _chainIter was invalidated then _iter too.
77 while(remain > 0) {
78 if(!_isSubIterEndAtMiddle()) remain -= _iterate(type, remain);
79 if(remain <= 0) break;
80
81 // _iter moved to 'End' state now.
82 if(isEnd()) break;
83 _updateIter();
84 if(_iter) remain--;
85 }
86
87 return step - remain;
88 }
89
90 ncnt _iterate(typename super::iterationType type, ncnt step) {
91 _isBoundary = false;
92 switch(type) {
93 case super::FORWARD: return _iter.stepForward(step);
94 case super::BACKWARD: return _iter.stepBackward(step);
95 case super::PREV: return _iter.prev(step);
96 default:
97 case super::NEXT: return _iter.next(step);
98 }
99 }
100
101 const iter* _getNextIter() const {
102 WHEN(!_chainIter) .ret(nullptr);
103 return this->isReversed() ? &_chainIter->_prev : &_chainIter->_next;
104 }
105
106 const tnchain* _getNextContainer() const {
107 WHEN(!_chainIter) .ret(nullptr);
108 return this->isReversed() ? _chainIter->getPrev() : _chainIter->getNext();
109 }
110
111 void _updateIter() {
112 const iter& nextIter = _getNextIter() OR_DO {
113 _chainIter.rel();
114 _iter.rel();
115 return;
116 };
117
118 // proceed to next chain:
119 _chainIter.bind(_castChain(nextIter));
120 // init container iter:
121 me& nextIteration = _castIteration(nextIter) OR.ret();
122 _iter = nextIteration._isBoundary ? _makeContainerIter(nextIteration.isReversed()) : nextIteration._iter;
123 if(!_isDummyKey && (!_iter.getKey() || _key != *_iter.getKey())) _iter.next(1);
124 }
125
134 iter _makeContainerIter(nbool isReversed) const {
135 return isReversed ? (this->isReversed() ? _chainIter->_map->begin(_getFindingKey()) :
136 _chainIter->_map->rbegin(_getFindingKey())) :
137 (this->isReversed() ? _chainIter->_map->rbegin(_getFindingKey()) :
138 _chainIter->_map->begin(_getFindingKey()));
139 }
140
141 void _setBoundary(nbool new1) { _isBoundary = new1; }
142
143 me* _castIteration(const iter& e) { return (me*) (e._iteration.get()); }
144 const me* _castIteration(const iter& e) const BY_CONST_FUNC(_castIteration(e))
145
146 tnchain* _castChain(const iter& e) { return (tnchain*) e.getContainer(); }
147
148 tnchain* _castChain(const iter* it) BY_SIDE_FUNC(_castChain);
149
150 const tnchain* _castChain(const iter& e) const BY_CONST_FUNC(_castChain(e));
151 const tnchain* _castChain(const iter* e) const BY_CONST_FUNC(_castChain(e));
152
172 nbool _isSubIterEndAtMiddle()
173 const { // if this iter is not reversed, there is no case you have the `end at middle`.
174 WHEN(!this->isReversed()) .ret(false);
175
176 // if there is no prev chain, I'll just regard it as `end()` soon.
177 const tnchain& prev = _castChain(_getNextIter()) OR.ret(false);
178 const me& prevNext = _castIteration(prev._next) OR.ret(false);
179 WHEN(prevNext.isBoundary()) .ret(false);
180 return _iter == prevNext._iter;
181 }
182
183 static const K& _getDummyKey() {
184 static K inner;
185 return inner;
186 }
187
188 const K* _getFindingKey() const { return _isDummyKey ? nullptr : &_key; }
189
190private:
195 tstr<tnchain> _chainIter;
196 K _key;
197 nbool _isDummyKey;
201 iter _iter;
202
225 nbool _isBoundary;
226};
Bidirectional iterator for key-value containers.
Definition biter.hpp:10
ncnt next(ncnt step) override
void rel() override
Definition biteration.hpp:5
Chain iteration implementation.
Definition nchainIteration.hpp:8
ncnt next(ncnt step) override
Definition nchainIteration.hpp:41
to Top