diff --git a/src/ChangeLog b/src/ChangeLog index 6d7672c9f5..90e892a4df 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2004-01-27 Lars Gullik Bjonnes + + * 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 * lyxfind.C (replaceAll): use std::advance diff --git a/src/PosIterator.C b/src/PosIterator.C index 28f7111f8e..0dba637dd0 100644 --- a/src/PosIterator.C +++ b/src/PosIterator.C @@ -25,9 +25,58 @@ #include + 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(pp.plist), + pp.pit, (*pp.it)->pos, *pp.index + 1)); + } + ParPosition const & pp = ph[last]; + stack_.push_back( + PosIteratorItem(const_cast(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) diff --git a/src/PosIterator.h b/src/PosIterator.h index f71e707936..cc6107e368 100644 --- a/src/PosIterator.h +++ b/src/PosIterator.h @@ -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 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 diff --git a/src/frontends/controllers/ControlErrorList.C b/src/frontends/controllers/ControlErrorList.C index 0c87819e65..6211826620 100644 --- a/src/frontends/controllers/ControlErrorList.C +++ b/src/frontends/controllers/ControlErrorList.C @@ -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); } diff --git a/src/iterators.C b/src/iterators.C index ebd8958d59..13b2193dff 100644 --- a/src/iterators.C +++ b/src/iterators.C @@ -24,30 +24,13 @@ #include "insets/insettext.h" #include -#include 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 it; - /// - optional 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 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(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(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 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(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(pp.plist), - pp.pit, (*pp.it)->pos, *pp.index + 1)); - } - ParPosition const & pp = pimpl_->positions[last]; - p.stack_.push_back( - PosIteratorItem(const_cast(pp.plist), pp.pit, pos, 0)); - return p; + return *const_cast(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(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); +} diff --git a/src/iterators.h b/src/iterators.h index 7dc35fea57..07c885b8c6 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -13,9 +13,13 @@ #define ITERATORS_H #include "ParagraphList_fwd.h" +#include "InsetList.h" + #include "support/types.h" -#include +#include + +#include 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 it; + /// + boost::optional 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 PosHolder; + PosHolder const & positions() const + { + return positions_; + } private: - struct Pimpl; - boost::scoped_ptr 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 PosHolder; + PosHolder const & positions() const + { + return positions_; + } private: - struct Pimpl; - boost::scoped_ptr pimpl_; + PosHolder positions_; }; bool operator==(ParConstIterator const & iter1,