Also some minor cleanups, and one not-so-minor: now when createUndo returns 0, it is not added to the undostack. As I understand it, this led to us adding to the stack sizeof(Undo *) on every character the user added.
Please apply (can applier add limited_stack.h to support/Makefile.am themselves also) thanks john -- "I never understood what's so hard about picking a unique first and last name - and not going beyond the 6 character limit." - Toon Moene
Index: src/ChangeLog =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ChangeLog,v retrieving revision 1.718 diff -u -r1.718 ChangeLog --- src/ChangeLog 22 May 2002 12:33:01 -0000 1.718 +++ src/ChangeLog 22 May 2002 19:16:29 -0000 @@ -1,3 +1,14 @@ +2002-05-22 John Levon <[EMAIL PROTECTED]> + + * Makefile.am: + * undostack.h: + * undostack.C: remove + + * undo_funcs.h: + * undo_funcs.C: + * buffer.h: from above change. Small changes. Don't + add non-undos to the undostack + 2002-05-22 Lars Gullik Bjønnes <[EMAIL PROTECTED]> * buffer.C: comment out some some code that depend upon lyx_format Index: src/buffer.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/buffer.h,v retrieving revision 1.97 diff -u -r1.97 buffer.h --- src/buffer.h 22 May 2002 12:33:02 -0000 1.97 +++ src/buffer.h 22 May 2002 19:16:46 -0000 @@ -19,7 +19,8 @@ #include "LString.h" #include "undo.h" -#include "undostack.h" +#include "support/limited_stack.h" + #include "lyxvc.h" #include "bufferparams.h" #include "texrow.h" @@ -298,11 +299,11 @@ bool isMultiLingual(); /// Does this mean that this is buffer local? - UndoStack undostack; - - /// Does this mean that this is buffer local? - UndoStack redostack; - + limited_stack<Undo *> undostack; + + /// Does this mean that this is buffer local? + limited_stack<Undo *> redostack; + /// BufferParams params; Index: src/undo_funcs.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/undo_funcs.C,v retrieving revision 1.22 diff -u -r1.22 undo_funcs.C --- src/undo_funcs.C 21 Mar 2002 17:25:32 -0000 1.22 +++ src/undo_funcs.C 22 May 2002 19:17:05 -0000 @@ -23,318 +23,199 @@ #include "iterators.h" -#define DELETE_UNUSED_PARAGRAPHS 1 -#ifdef DELETE_UNUSED_PARAGRAPHS #include <vector> -#endif using std::vector; /// the flag used by FinishUndo(); bool undo_finished; -/// a flag +/// FIXME bool undo_frozen; +namespace { -bool textUndo(BufferView * bv) +// returns false if no undo possible +bool textHandleUndo(BufferView * bv, Undo * undo) { - // returns false if no undo possible - Undo * undo = bv->buffer()->undostack.top(); - bv->buffer()->undostack.pop(); - if (undo) { + if (!undo) { finishUndo(); - if (!undo_frozen) { - Paragraph * first = bv->buffer()->getParFromID(undo->number_of_before_par); - if (first && first->next()) - first = first->next(); - else if (!first) - first = firstUndoParagraph(bv, undo->number_of_inset_id); - if (first) { - bv->buffer()->redostack.push( - createUndo(bv, undo->kind, first, - bv->buffer()->getParFromID(undo->number_of_behind_par))); - } - } + bv->text->status(bv, LyXText::NEED_MORE_REFRESH); + return false; } - // now we can unlock the inset for saftey because the inset pointer could - // be changed during the undo-function. Anyway if needed we have to lock - // the right inset/position if this is requested. - freezeUndo(); - bv->unlockInset(bv->theLockingInset()); - bool ret = textHandleUndo(bv, undo); - unFreezeUndo(); - return ret; -} - - -bool textRedo(BufferView * bv) -{ - // returns false if no redo possible - Undo * undo = bv->buffer()->redostack.top(); - bv->buffer()->redostack.pop(); - if (undo) { - finishUndo(); - if (!undo_frozen) { - Paragraph * first = bv->buffer()->getParFromID(undo->number_of_before_par); - if (first && first->next()) - first = first->next(); - else if (!first) - first = firstUndoParagraph(bv, undo->number_of_inset_id); - if (first) { - bv->buffer()->undostack.push( - createUndo(bv, undo->kind, first, - bv->buffer()->getParFromID(undo->number_of_behind_par))); + + Buffer * b = bv->buffer(); + + Paragraph * before = + b->getParFromID(undo->number_of_before_par); + Paragraph * behind = + b->getParFromID(undo->number_of_behind_par); + Paragraph * tmppar; + Paragraph * tmppar2; + Paragraph * tmppar5; + + // if there's no before take the beginning + // of the document for redoing + if (!before) { + LyXText * t = bv->text; + int num = undo->number_of_inset_id; + if (undo->number_of_inset_id >= 0) { + Inset * in = bv->buffer()->getInsetFromID(num); + if (in) { + t = in->getLyXText(bv); + } else { + num = -1; } } + t->setCursorIntern(bv, firstUndoParagraph(bv, num), 0); } - // now we can unlock the inset for saftey because the inset pointer could - // be changed during the undo-function. Anyway if needed we have to lock - // the right inset/position if this is requested. - freezeUndo(); - bv->unlockInset(bv->theLockingInset()); - bool ret = textHandleUndo(bv, undo); - unFreezeUndo(); - return ret; -} - - -bool textHandleUndo(BufferView * bv, Undo * undo) -{ - // returns false if no undo possible - bool result = false; - if (undo) { - Paragraph * before = - bv->buffer()->getParFromID(undo->number_of_before_par); - Paragraph * behind = - bv->buffer()->getParFromID(undo->number_of_behind_par); - Paragraph * tmppar; - Paragraph * tmppar2; - Paragraph * tmppar5; - - // if there's no before take the beginning - // of the document for redoing - if (!before) { - LyXText * t = bv->text; - int num = undo->number_of_inset_id; - if (undo->number_of_inset_id >= 0) { - Inset * in = bv->buffer()->getInsetFromID(num); - if (in) { - t = in->getLyXText(bv); - } else { - num = -1; - } - } - t->setCursorIntern(bv, firstUndoParagraph(bv, num), 0); - } - // replace the paragraphs with the undo informations + // replace the paragraphs with the undo informations - Paragraph * tmppar3 = undo->par; - undo->par = 0; /* otherwise the undo destructor would - delete the paragraph */ - - // get last undo par and set the right(new) inset-owner of the - // paragraph if there is any. This is not needed if we don't have - // a paragraph before because then in is automatically done in the - // function which assigns the first paragraph to an InsetText. (Jug) - Paragraph * tmppar4 = tmppar3; - if (tmppar4) { - Inset * in = 0; - if (before) - in = before->inInset(); - else if (undo->number_of_inset_id >= 0) - in = bv->buffer()->getInsetFromID(undo->number_of_inset_id); + Paragraph * tmppar3 = undo->par; + undo->par = 0; /* otherwise the undo destructor would + delete the paragraph */ + + // get last undo par and set the right(new) inset-owner of the + // paragraph if there is any. This is not needed if we don't have + // a paragraph before because then in is automatically done in the + // function which assigns the first paragraph to an InsetText. (Jug) + Paragraph * tmppar4 = tmppar3; + if (tmppar4) { + Inset * in = 0; + if (before) + in = before->inInset(); + else if (undo->number_of_inset_id >= 0) + in = bv->buffer()->getInsetFromID(undo->number_of_inset_id); + tmppar4->setInsetOwner(in); + while (tmppar4->next()) { + tmppar4 = tmppar4->next(); tmppar4->setInsetOwner(in); - while (tmppar4->next()) { - tmppar4 = tmppar4->next(); - tmppar4->setInsetOwner(in); - } } + } - // now remove the old text if there is any -#ifdef DELETE_UNUSED_PARAGRAPHS - vector<Paragraph *> vvpar; -#endif - if (before != behind || (!behind && !before)) { - if (before) - tmppar5 = before->next(); - else - tmppar5 = firstUndoParagraph(bv, undo->number_of_inset_id); - tmppar2 = tmppar3; - while (tmppar5 && tmppar5 != behind) { -#ifdef DELETE_UNUSED_PARAGRAPHS - vvpar.push_back(tmppar5); -#endif - tmppar = tmppar5; - tmppar5 = tmppar5->next(); - // a memory optimization for edit: - // Only layout information - // is stored in the undo. So restore - // the text informations. - if (undo->kind == Undo::EDIT) { - tmppar2->setContentsFromPar(tmppar); -#ifndef DELETE_UNUSED_PARAGRAPHS - tmppar->clearContents(); -#endif - tmppar2 = tmppar2->next(); - } + // now remove the old text if there is any + vector<Paragraph *> vvpar; + if (before != behind || (!behind && !before)) { + if (before) + tmppar5 = before->next(); + else + tmppar5 = firstUndoParagraph(bv, undo->number_of_inset_id); + tmppar2 = tmppar3; + while (tmppar5 && tmppar5 != behind) { + vvpar.push_back(tmppar5); + tmppar = tmppar5; + tmppar5 = tmppar5->next(); + + // a memory optimization for edit: + // Only layout information + // is stored in the undo. So restore + // the text informations. + if (undo->kind == Undo::EDIT) { + tmppar2->setContentsFromPar(tmppar); + tmppar2 = tmppar2->next(); } } + } - // put the new stuff in the list if there is one - if (tmppar3) { - if (before) - before->next(tmppar3); - else - bv->text->ownerParagraph(firstUndoParagraph(bv, undo->number_of_inset_id)->id(), - tmppar3); - - tmppar3->previous(before); - } else { - // We enter here on DELETE undo operations where we have to - // substitue the second paragraph with the first if the removed - // one is the first! - if (!before && behind) { - bv->text->ownerParagraph(firstUndoParagraph(bv, undo->number_of_inset_id)->id(), - behind); - tmppar3 = behind; - } - } - if (tmppar4) { - tmppar4->next(behind); - if (behind) - behind->previous(tmppar4); + // put the new stuff in the list if there is one + if (tmppar3) { + if (before) + before->next(tmppar3); + else + bv->text->ownerParagraph(firstUndoParagraph(bv, +undo->number_of_inset_id)->id(), + tmppar3); + + tmppar3->previous(before); + } else { + // We enter here on DELETE undo operations where we have to + // substitue the second paragraph with the first if the removed + // one is the first! + if (!before && behind) { + bv->text->ownerParagraph(firstUndoParagraph(bv, +undo->number_of_inset_id)->id(), + behind); + tmppar3 = behind; } + } + if (tmppar4) { + tmppar4->next(behind); + if (behind) + behind->previous(tmppar4); + } - // Set the cursor for redoing - if (before) { - Inset * it = before->inInset(); - if (it) - it->getLyXText(bv)->setCursorIntern(bv, before, 0); - else - bv->text->setCursorIntern(bv, before, 0); - } + // Set the cursor for redoing + if (before) { + Inset * it = before->inInset(); + if (it) + it->getLyXText(bv)->setCursorIntern(bv, before, 0); + else + bv->text->setCursorIntern(bv, before, 0); + } - Paragraph * endpar = 0; - // calculate the endpar for redoing the paragraphs. - if (behind) - endpar = behind->next(); + Paragraph * endpar = 0; + // calculate the endpar for redoing the paragraphs. + if (behind) + endpar = behind->next(); - tmppar = bv->buffer()->getParFromID(undo->number_of_cursor_par); - UpdatableInset* it = 0; - if (tmppar3) - it = static_cast<UpdatableInset*>(tmppar3->inInset()); - if (it) { - it->getLyXText(bv)->redoParagraphs(bv, - it->getLyXText(bv)->cursor, - endpar); - if (tmppar) { - it = static_cast<UpdatableInset*>(tmppar->inInset()); - LyXText * t; - if (it) { - it->edit(bv); - t = it->getLyXText(bv); - } else { - t = bv->text; - } - t->setCursorIntern(bv, tmppar, undo->cursor_pos); - t->updateCounters(bv, t->cursor.row()); - bv->fitCursor(); + tmppar = bv->buffer()->getParFromID(undo->number_of_cursor_par); + UpdatableInset* it = 0; + if (tmppar3) + it = static_cast<UpdatableInset*>(tmppar3->inInset()); + if (it) { + it->getLyXText(bv)->redoParagraphs(bv, + it->getLyXText(bv)->cursor, + endpar); + if (tmppar) { + it = static_cast<UpdatableInset*>(tmppar->inInset()); + LyXText * t; + if (it) { + it->edit(bv); + t = it->getLyXText(bv); + } else { + t = bv->text; } - bv->updateInset(it, false); - bv->text->setCursorIntern(bv, bv->text->cursor.par(), - bv->text->cursor.pos()); - } else { - bv->text->redoParagraphs(bv, bv->text->cursor, endpar); - if (tmppar) { - LyXText * t; - Inset * it = tmppar->inInset(); - if (it) { - it->edit(bv); - t = it->getLyXText(bv); - } else { - t = bv->text; - } - t->setCursorIntern(bv, tmppar, undo->cursor_pos); - t->updateCounters(bv, t->cursor.row()); + t->setCursorIntern(bv, tmppar, undo->cursor_pos); + t->updateCounters(bv, t->cursor.row()); + bv->fitCursor(); + } + bv->updateInset(it, false); + bv->text->setCursorIntern(bv, bv->text->cursor.par(), + bv->text->cursor.pos()); + } else { + bv->text->redoParagraphs(bv, bv->text->cursor, endpar); + if (tmppar) { + LyXText * t; + Inset * it = tmppar->inInset(); + if (it) { + it->edit(bv); + t = it->getLyXText(bv); + } else { + t = bv->text; } + t->setCursorIntern(bv, tmppar, undo->cursor_pos); + t->updateCounters(bv, t->cursor.row()); } - result = true; - delete undo; -#ifdef DELETE_UNUSED_PARAGRAPHS - // And here it's save enough to delete all removed paragraphs - vector<Paragraph *>::iterator pit = vvpar.begin(); - if (pit != vvpar.end()) { -#if 0 - lyxerr << endl << "PARS BEFORE:"; - ParIterator end = bv->buffer()->par_iterator_end(); - ParIterator it = bv->buffer()->par_iterator_begin(); - for (; it != end; ++it) - lyxerr << (*it)->previous() << "<- " << (*it) << " ->" << (*it)->next() << endl; - lyxerr << "DEL: "; -#endif + } + + delete undo; + + // And here it's save enough to delete all removed paragraphs + vector<Paragraph *>::iterator pit = vvpar.begin(); + if (pit != vvpar.end()) { for(;pit != vvpar.end(); ++pit) { -// lyxerr << *pit << " "; (*pit)->previous(0); (*pit)->next(0); delete (*pit); } -#if 0 - lyxerr << endl << "PARS AFTER:"; - end = bv->buffer()->par_iterator_end(); - it = bv->buffer()->par_iterator_begin(); - for (; it != end; ++it) - lyxerr << (*it)->previous() << "<- " << (*it) << " ->" << (*it)->next() << endl; -#endif } -#endif - } + finishUndo(); bv->text->status(bv, LyXText::NEED_MORE_REFRESH); - return result; -} - - -void finishUndo() -{ - // makes sure the next operation will be stored - undo_finished = true; -} - - -void freezeUndo() -{ - // this is dangerous and for internal use only - undo_frozen = true; -} - - -void unFreezeUndo() -{ - // this is dangerous and for internal use only - undo_frozen = false; -} - - -void setUndo(BufferView * bv, Undo::undo_kind kind, - Paragraph const * first, Paragraph const * behind) -{ - if (!undo_frozen) { - bv->buffer()->undostack.push(createUndo(bv, kind, first, behind)); - bv->buffer()->redostack.clear(); - } -} - - -void setRedo(BufferView * bv, Undo::undo_kind kind, - Paragraph const * first, Paragraph const * behind) -{ - bv->buffer()->redostack.push(createUndo(bv, kind, first, behind)); + return true; } - + Undo * createUndo(BufferView * bv, Undo::undo_kind kind, Paragraph const * first, Paragraph const * behind) { @@ -351,6 +232,8 @@ if (first->inInset()) inset_id = first->inInset()->id(); + Buffer * b = bv->buffer(); + // Undo::EDIT and Undo::FINISH are // always finished. (no overlapping there) // overlapping only with insert and delete inside one paragraph: @@ -359,15 +242,16 @@ // EDIT is special since only layout information, not the // contents of a paragaph are stored. if (!undo_finished && (kind != Undo::EDIT) && (kind != Undo::FINISH)) { - // check wether storing is needed - if (!bv->buffer()->undostack.empty() && - bv->buffer()->undostack.top()->kind == kind && - bv->buffer()->undostack.top()->number_of_before_par == before_number && - bv->buffer()->undostack.top()->number_of_behind_par == behind_number) { + // check whether storing is needed + if (!b->undostack.empty() && + b->undostack.top()->kind == kind && + b->undostack.top()->number_of_before_par == before_number && + b->undostack.top()->number_of_behind_par == behind_number) { // no undo needed return 0; } } + // create a new Undo Paragraph * undopar; @@ -426,6 +310,120 @@ undo_finished = false; return undo; +} + +} // namespace anon + +void finishUndo() +{ + // makes sure the next operation will be stored + undo_finished = true; +} + + +void freezeUndo() +{ + // this is dangerous and for internal use only + undo_frozen = true; +} + + +void unFreezeUndo() +{ + // this is dangerous and for internal use only + undo_frozen = false; +} + + +// returns false if no undo possible +bool textUndo(BufferView * bv) +{ + Buffer * b = bv->buffer(); + Undo * undo = 0; + + if (!b->undostack.empty()) { + undo = b->undostack.top(); + b->undostack.pop(); + finishUndo(); + if (!undo_frozen) { + Paragraph * first = +b->getParFromID(undo->number_of_before_par); + if (first && first->next()) + first = first->next(); + else if (!first) + first = firstUndoParagraph(bv, +undo->number_of_inset_id); + if (first) { + Undo * u = createUndo(bv, undo->kind, first, + b->getParFromID(undo->number_of_behind_par)); + if (u) + bv->buffer()->redostack.push(u); + } + } + } + + // now we can unlock the inset for saftey because the inset pointer could + // be changed during the undo-function. Anyway if needed we have to lock + // the right inset/position if this is requested. + freezeUndo(); + bv->unlockInset(bv->theLockingInset()); + bool ret = textHandleUndo(bv, undo); + unFreezeUndo(); + return ret; +} + + +// returns false if no redo possible +bool textRedo(BufferView * bv) +{ + Buffer * b = bv->buffer(); + Undo * undo = 0; + if (!b->redostack.empty()) { + undo = b->redostack.top(); + b->redostack.pop(); + finishUndo(); + if (!undo_frozen) { + Paragraph * first = +bv->buffer()->getParFromID(undo->number_of_before_par); + if (first && first->next()) + first = first->next(); + else if (!first) + first = firstUndoParagraph(bv, +undo->number_of_inset_id); + if (first) { + Undo * u = createUndo(bv, undo->kind, first, + +bv->buffer()->getParFromID(undo->number_of_behind_par)); + if (u) + bv->buffer()->undostack.push(u); + } + } + } + + // now we can unlock the inset for saftey because the inset pointer could + // be changed during the undo-function. Anyway if needed we have to lock + // the right inset/position if this is requested. + freezeUndo(); + bv->unlockInset(bv->theLockingInset()); + bool ret = textHandleUndo(bv, undo); + unFreezeUndo(); + return ret; +} + + +void setUndo(BufferView * bv, Undo::undo_kind kind, + Paragraph const * first, Paragraph const * behind) +{ + if (!undo_frozen) { + Undo * u = createUndo(bv, kind, first, behind); + if (u) + bv->buffer()->undostack.push(u); + bv->buffer()->redostack.clear(); + } +} + + +void setRedo(BufferView * bv, Undo::undo_kind kind, + Paragraph const * first, Paragraph const * behind) +{ + Undo * u = createUndo(bv, kind, first, behind); + if (u) + bv->buffer()->redostack.push(u); } Index: src/undo_funcs.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/undo_funcs.h,v retrieving revision 1.2 diff -u -r1.2 undo_funcs.h --- src/undo_funcs.h 21 Mar 2002 17:25:32 -0000 1.2 +++ src/undo_funcs.h 22 May 2002 19:17:05 -0000 @@ -25,8 +25,6 @@ extern bool textUndo(BufferView *); /// returns false if no redo possible extern bool textRedo(BufferView *); -/// used by TextUndo/TextRedo -extern bool textHandleUndo(BufferView *, Undo * undo); /// makes sure the next operation will be stored extern void finishUndo(); /// this is dangerous and for internal use only @@ -40,9 +38,6 @@ extern void setRedo(BufferView *, Undo::undo_kind kind, Paragraph const * first, Paragraph const * behind); /// -extern Undo * createUndo(BufferView *, Undo::undo_kind kind, - Paragraph const * first, Paragraph const * behind); -/// for external use in lyx_cb.C extern void setCursorParUndo(BufferView *); // returns a pointer to the very first Paragraph depending of where we are @@ -53,8 +48,6 @@ /// extern LyXCursor const & undoCursor(BufferView * bv); -/// the flag used by FinishUndo(); -extern bool undo_finished; /// a flag extern bool undo_frozen; Index: src/undostack.C =================================================================== RCS file: src/undostack.C diff -N src/undostack.C --- src/undostack.C 21 Mar 2002 17:25:32 -0000 1.3 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,81 +0,0 @@ -/* This file is part of - * ====================================================== - * - * LyX, The Document Processor - * - * Copyright 1995 Matthias Ettrich - * Copyright 1995-2001 The LyX Team. - * - * ====================================================== */ - -#include <config.h> - -#ifdef __GNUG__ -#pragma implementation -#endif - -#include "undostack.h" -#include "undo.h" -#include "paragraph.h" - - -UndoStack::UndoStack() - : limit(100) {} - - -void UndoStack::pop() -{ - if (stakk.empty()) - return; - stakk.pop_front(); -} - - -Undo * UndoStack::top() const -{ - if (stakk.empty()) - return 0; - return stakk.front(); -} - - -UndoStack::~UndoStack() -{ - clear(); -} - - -void UndoStack::clear() -{ - while (!stakk.empty()) { - Undo * tmp = stakk.front(); - stakk.pop_front(); - delete tmp; - } -} - - -void UndoStack::SetStackLimit(Stakk::size_type l) -{ - limit = l; -} - - -void UndoStack::push(Undo * undo_arg) -{ - if (!undo_arg) - return; - - stakk.push_front(undo_arg); - if (stakk.size() > limit) { - Undo * tmp = stakk.back(); - stakk.pop_back(); - delete tmp; - } -} - - -bool UndoStack::empty() const -{ - return stakk.empty(); -} Index: src/undostack.h =================================================================== RCS file: src/undostack.h diff -N src/undostack.h --- src/undostack.h 21 Mar 2002 17:25:32 -0000 1.3 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,51 +0,0 @@ -// -*- C++ -*- -/* This file is part of - * ====================================================== - * - * LyX, The Document Processor - * - * Copyright 1995 Matthias Ettrich - * Copyright 1995-2001 The LyX Team. - * - * ====================================================== */ - -#ifndef UNDO_STACK_H -#define UNDO_STACK_H - -#ifdef __GNUG__ -#pragma interface -#endif - -#include <list> - -class Undo; - -/// A limited Stack for the undo informations. -class UndoStack { -private: - /// - typedef std::list<Undo*> Stakk; - /// - Stakk stakk; - /// the maximum number of undo steps stored. - Stakk::size_type limit; -public: - /// - UndoStack(); - /// - ~UndoStack(); - /// - void pop(); - /// - Undo * top() const; - /// - bool empty() const; - /// - void clear(); - /// - void SetStackLimit(Stakk::size_type l); - /// - void push(Undo * undo_arg); -}; - -#endif Index: src/support/ChangeLog =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/support/ChangeLog,v retrieving revision 1.105 diff -u -r1.105 ChangeLog --- src/support/ChangeLog 22 May 2002 01:16:37 -0000 1.105 +++ src/support/ChangeLog 22 May 2002 19:17:18 -0000 @@ -1,3 +1,7 @@ +2002-05-22 John Levon <[EMAIL PROTECTED]> + + * limited_stack.h: new managed stack template + 2002-05-22 Lars Gullik Bjønnes <[EMAIL PROTECTED]> * forkedcall.h: use more specific smart_ptr header. Index: src/support/limited_stack.h =================================================================== RCS file: src/support/limited_stack.h diff -N src/support/limited_stack.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/support/limited_stack.h 22 May 2002 19:17:20 -0000 @@ -0,0 +1,79 @@ +// -*- C++ -*- +/** + * \file limited_stack.h + * Copyright 2002 the LyX Team + * Read the file COPYING + * + * \author John Levon <[EMAIL PROTECTED]> + */ + +#ifndef LIMITED_STACK_H +#define LIMITED_STACK_H + +#include <list> + +// make non-pointer type an error. +template <typename T> +class limited_stack; + +/** + * limited_stack - a stack of limited size + * + * Like a normal stack, but only accepts pointer types, + * and bottom elements are deleted on overflow + */ +template <typename T> +class limited_stack<T*> { +public: + typedef std::list<T*> container_type; + typedef typename container_type::value_type value_type; + typedef typename container_type::size_type size_type; + + /// limit is the maximum size of the stack + limited_stack(size_type limit = 10) { + limit_ = limit; + } + + /// return the top element + value_type top() { + return c_.front(); + } + + /// pop and throw away the top element + void pop() { + c_.pop_front(); + } + + /// return true if the stack is empty + bool empty() const { + return c_.size() == 0; + } + + /// clear all elements, deleting them + void clear() { + while (!c_.empty()) { + value_type v = c_.back(); + c_.pop_back(); + delete v; + } + } + + /// push an item on to the stack, deleting the + /// bottom item on overflow. + void push(value_type const & v) { + c_.push_front(v); + if (c_.size() > limit_) { + value_type v = c_.back(); + c_.pop_back(); + delete v; + } + } + +private: + /// internal contents + container_type c_; + /// the maximum number elements stored + size_type limit_; +}; + +#endif // LIMITED_STACK_H