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> 2004-01-26 Lars Gullik Bjonnes <larsbj@gullik.net>
* lyxfind.C (replaceAll): use std::advance * lyxfind.C (replaceAll): use std::advance

View File

@ -25,9 +25,58 @@
#include <boost/next_prior.hpp> #include <boost/next_prior.hpp>
using boost::prior; 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++() PosIterator & PosIterator::operator++()
{ {
BOOST_ASSERT(!stack_.empty()); 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) bool operator==(PosIterator const & lhs, PosIterator const & rhs)
{ {
PosIteratorItem const & li = lhs.stack_.back(); PosIteratorItem const & li = lhs.stack_.back();
PosIteratorItem const & ri = rhs.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 InsetBase * PosIterator::inset() const
{ {
if (stack_.size() == 1) if (stack_.size() == 1)

View File

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

View File

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

View File

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