]> git.lyx.org Git - lyx.git/blob - src/iterators.C
compile fix
[lyx.git] / src / iterators.C
1 /* \file iterators.C
2  * This file is part of LyX, the document processor.
3  * Licence details can be found in the file COPYING.
4  *
5  * \author unknown
6  * \author Lars Gullik Bjønnes
7  *
8  * Full author contact details are available in file CREDITS
9  */
10
11
12 #include <config.h>
13
14 #include "iterators.h"
15 #include "paragraph.h"
16
17 #include <boost/next_prior.hpp>
18 #include <boost/optional.hpp>
19
20 #include <stack>
21
22 using boost::next;
23 using boost::optional;
24 using std::stack;
25
26 ///
27 /// ParPosition
28 ///
29
30 class ParPosition {
31 public:
32         ///
33         ParPosition(ParagraphList::iterator p, ParagraphList const & pl);
34         ///
35         ParagraphList::iterator pit;
36         ///
37         ParagraphList const * plist;
38         ///
39         optional<InsetList::iterator> it;
40         ///
41         optional<int> index;
42 };
43
44
45 ParPosition::ParPosition(ParagraphList::iterator p, ParagraphList const & pl)
46         : pit(p), plist(&pl)
47 {
48         if (p != pl.end()) {
49                 it.reset(p->insetlist.begin());
50         }
51 }
52
53
54 bool operator==(ParPosition const & pos1, ParPosition const & pos2)
55 {
56         return pos1.pit == pos2.pit;
57 }
58
59
60 bool operator!=(ParPosition const & pos1, ParPosition const & pos2)
61 {
62         return !(pos1 == pos2);
63 }
64
65
66 ///
67 /// ParIterator
68 ///
69
70 struct ParIterator::Pimpl {
71         typedef stack<ParPosition> PosHolder;
72         PosHolder positions;
73 };
74
75 ParIterator::ParIterator(ParagraphList::iterator pit, ParagraphList const & pl)
76         : pimpl_(new Pimpl)
77 {
78         pimpl_->positions.push(ParPosition(pit, pl));
79 }
80
81
82 ParIterator::~ParIterator()
83 {}
84
85
86 ParIterator::ParIterator(ParIterator const & pi)
87         : pimpl_(new Pimpl(*pi.pimpl_))
88 {}
89
90
91 ParIterator & ParIterator::operator++()
92 {
93         while (!pimpl_->positions.empty()) {
94                 ParPosition & p = pimpl_->positions.top();
95
96                 // Does the current inset contain more "cells" ?
97                 if (p.index) {
98                         ++(*p.index);
99                         ParagraphList * plist = p.it->getInset()->getParagraphs(*p.index);
100                         if (plist && !plist->empty()) {
101                                 pimpl_->positions.push(ParPosition(plist->begin(), *plist));
102                                 return *this;
103                         }
104                         ++(*p.it);
105                 } else
106                         // The following line is needed because the value of
107                         // p.it may be invalid if inset was added/removed to
108                         // the paragraph pointed by the iterator
109                         p.it.reset(p.pit->insetlist.begin());
110
111                 // Try to find the next inset that contains paragraphs
112                 InsetList::iterator end = p.pit->insetlist.end();
113                 for (; *p.it != end; ++(*p.it)) {
114                         ParagraphList * plist = p.it->getInset()->getParagraphs(0);
115                         if (plist && !plist->empty()) {
116                                 p.index.reset(0);
117                                 pimpl_->positions.push(ParPosition(plist->begin(), *plist));
118                                 return *this;
119                         }
120                 }
121
122                 // Try to go to the next paragarph
123                 if (next(p.pit) != p.plist->end()
124                     || pimpl_->positions.size() == 1) {
125                         ++p.pit;
126                         p.index.reset();
127                         p.it.reset();
128
129                         return *this;
130                 }
131
132                 // Drop end and move up in the stack.
133                 pimpl_->positions.pop();
134         }
135         return *this;
136 }
137
138
139 ParagraphList::iterator ParIterator::operator*() const
140 {
141         return pimpl_->positions.top().pit;
142 }
143
144
145 ParagraphList::iterator ParIterator::operator->() const
146 {
147         return pimpl_->positions.top().pit;
148 }
149
150
151 size_t ParIterator::size() const
152 {
153         return pimpl_->positions.size();
154 }
155
156
157 bool operator==(ParIterator const & iter1, ParIterator const & iter2)
158 {
159         return iter1.pimpl_->positions == iter2.pimpl_->positions;
160 }
161
162
163 bool operator!=(ParIterator const & iter1, ParIterator const & iter2)
164 {
165         return !(iter1 == iter2);
166 }
167
168
169 ///
170 /// ParConstIterator
171 ///
172
173
174 struct ParConstIterator::Pimpl {
175         typedef stack<ParPosition> PosHolder;
176         PosHolder positions;
177 };
178
179
180 ParConstIterator::ParConstIterator(ParagraphList::iterator pit,
181                                    ParagraphList const & pl)
182         : pimpl_(new Pimpl)
183 {
184         pimpl_->positions.push(ParPosition(pit, pl));
185 }
186
187
188 ParConstIterator::~ParConstIterator()
189 {}
190
191
192 ParConstIterator::ParConstIterator(ParConstIterator const & pi)
193         : pimpl_(new Pimpl(*pi.pimpl_))
194 {}
195
196
197 ParConstIterator & ParConstIterator::operator++()
198 {
199         while (!pimpl_->positions.empty()) {
200                 ParPosition & p = pimpl_->positions.top();
201
202                 // Does the current inset contain more "cells" ?
203                 if (p.index) {
204                         ++(*p.index);
205                         ParagraphList * plist = p.it->getInset()->getParagraphs(*p.index);
206                         if (plist && !plist->empty()) {
207                                 pimpl_->positions.push(ParPosition(plist->begin(), *plist));
208                                 return *this;
209                         }
210                         ++(*p.it);
211                 } else
212                         // The following line is needed because the value of
213                         // p.it may be invalid if inset was added/removed to
214                         // the paragraph pointed by the iterator
215                         p.it.reset(p.pit->insetlist.begin());
216
217                 // Try to find the next inset that contains paragraphs
218                 InsetList::iterator end = p.pit->insetlist.end();
219                 for (; *p.it != end; ++(*p.it)) {
220                         ParagraphList * plist = p.it->getInset()->getParagraphs(0);
221                         if (plist && !plist->empty()) {
222                                 p.index.reset(0);
223                                 pimpl_->positions.push(ParPosition(plist->begin(), *plist));
224                                 return *this;
225                         }
226                 }
227
228                 // Try to go to the next paragarph
229                 if (next(p.pit) != p.plist->end()
230                     || pimpl_->positions.size() == 1) {
231                         ++p.pit;
232                         p.index.reset();
233                         p.it.reset();
234
235                         return *this;
236                 }
237
238                 // Drop end and move up in the stack.
239                 pimpl_->positions.pop();
240         }
241
242         return *this;
243 }
244
245
246 ParagraphList::iterator ParConstIterator::operator*() const
247 {
248         return pimpl_->positions.top().pit;
249 }
250
251
252 ParagraphList::iterator ParConstIterator::operator->() const
253 {
254         return pimpl_->positions.top().pit;
255 }
256
257
258 size_t ParConstIterator::size() const
259 {
260         return pimpl_->positions.size();
261 }
262
263
264 bool operator==(ParConstIterator const & iter1, ParConstIterator const & iter2)
265 {
266         return iter1.pimpl_->positions == iter2.pimpl_->positions;
267 }
268
269
270 bool operator!=(ParConstIterator const & iter1, ParConstIterator const & iter2)
271 {
272         return !(iter1 == iter2);
273 }