]> git.lyx.org Git - lyx.git/blobdiff - src/iterators.C
iterators-2.diff + some whitespace changes
[lyx.git] / src / iterators.C
index 9521313243cbf24a37717ead27b5fbedb858beaa..7f067728d1e14549f9a3740fede79f14851af54b 100644 (file)
+/* \file iterators.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author unknown
+ * \author Lars Gullik Bjønnes
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+
 #include <config.h>
 
 #include "iterators.h"
+#include "paragraph.h"
+
+#include <boost/next_prior.hpp>
+#include <boost/optional.hpp>
+
+#include <stack>
+
+using boost::next;
+using boost::optional;
+using std::stack;
+
+///
+/// ParPosition
+///
+
+class ParPosition {
+public:
+       ///
+       ParPosition(ParagraphList::iterator p, ParagraphList const & pl);
+       ///
+       ParagraphList::iterator pit;
+       ///
+       ParagraphList const * plist;
+       ///
+       optional<InsetList::iterator> it;
+       ///
+       optional<int> index;
+};
+
+
+ParPosition::ParPosition(ParagraphList::iterator p, ParagraphList const & pl)
+       : pit(p), plist(&pl)
+{
+       if (p != pl.end()) {
+               it.reset(p->insetlist.begin());
+       }
+}
+
+
+bool operator==(ParPosition const & pos1, ParPosition const & pos2)
+{
+       return pos1.pit == pos2.pit;
+}
+
+
+bool operator!=(ParPosition const & pos1, ParPosition const & pos2)
+{
+       return !(pos1 == pos2);
+}
+
+
+///
+/// ParIterator
+///
+
+struct ParIterator::Pimpl {
+       typedef stack<ParPosition> PosHolder;
+       PosHolder positions;
+};
+
+ParIterator::ParIterator(ParagraphList::iterator pit, ParagraphList const & pl)
+       : pimpl_(new Pimpl)
+{
+       pimpl_->positions.push(ParPosition(pit, pl));
+}
+
+
+ParIterator::~ParIterator()
+{}
+
+
+ParIterator::ParIterator(ParIterator const & pi)
+       : pimpl_(new Pimpl(*pi.pimpl_))
+{}
+
 
 ParIterator & ParIterator::operator++()
 {
-       while (!positions.empty()) {
-               ParPosition & p = positions.top();
+       while (!pimpl_->positions.empty()) {
+               ParPosition & p = pimpl_->positions.top();
 
                // Does the current inset contain more "cells" ?
-               if (p.index >= 0) {
-                       ++p.index;
-                       ParagraphList * plist = p.it.getInset()->getParagraphs(p.index);
+               if (p.index) {
+                       ++(*p.index);
+                       ParagraphList * plist = p.it->getInset()->getParagraphs(*p.index);
                        if (plist && !plist->empty()) {
-                               positions.push(ParPosition(&plist->front()));
+                               pimpl_->positions.push(ParPosition(plist->begin(), *plist));
                                return *this;
                        }
-                       ++p.it;
+                       ++(*p.it);
                } else
                        // The following line is needed because the value of
                        // p.it may be invalid if inset was added/removed to
                        // the paragraph pointed by the iterator
-                       p.it = p.par->insetlist.begin();
+                       p.it.reset(p.pit->insetlist.begin());
 
                // Try to find the next inset that contains paragraphs
-               InsetList::iterator end = p.par->insetlist.end();
-               for (; p.it != end; ++p.it) {
-                       ParagraphList * plist = p.it.getInset()->getParagraphs(0);
+               InsetList::iterator end = p.pit->insetlist.end();
+               for (; *p.it != end; ++(*p.it)) {
+                       ParagraphList * plist = p.it->getInset()->getParagraphs(0);
                        if (plist && !plist->empty()) {
-                               p.index = 0;
-                               positions.push(ParPosition(&plist->front()));
+                               p.index.reset(0);
+                               pimpl_->positions.push(ParPosition(plist->begin(), *plist));
                                return *this;
                        }
                }
+
                // Try to go to the next paragarph
-               if (p.par->next()) {
-                       p = ParPosition(p.par->next());
+               if (next(p.pit) != p.plist->end()
+                   || pimpl_->positions.size() == 1) {
+                       ++p.pit;
+                       p.index.reset();
+                       p.it.reset();
+
                        return *this;
                }
 
-               positions.pop();
+               // Drop end and move up in the stack.
+               pimpl_->positions.pop();
        }
        return *this;
 }
 
 
+ParagraphList::iterator ParIterator::operator*()
+{
+       return pimpl_->positions.top().pit;
+}
+
+
+ParagraphList::iterator ParIterator::operator->()
+{
+       return pimpl_->positions.top().pit;
+}
+
+
+size_t ParIterator::size() const
+{
+       return pimpl_->positions.size();
+}
+
+
+bool operator==(ParIterator const & iter1, ParIterator const & iter2)
+{
+       return iter1.pimpl_->positions == iter2.pimpl_->positions;
+}
+
+
+bool operator!=(ParIterator const & iter1, ParIterator const & iter2)
+{
+       return !(iter1 == iter2);
+}
+
+
+///
+/// ParConstIterator
+///
+
+
+struct ParConstIterator::Pimpl {
+       typedef stack<ParPosition> PosHolder;
+       PosHolder positions;
+};
+
+
+ParConstIterator::ParConstIterator(ParagraphList::iterator pit,
+                                  ParagraphList const & pl)
+       : pimpl_(new Pimpl)
+{
+       pimpl_->positions.push(ParPosition(pit, pl));
+}
+
+
+ParConstIterator::~ParConstIterator()
+{}
+
+
+ParConstIterator::ParConstIterator(ParConstIterator const & pi)
+       : pimpl_(new Pimpl(*pi.pimpl_))
+{}
+
+
 ParConstIterator & ParConstIterator::operator++()
 {
-       while (!positions.empty()) {
-               ParPosition & p = positions.top();
+       while (!pimpl_->positions.empty()) {
+               ParPosition & p = pimpl_->positions.top();
 
                // Does the current inset contain more "cells" ?
-               if (p.index >= 0) {
-                       ++p.index;
-                       ParagraphList * plist = p.it.getInset()->getParagraphs(p.index);
+               if (p.index) {
+                       ++(*p.index);
+                       ParagraphList * plist = p.it->getInset()->getParagraphs(*p.index);
                        if (plist && !plist->empty()) {
-                               positions.push(ParPosition(&plist->front()));
+                               pimpl_->positions.push(ParPosition(plist->begin(), *plist));
                                return *this;
                        }
-                       ++p.it;
+                       ++(*p.it);
                } else
                        // The following line is needed because the value of
                        // p.it may be invalid if inset was added/removed to
                        // the paragraph pointed by the iterator
-                       p.it = p.par->insetlist.begin();
+                       p.it.reset(p.pit->insetlist.begin());
 
                // Try to find the next inset that contains paragraphs
-               InsetList::iterator end = p.par->insetlist.end();
-               for (; p.it != end; ++p.it) {
-                       ParagraphList * plist = p.it.getInset()->getParagraphs(0);
+               InsetList::iterator end = p.pit->insetlist.end();
+               for (; *p.it != end; ++(*p.it)) {
+                       ParagraphList * plist = p.it->getInset()->getParagraphs(0);
                        if (plist && !plist->empty()) {
-                               p.index = 0;
-                               positions.push(ParPosition(&plist->front()));
+                               p.index.reset(0);
+                               pimpl_->positions.push(ParPosition(plist->begin(), *plist));
                                return *this;
                        }
                }
+
                // Try to go to the next paragarph
-               if (p.par->next()) {
-                       p = ParPosition(p.par->next());
+               if (next(p.pit) != p.plist->end()
+                   || pimpl_->positions.size() == 1) {
+                       ++p.pit;
+                       p.index.reset();
+                       p.it.reset();
+
                        return *this;
                }
 
-               positions.pop();
+               // Drop end and move up in the stack.
+               pimpl_->positions.pop();
        }
+
        return *this;
 }
+
+
+ParagraphList::iterator ParConstIterator::operator*()
+{
+       return pimpl_->positions.top().pit;
+}
+
+
+ParagraphList::iterator ParConstIterator::operator->()
+{
+       return pimpl_->positions.top().pit;
+}
+
+
+size_t ParConstIterator::size() const
+{
+       return pimpl_->positions.size();
+}
+
+
+bool operator==(ParConstIterator const & iter1, ParConstIterator const & iter2)
+{
+       return iter1.pimpl_->positions == iter2.pimpl_->positions;
+}
+
+
+bool operator!=(ParConstIterator const & iter1, ParConstIterator const & iter2)
+{
+       return !(iter1 == iter2);
+}