unpimplify ParIterator, move some functions around, remove some friends.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8374 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Lars Gullik Bjønnes 2004-01-27 15:14:34 +00:00
parent 7ffb8944e1
commit c812bf5ba4
6 changed files with 264 additions and 258 deletions

View File

@ -1,3 +1,15 @@
2004-01-27 Lars Gullik Bjonnes <larsbj@gullik.net>
* iterators.C: Remove the pimple, move the needed structures to
the header file. Create accessor for the positions stack.
(asPosIterator): remove function
* PosIterator.C (PosIterator): move constructors to top of file
(PosIterator): reimplement the constructor taking a ParIterator in
terms of setFrom.
(setFrom): new function
(operator!=): inline it
2004-01-26 Lars Gullik Bjonnes <larsbj@gullik.net>
* lyxfind.C (replaceAll): use std::advance

View File

@ -25,9 +25,58 @@
#include <boost/next_prior.hpp>
using boost::prior;
PosIterator::PosIterator(ParagraphList * pl, ParagraphList::iterator pit,
lyx::pos_type pos)
{
stack_.push_back(PosIteratorItem(pl, pit, pos));
}
PosIterator::PosIterator(BufferView & bv)
{
LyXText * text = bv.getLyXText();
lyx::pos_type pos = text->cursor().pos();
ParagraphList::iterator pit = text->cursorPar();
ParIterator par = bv.buffer()->par_iterator_begin();
ParIterator end = bv.buffer()->par_iterator_end();
for (; par != end; ++par) {
if (par.pit() == pit)
break;
}
setFrom(par, pos);
}
PosIterator::PosIterator(ParIterator const & par, lyx::pos_type pos)
{
setFrom(par, pos);
}
void PosIterator::setFrom(ParIterator const & par, lyx::pos_type pos)
{
BOOST_ASSERT(par.size() > 0);
ParIterator::PosHolder const & ph = par.positions();
int const last = par.size() - 1;
for (int i = 0; i < last; ++i) {
ParPosition const & pp = ph[i];
stack_.push_back(
PosIteratorItem(const_cast<ParagraphList *>(pp.plist),
pp.pit, (*pp.it)->pos, *pp.index + 1));
}
ParPosition const & pp = ph[last];
stack_.push_back(
PosIteratorItem(const_cast<ParagraphList *>(pp.plist), pp.pit, pos, 0));
}
PosIterator & PosIterator::operator++()
{
BOOST_ASSERT(!stack_.empty());
@ -97,15 +146,8 @@ PosIterator & PosIterator::operator--()
}
bool operator!=(PosIterator const & lhs, PosIterator const & rhs)
{
return !(lhs == rhs);
}
bool operator==(PosIterator const & lhs, PosIterator const & rhs)
{
PosIteratorItem const & li = lhs.stack_.back();
PosIteratorItem const & ri = rhs.stack_.back();
@ -120,30 +162,6 @@ bool PosIterator::at_end() const
}
PosIterator::PosIterator(ParagraphList * pl, ParagraphList::iterator pit,
lyx::pos_type pos)
{
stack_.push_back(PosIteratorItem(pl, pit, pos));
}
PosIterator::PosIterator(BufferView & bv)
{
LyXText * text = bv.getLyXText();
lyx::pos_type pos = bv.cursor().pos();
ParagraphList::iterator pit = text->cursorPar();
ParIterator par = bv.buffer()->par_iterator_begin();
ParIterator end = bv.buffer()->par_iterator_end();
for ( ; par != end; ++par) {
if (par.pit() == pit)
break;
}
operator=(par.asPosIterator(pos));
}
InsetBase * PosIterator::inset() const
{
if (stack_.size() == 1)

View File

@ -39,11 +39,13 @@ class PosIterator : public std::iterator<
std::bidirectional_iterator_tag,
ParagraphList::value_type> {
public:
// Creates a singular.
PosIterator() {};
PosIterator(BufferView & bv);
PosIterator(ParIterator & par, lyx::pos_type pos);
PosIterator(ParagraphList * pl, ParagraphList::iterator pit,
lyx::pos_type pos);
PosIterator(ParIterator const & parit, lyx::pos_type p);
PosIterator(ParIterator const & par, lyx::pos_type pos);
PosIterator & operator++();
PosIterator & operator--();
friend bool operator==(PosIterator const &, PosIterator const &);
@ -52,17 +54,22 @@ public:
lyx::pos_type pos() const { return stack_.back().pos; }
bool at_end() const;
InsetBase * inset() const;
friend PosIterator ParIterator::asPosIterator(lyx::pos_type) const;
friend ParIterator::ParIterator(PosIterator const &);
private:
PosIterator() {};
//this is conceptually a stack, but we need random access sometimes
void setFrom(ParIterator const & par, lyx::pos_type pos);
// This is conceptually a stack,
// but we need random access sometimes.
std::vector<PosIteratorItem> stack_;
};
bool operator!=(PosIterator const &, PosIterator const &);
bool operator==(PosIterator const &, PosIterator const &);
inline
bool operator!=(PosIterator const & lhs, PosIterator const & rhs)
{
return !(lhs == rhs);
}
#endif

View File

@ -73,6 +73,6 @@ void ControlErrorList::goTo(int item)
int const range = end - start;
// Now make the selection.
PosIterator const pos = pit.asPosIterator(start);
PosIterator const pos(pit, start);
kernel().bufferview()->putSelectionAt(pos, range, false);
}

