2003-05-21 21:20:50 +00:00
|
|
|
|
/* \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<EFBFBD>nnes
|
|
|
|
|
*
|
|
|
|
|
* Full author contact details are available in file CREDITS
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2001-09-01 21:26:34 +00:00
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
|
|
#include "iterators.h"
|
2003-05-21 21:20:50 +00:00
|
|
|
|
#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_))
|
|
|
|
|
{}
|
|
|
|
|
|
2001-09-01 21:26:34 +00:00
|
|
|
|
|
2001-12-07 18:40:24 +00:00
|
|
|
|
ParIterator & ParIterator::operator++()
|
2001-09-01 21:26:34 +00:00
|
|
|
|
{
|
2003-05-21 21:20:50 +00:00
|
|
|
|
while (!pimpl_->positions.empty()) {
|
|
|
|
|
ParPosition & p = pimpl_->positions.top();
|
2001-09-01 21:26:34 +00:00
|
|
|
|
|
|
|
|
|
// Does the current inset contain more "cells" ?
|
2003-05-21 21:20:50 +00:00
|
|
|
|
if (p.index) {
|
|
|
|
|
++(*p.index);
|
|
|
|
|
ParagraphList * plist = p.it->getInset()->getParagraphs(*p.index);
|
2003-05-05 15:39:48 +00:00
|
|
|
|
if (plist && !plist->empty()) {
|
2003-05-21 21:20:50 +00:00
|
|
|
|
pimpl_->positions.push(ParPosition(plist->begin(), *plist));
|
2001-09-01 21:26:34 +00:00
|
|
|
|
return *this;
|
|
|
|
|
}
|
2003-05-21 21:20:50 +00:00
|
|
|
|
++(*p.it);
|
2001-12-07 18:40:24 +00:00
|
|
|
|
} 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
|
2003-05-21 21:20:50 +00:00
|
|
|
|
p.it.reset(p.pit->insetlist.begin());
|
2001-09-01 21:26:34 +00:00
|
|
|
|
|
|
|
|
|
// Try to find the next inset that contains paragraphs
|
2003-05-21 21:20:50 +00:00
|
|
|
|
InsetList::iterator end = p.pit->insetlist.end();
|
|
|
|
|
for (; *p.it != end; ++(*p.it)) {
|
|
|
|
|
ParagraphList * plist = p.it->getInset()->getParagraphs(0);
|
2003-05-05 15:39:48 +00:00
|
|
|
|
if (plist && !plist->empty()) {
|
2003-05-21 21:20:50 +00:00
|
|
|
|
p.index.reset(0);
|
|
|
|
|
pimpl_->positions.push(ParPosition(plist->begin(), *plist));
|
2001-09-01 21:26:34 +00:00
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-05-21 21:20:50 +00:00
|
|
|
|
|
2001-09-01 21:26:34 +00:00
|
|
|
|
// Try to go to the next paragarph
|
2003-05-21 21:20:50 +00:00
|
|
|
|
if (next(p.pit) != p.plist->end()
|
|
|
|
|
|| pimpl_->positions.size() == 1) {
|
|
|
|
|
++p.pit;
|
|
|
|
|
p.index.reset();
|
|
|
|
|
p.it.reset();
|
|
|
|
|
|
2001-09-01 21:26:34 +00:00
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2003-05-21 21:20:50 +00:00
|
|
|
|
// Drop end and move up in the stack.
|
|
|
|
|
pimpl_->positions.pop();
|
2001-09-01 21:26:34 +00:00
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
2002-11-08 01:08:27 +00:00
|
|
|
|
|
|
|
|
|
|
2003-05-21 21:20:50 +00:00
|
|
|
|
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_))
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
2002-11-08 01:08:27 +00:00
|
|
|
|
ParConstIterator & ParConstIterator::operator++()
|
|
|
|
|
{
|
2003-05-21 21:20:50 +00:00
|
|
|
|
while (!pimpl_->positions.empty()) {
|
|
|
|
|
ParPosition & p = pimpl_->positions.top();
|
2002-11-08 01:08:27 +00:00
|
|
|
|
|
|
|
|
|
// Does the current inset contain more "cells" ?
|
2003-05-21 21:20:50 +00:00
|
|
|
|
if (p.index) {
|
|
|
|
|
++(*p.index);
|
|
|
|
|
ParagraphList * plist = p.it->getInset()->getParagraphs(*p.index);
|
2003-05-05 15:39:48 +00:00
|
|
|
|
if (plist && !plist->empty()) {
|
2003-05-21 21:20:50 +00:00
|
|
|
|
pimpl_->positions.push(ParPosition(plist->begin(), *plist));
|
2002-11-08 01:08:27 +00:00
|
|
|
|
return *this;
|
|
|
|
|
}
|
2003-05-21 21:20:50 +00:00
|
|
|
|
++(*p.it);
|
2002-11-08 01:08:27 +00:00
|
|
|
|
} 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
|
2003-05-21 21:20:50 +00:00
|
|
|
|
p.it.reset(p.pit->insetlist.begin());
|
2002-11-08 01:08:27 +00:00
|
|
|
|
|
|
|
|
|
// Try to find the next inset that contains paragraphs
|
2003-05-21 21:20:50 +00:00
|
|
|
|
InsetList::iterator end = p.pit->insetlist.end();
|
|
|
|
|
for (; *p.it != end; ++(*p.it)) {
|
|
|
|
|
ParagraphList * plist = p.it->getInset()->getParagraphs(0);
|
2003-05-05 15:39:48 +00:00
|
|
|
|
if (plist && !plist->empty()) {
|
2003-05-21 21:20:50 +00:00
|
|
|
|
p.index.reset(0);
|
|
|
|
|
pimpl_->positions.push(ParPosition(plist->begin(), *plist));
|
2002-11-08 01:08:27 +00:00
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-05-21 21:20:50 +00:00
|
|
|
|
|
2002-11-08 01:08:27 +00:00
|
|
|
|
// Try to go to the next paragarph
|
2003-05-21 21:20:50 +00:00
|
|
|
|
if (next(p.pit) != p.plist->end()
|
|
|
|
|
|| pimpl_->positions.size() == 1) {
|
|
|
|
|
++p.pit;
|
|
|
|
|
p.index.reset();
|
|
|
|
|
p.it.reset();
|
|
|
|
|
|
2002-11-08 01:08:27 +00:00
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2003-05-21 21:20:50 +00:00
|
|
|
|
// Drop end and move up in the stack.
|
|
|
|
|
pimpl_->positions.pop();
|
2002-11-08 01:08:27 +00:00
|
|
|
|
}
|
2003-05-21 21:20:50 +00:00
|
|
|
|
|
2002-11-08 01:08:27 +00:00
|
|
|
|
return *this;
|
|
|
|
|
}
|
2003-05-21 21:20:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|