View File

@ -24,30 +24,13 @@
#include "insets/insettext.h"
#include <boost/next_prior.hpp>
#include <boost/optional.hpp>
using boost::next;
using boost::optional;
using std::vector;
///
/// 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)
@ -74,15 +57,9 @@ bool operator!=(ParPosition const & pos1, ParPosition const & pos2)
/// ParIterator
///
struct ParIterator::Pimpl {
typedef vector<ParPosition> PosHolder;
PosHolder positions;
};
ParIterator::ParIterator(ParagraphList::iterator pit, ParagraphList const & pl)
: pimpl_(new Pimpl)
{
pimpl_->positions.push_back(ParPosition(pit, pl));
positions_.push_back(ParPosition(pit, pl));
}
@ -91,21 +68,21 @@ ParIterator::~ParIterator()
ParIterator::ParIterator(ParIterator const & pi)
: pimpl_(new Pimpl(*pi.pimpl_))
: positions_(pi.positions_)
{}
void ParIterator::operator=(ParIterator const & pi)
{
ParIterator tmp(pi);
pimpl_.swap(tmp.pimpl_);
swap(positions_ , tmp.positions_);
}
ParIterator & ParIterator::operator++()
{
while (!pimpl_->positions.empty()) {
ParPosition & p = pimpl_->positions.back();
while (!positions_.empty()) {
ParPosition & p = positions_.back();
// Does the current inset contain more "cells" ?
if (p.index) {
@ -113,7 +90,7 @@ ParIterator & ParIterator::operator++()
if (LyXText * text = (*p.it)->inset->getText(*p.index)) {
ParagraphList & plist = text->paragraphs();
if (!plist.empty()) {
pimpl_->positions.push_back(ParPosition(plist.begin(), plist));
positions_.push_back(ParPosition(plist.begin(), plist));
return *this;
}
}
@ -132,7 +109,7 @@ ParIterator & ParIterator::operator++()
ParagraphList & plist = text->paragraphs();
if (!plist.empty()) {
p.index.reset(0);
pimpl_->positions.push_back(ParPosition(plist.begin(), plist));
positions_.push_back(ParPosition(plist.begin(), plist));
return *this;
}
}
@ -140,7 +117,7 @@ ParIterator & ParIterator::operator++()
// Try to go to the next paragarph
if (next(p.pit) != const_cast<ParagraphList*>(p.plist)->end()
|| pimpl_->positions.size() == 1) {
|| positions_.size() == 1) {
++p.pit;
p.index.reset();
p.it.reset();
@ -149,7 +126,7 @@ ParIterator & ParIterator::operator++()
}
// Drop end and move up in the stack.
pimpl_->positions.pop_back();
positions_.pop_back();
}
return *this;
}
@ -157,227 +134,72 @@ ParIterator & ParIterator::operator++()
LyXText * ParIterator::text(Buffer & buf) const
{
//lyxerr << "positions.size: " << pimpl_->positions.size() << std::endl;
if (pimpl_->positions.size() <= 1)
//lyxerr << "positions.size: " << positions.size() << std::endl;
if (positions_.size() <= 1)
return &buf.text();
ParPosition const & pos = pimpl_->positions[pimpl_->positions.size() - 2];
ParPosition const & pos = positions_[positions_.size() - 2];
return (*pos.it)->inset->getText(*pos.index);
}
InsetBase * ParIterator::inset() const
{
//lyxerr << "positions.size: " << pimpl_->positions.size() << std::endl;
if (pimpl_->positions.size() <= 1)
//lyxerr << "positions.size: " << positions.size() << std::endl;
if (positions_.size() <= 1)
return 0;
ParPosition const & pos = pimpl_->positions[pimpl_->positions.size() - 2];
ParPosition const & pos = positions_[positions_.size() - 2];
return (*pos.it)->inset;
}
int ParIterator::index() const
{
if (pimpl_->positions.size() <= 1)
if (positions_.size() <= 1)
return 0;
return *(pimpl_->positions[pimpl_->positions.size() - 2].index);
return *(positions_[positions_.size() - 2].index);
}
Paragraph & ParIterator::operator*() const
{
return *pimpl_->positions.back().pit;
return *positions_.back().pit;
}
ParagraphList::iterator ParIterator::pit() const
{
return pimpl_->positions.back().pit;
return positions_.back().pit;
}
ParagraphList::iterator ParIterator::operator->() const
{
return pimpl_->positions.back().pit;
return positions_.back().pit;
}
ParagraphList::iterator ParIterator::outerPar() const
{
return pimpl_->positions[0].pit;
return positions_[0].pit;
}
size_t ParIterator::size() const
{
return pimpl_->positions.size();
return positions_.size();
}
ParagraphList & ParIterator::plist() const
{
return *const_cast<ParagraphList*>(pimpl_->positions.back().plist);
}
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 vector<ParPosition> PosHolder;
PosHolder positions;
};
ParConstIterator::ParConstIterator(ParagraphList::iterator pit,
ParagraphList const & pl)
: pimpl_(new Pimpl)
{
pimpl_->positions.push_back(ParPosition(pit, pl));
}
ParConstIterator::~ParConstIterator()
{}
ParConstIterator::ParConstIterator(ParConstIterator const & pi)
: pimpl_(new Pimpl(*pi.pimpl_))
{}
ParConstIterator & ParConstIterator::operator++()
{
while (!pimpl_->positions.empty()) {
ParPosition & p = pimpl_->positions.back();
// Does the current inset contain more "cells" ?
if (p.index) {
++(*p.index);
if (LyXText * text = (*p.it)->inset->getText(*p.index)) {
ParagraphList & plist = text->paragraphs();
if (!plist.empty()) {
pimpl_->positions.push_back(ParPosition(plist.begin(), plist));
return *this;
}
}
++(*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.reset(p.pit->insetlist.begin());
}
// Try to find the next inset that contains paragraphs
InsetList::iterator end = p.pit->insetlist.end();
for (; *p.it != end; ++(*p.it)) {
if (LyXText * text = (*p.it)->inset->getText(0)) {
ParagraphList & plist = text->paragraphs();
if (!plist.empty()) {
p.index.reset(0);
pimpl_->positions.push_back(ParPosition(plist.begin(), plist));
return *this;
}
}
}
// Try to go to the next paragarph
if (next(p.pit) != const_cast<ParagraphList*>(p.plist)->end()
|| pimpl_->positions.size() == 1) {
++p.pit;
p.index.reset();
p.it.reset();
return *this;
}
// Drop end and move up in the stack.
pimpl_->positions.pop_back();
}
return *this;
}
Paragraph const & ParConstIterator::operator*() const
{
return *pimpl_->positions.back().pit;
}
ParagraphList::const_iterator ParConstIterator::pit() const
{
return pimpl_->positions.back().pit;
}
ParagraphList::const_iterator ParConstIterator::operator->() const
{
return pimpl_->positions.back().pit;
}
ParagraphList const & ParConstIterator::plist() const
{
return *pimpl_->positions.back().plist;
}
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);
}
PosIterator ParIterator::asPosIterator(lyx::pos_type pos) const
{
PosIterator p;
int const last = size() - 1;
for (int i = 0; i < last; ++i) {
ParPosition & pp = pimpl_->positions[i];
p.stack_.push_back(
PosIteratorItem(const_cast<ParagraphList *>(pp.plist),
pp.pit, (*pp.it)->pos, *pp.index + 1));
}
ParPosition const & pp = pimpl_->positions[last];
p.stack_.push_back(
PosIteratorItem(const_cast<ParagraphList *>(pp.plist), pp.pit, pos, 0));
return p;
return *const_cast<ParagraphList*>(positions_.back().plist);
}
ParIterator::ParIterator(PosIterator const & pos)
: pimpl_(new Pimpl)
{
int const size = pos.stack_.size();
@ -394,7 +216,7 @@ ParIterator::ParIterator(PosIterator const & pos)
pp.it.reset(beg);
pp.index.reset(it.index - 1);
}
pimpl_->positions.push_back(pp);
positions_.push_back(pp);
}
}
@ -403,7 +225,137 @@ void ParIterator::lockPath(BufferView * bv) const
{
LCursor & cur = bv->cursor();
cur.cursor_.clear();
for (int i = 0, last = size() - 1; i < last; ++i)
(*pimpl_->positions[i].it)->inset->edit(cur, true);
int const last = size() - 1;
for (int i = 0; i < last; ++i)
(*positions_[i].it)->inset->edit(cur, true);
cur.resetAnchor();
}
bool operator==(ParIterator const & iter1, ParIterator const & iter2)
{
return iter1.positions() == iter2.positions();
}
bool operator!=(ParIterator const & iter1, ParIterator const & iter2)
{
return !(iter1 == iter2);
}
///
/// ParConstIterator
///
ParConstIterator::ParConstIterator(ParagraphList::iterator pit,
ParagraphList const & pl)
{
positions_.push_back(ParPosition(pit, pl));
}
ParConstIterator::~ParConstIterator()
{}
ParConstIterator::ParConstIterator(ParConstIterator const & pi)
: positions_(pi.positions_)
{}
ParConstIterator & ParConstIterator::operator++()
{
while (!positions_.empty()) {
ParPosition & p = positions_.back();
// Does the current inset contain more "cells" ?
if (p.index) {
++(*p.index);
if (LyXText * text = (*p.it)->inset->getText(*p.index)) {
ParagraphList & plist = text->paragraphs();
if (!plist.empty()) {
positions_.push_back(ParPosition(plist.begin(), plist));
return *this;
}
}
++(*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.reset(p.pit->insetlist.begin());
}
// Try to find the next inset that contains paragraphs
InsetList::iterator end = p.pit->insetlist.end();
for (; *p.it != end; ++(*p.it)) {
if (LyXText * text = (*p.it)->inset->getText(0)) {
ParagraphList & plist = text->paragraphs();
if (!plist.empty()) {
p.index.reset(0);
positions_.push_back(ParPosition(plist.begin(), plist));
return *this;
}
}
}
// Try to go to the next paragarph
if (next(p.pit) != const_cast<ParagraphList*>(p.plist)->end()
|| positions_.size() == 1) {
++p.pit;
p.index.reset();
p.it.reset();
return *this;
}
// Drop end and move up in the stack.
positions_.pop_back();
}
return *this;
}
Paragraph const & ParConstIterator::operator*() const
{
return *positions_.back().pit;
}
ParagraphList::const_iterator ParConstIterator::pit() const
{
return positions_.back().pit;
}
ParagraphList::const_iterator ParConstIterator::operator->() const
{
return positions_.back().pit;
}
ParagraphList const & ParConstIterator::plist() const
{
return *positions_.back().plist;
}
size_t ParConstIterator::size() const
{
return positions_.size();
}
bool operator==(ParConstIterator const & iter1, ParConstIterator const & iter2)
{
return iter1.positions() == iter2.positions();
}
bool operator!=(ParConstIterator const & iter1, ParConstIterator const & iter2)
{
return !(iter1 == iter2);
}

View File

@ -13,9 +13,13 @@
#define ITERATORS_H
#include "ParagraphList_fwd.h"
#include "InsetList.h"
#include "support/types.h"
#include <boost/scoped_ptr.hpp>
#include <boost/optional.hpp>
#include <vector>
class LyXText;
class InsetBase;
@ -25,6 +29,21 @@ class BufferView;
class PosIterator;
class ParPosition {
public:
///
ParPosition(ParagraphList::iterator p, ParagraphList const & pl);
///
ParagraphList::iterator pit;
///
ParagraphList const * plist;
///
boost::optional<InsetList::iterator> it;
///
boost::optional<int> index;
};
class ParIterator : public std::iterator<
std::forward_iterator_tag,
ParagraphList::value_type> {
@ -60,16 +79,15 @@ public:
///
size_t size() const;
///
friend
bool operator==(ParIterator const & iter1, ParIterator const & iter2);
///
void lockPath(BufferView *) const;
///
PosIterator asPosIterator(lyx::pos_type) const;
typedef std::vector<ParPosition> PosHolder;
PosHolder const & positions() const
{
return positions_;
}
private:
struct Pimpl;
boost::scoped_ptr<Pimpl> pimpl_;
PosHolder positions_;
};
///
@ -102,14 +120,13 @@ public:
/// depth of nesting
size_t size() const;
///
friend
bool operator==(ParConstIterator const & iter1,
ParConstIterator const & iter2);
typedef std::vector<ParPosition> PosHolder;
PosHolder const & positions() const
{
return positions_;
}
private:
struct Pimpl;
boost::scoped_ptr<Pimpl> pimpl_;
PosHolder positions_;
};
bool operator==(ParConstIterator const & iter1,