------------------------------------------------------------------------
Index: src/insets/insettext.h
===================================================================
--- src/insets/insettext.h (revision 13351)
+++ src/insets/insettext.h (working copy)
@@ -16,6 +16,7 @@
#include "RowList_fwd.h"
#include "lyxfont.h"
#include "lyxtext.h"
+#include "ParagraphList_fwd.h"
#include "support/types.h"
@@ -27,7 +28,6 @@
class CursorSlice;
class Dimension;
class LColor_color;
-class ParagraphList;
/**
Index: src/insets/insetbibitem.C
===================================================================
--- src/insets/insetbibitem.C (revision 13351)
+++ src/insets/insetbibitem.C (working copy)
@@ -19,7 +19,7 @@
#include "lyxfont.h"
#include "lyxlex.h"
#include "paragraph.h"
-#include "ParagraphList_fwd.h"
+#include "ParagraphList.h"
#include "frontends/font_metrics.h"
Index: src/output_plaintext.C
===================================================================
--- src/output_plaintext.C (revision 13351)
+++ src/output_plaintext.C (working copy)
@@ -19,7 +19,7 @@
#include "output.h"
#include "outputparams.h"
#include "paragraph.h"
-#include "ParagraphList_fwd.h"
+#include "ParagraphList.h"
#include "ParagraphParameters.h"
#include "support/lstrings.h"
Index: src/output_latex.h
===================================================================
--- src/output_latex.h (revision 13351)
+++ src/output_latex.h (working copy)
@@ -12,11 +12,12 @@
#ifndef OUTPUT_LATEX_H
#define OUTPUT_LATEX_H
+#include "ParagraphList_fwd.h"
+
#include <string>
class Buffer;
class OutputParams;
-class ParagraphList;
class TexRow;
/// Just a wrapper for the method below, first creating the ofstream.
Index: src/bufferlist.C
===================================================================
--- src/bufferlist.C (revision 13351)
+++ src/bufferlist.C (working copy)
@@ -22,7 +22,7 @@
#include "lyx_main.h"
#include "output_latex.h"
#include "paragraph.h"
-#include "ParagraphList_fwd.h"
+#include "ParagraphList.h"
#include "frontends/Alert.h"
Index: src/ParagraphList_fwd.h
===================================================================
--- src/ParagraphList_fwd.h (revision 13351)
+++ src/ParagraphList_fwd.h (working copy)
@@ -12,22 +12,11 @@
#ifndef PARAGRAPH_LIST_FWD_H
#define PARAGRAPH_LIST_FWD_H
-#include "paragraph.h"
+template <class T>
+class RandomAccessList;
-#include <vector>
+class Paragraph;
-class ParagraphList : public std::vector<Paragraph>
-{
-public:
- ///
- typedef std::vector<Paragraph> BaseType;
- ///
- ParagraphList();
- ///
- template <class Iter>
- ParagraphList(Iter beg, Iter end)
- : BaseType(beg, end)
- {}
-};
+typedef RandomAccessList<Paragraph> ParagraphList;
#endif
Index: src/lyxtext.h
===================================================================
--- src/lyxtext.h (revision 13351)
+++ src/lyxtext.h (working copy)
@@ -21,7 +21,7 @@
#include "lyxfont.h"
#include "layout.h"
#include "lyxlayout_ptr_fwd.h"
-#include "ParagraphList_fwd.h"
+#include "ParagraphList.h"
#include <iosfwd>
Index: src/undo.h
===================================================================
--- src/undo.h (revision 13351)
+++ src/undo.h (working copy)
@@ -17,7 +17,7 @@
#define UNDO_H
#include "dociterator.h"
-#include "ParagraphList_fwd.h"
+#include "ParagraphList.h"
#include "bufferparams.h"
#include "support/types.h"
Index: src/buffer.h
===================================================================
--- src/buffer.h (revision 13351)
+++ src/buffer.h (working copy)
@@ -15,6 +15,7 @@
#include "InsetList.h"
#include "dociterator.h"
+#include "ParagraphList_fwd.h"
#include "support/limited_stack.h"
#include "support/types.h"
@@ -42,7 +43,6 @@
class Language;
class MacroData;
class OutputParams;
-class ParagraphList;
class ParConstIterator;
class ParIterator;
class TeXErrors;
Index: src/CutAndPaste.h
===================================================================
--- src/CutAndPaste.h (revision 13351)
+++ src/CutAndPaste.h (working copy)
@@ -14,6 +14,8 @@
#ifndef CUTANDPASTE_H
#define CUTANDPASTE_H
+#include "ParagraphList_fwd.h"
+
#include "support/types.h"
#include <string>
@@ -23,7 +25,6 @@
class ErrorList;
class LyXTextClass;
class LCursor;
-class ParagraphList;
///
namespace lyx {
Index: src/support/RandomAccessList.h
===================================================================
--- src/support/RandomAccessList.h (revision 0)
+++ src/support/RandomAccessList.h (revision 0)
@@ -0,0 +1,479 @@
+// -*- C++ -*-
+/**
+ * \file RandomAccessList.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ *
+ */
+
+#ifndef RANDOM_ACESS_LIST_H
+#define RANDOM_ACESS_LIST_H
+
+//#include "debug.h"
+
+#include <boost/utility.hpp>
+
+#include <vector>
+#include <list>
+#include <algorithm>
+
+/// Random Access List.
+/**
+This templatized class provide a std::vector like interface to a
+standard std::list underneath. An important property is that it
+keeps the std::list::iterator interface. A typical use would be:
+
+ typedef RandomAccessList<some_class> MyContainer;
+
+Then you can use MyContainer as if it was a standard
+std::vector<some_class> for operator[] access and as if it was a
+standard std::list for iterator access. The main difference with
+std::vector is that insertion of elements is much less costly. Compared
+to a standard list alone, there is of course a small overhead because
+the class always keeps its internal vector of iterator (it_vector_) up
+to date.
+*/
+template <class T>
+class RandomAccessList {
+protected:
+ typedef std::list<T> Container;
+ typedef typename Container::const_iterator BaseConstIt;
+ typedef typename Container::iterator BaseIt;
+public:
+ typedef T value_type;
+ typedef typename Container::difference_type difference_type;
+ typedef size_t size_type;
+
+ ///
+ class iterator: public Container::iterator {
+ public:
+ iterator()
+ {}
+
+ iterator(BaseIt const & it)
+ {
+ Container::iterator::operator=(it);
+ }
+ iterator & operator+=(difference_type pos)
+ {
+ std::advance(*this, pos);
+ return *this;
+ }
+ iterator operator+(difference_type pos) const
+ {
+ return boost::next(*this,pos);
+ }
+ difference_type operator-(iterator it2) const
+ {
+ return std::distance(it2, *this);
+ }
+ };
+
+ ///
+ class const_iterator: public Container::const_iterator {
+ public:
+ const_iterator()
+ {}
+
+ const_iterator(BaseConstIt const & it)
+ {
+ Container::const_iterator::operator=(it);
+ }
+ const_iterator(iterator const & it)
+ {
+
Container::const_iterator::operator=(static_cast<BaseIt>(it));
+ }
+ const_iterator & operator+=(difference_type pos)
+ {
+ std::advance(*this, pos);
+ return *this;
+ }
+ const_iterator operator+(difference_type pos) const
+ {
+ return boost::next(*this, pos);
+ }
+ difference_type operator-(const_iterator it2) const
+ {
+ return std::distance(it2, *this);
+ }
+ };
+
+private:
+ /// Our container.
+ Container container_;
+ /// Our vector of container iterators.
+ std::vector<iterator> it_vector_;
+public:
+ ///
+ RandomAccessList()
+ {}
+
+ /// Copy constructor.
+ RandomAccessList(RandomAccessList const & ext_list)
+ {
+ it_vector_.reserve(ext_list.size());
+ size_t const end = ext_list.size();
+ for (size_t i = 0; i != end; ++i)
+ push_back(ext_list[i]);
+ }
+
+ /// Partial copy constructor.
+ /**
+ Copy "length" elements from ext_list beginning at pos.
+ */
+ RandomAccessList(RandomAccessList const & ext_list,
+ size_t pos, size_t length)
+ {
+ it_vector_.reserve(length);
+ size_t const end = pos + length;
+ //BOOST_ASSERT(end <= ext_list.size());
+ for (size_t i = pos; i != end; ++i)
+ push_back(ext_list[i]);
+ }
+
+ /// Construct a new RandomAccessList by copying elements
+ /// pointed from it_start to it_end.
+ template<class It>
+ RandomAccessList(It it_start, It it_end)
+ {
+ for (It it = it_start; it != it_end; ++it)
+ push_back(*it);
+ }
+
+ ///
+ value_type & operator[](size_t pos)
+ {
+ return at(pos);
+ }
+
+ ///
+ value_type const & operator[](size_t pos) const
+ {
+ return at(pos);
+ }
+
+ ///
+ iterator operator()(size_t pos)
+ {
+ return it_vector_[pos];
+ }
+
+ ///
+ const_iterator operator()(size_t pos) const
+ {
+ return it_vector_[pos];
+ }
+
+ ///
+ RandomAccessList & operator=(RandomAccessList const & ext_list)
+ {
+ assign(ext_list);
+ return *this;
+ }
+
+ /// Copy ext_list.
+ void assign(RandomAccessList const & ext_list)
+ {
+ assign(ext_list, 0, ext_list.size());
+ }
+
+ /// Copy ext_list from it_start to it_end.
+ template<class It>
+ void assign(It it_start, It it_end)
+ {
+ clear();
+ for (It it = it_start; it != it_end; ++it)
+ push_back(*it);
+ }
+
+ /// Copy "length" elements from ext_list beginning at pos.
+ void assign(RandomAccessList const & ext_list,
+ size_t pos, size_t length)
+ {
+ clear();
+ size_t const end = pos + length;
+ for (size_t i = pos; i != end; ++i)
+ push_back(ext_list[i]);
+ }
+
+ value_type & at(size_t pos)
+ {
+ // Make sure it_vector_ and container_ are always in sync.
+ //BOOST_ASSERT(it_vector_[pos] ==
boost::next(container_.begin(),pos));
+ return *it_vector_[pos];
+ }
+
+ /// \todo remove first test (pos >= it_vector_.size()) when output_*.C
has been verified.
+ value_type const & at(size_t pos) const
+ {
+ // Make sure it_vector_ and container_ are always in sync.
+ //BOOST_ASSERT(it_vector_[pos] ==
boost::next(container_.begin(),pos));
+ return *it_vector_[pos];
+ }
+
+ size_t size() const
+ {
+ return it_vector_.size();
+ }
+
+ const_iterator begin() const
+ {
+ return container_.begin();
+ }
+
+ iterator begin()
+ {
+ return container_.begin();
+ }
+
+ const_iterator end() const
+ {
+ return container_.end();
+ }
+
+ iterator end()
+ {
+ return container_.end();
+ }
+
+ value_type & back()
+ {
+ return container_.back();
+ }
+
+ value_type const & back() const
+ {
+ return container_.back();
+ }
+
+ value_type & front()
+ {
+ return container_.front();
+ }
+
+ value_type const & front() const
+ {
+ return container_.front();
+ }
+
+ bool empty() const
+ {
+ return container_.empty();
+ }
+
+ void clear()
+ {
+ container_.clear();
+ it_vector_.clear();
+ }
+
+ /// Erases 'length' elements starting from pos.
+ /**
+ \todo This could be optimized a bit by rebuilding ItVector instead of
multiple deletion.
+
+ Comments from Angus: use std::remove_if and vector<>::erase, passing the
+ same predicate to remove_if as is used by erase(size_t);
+ Refactor the other erase() member funtions to use this predicate
+ also?
+ std::remove_if doesn't actually remove anything from the vector. It
simply rearranges the
+ contents so that the stuff to be removed is all at the end, making it
trivial
+ (and cheap) to then used "itVector_.erase(it, itVector_.end());" to
resize the
+ vector. (it here is the iterator returned by std::remove_if). You just
need to
+ write the predicate that would actually flag up elements for removal.
+ */
+ bool erase(size_t pos, size_t length)
+ {
+ bool result = true;
+ size_t const end = pos + length;
+ for (size_t i = pos; i != end; ++i)
+ result = result && erase(i);
+
+ return result;
+ }
+
+ /// Erases last element.
+ void pop_back()
+ {
+ //lyxerr[Debug::ACTION] << "pop_back from Container"<<
std::endl;
+ container_.pop_back();
+ it_vector_.pop_back();
+ //lyxerr[Debug::ACTION] << "pop_back done"<< std::endl;
+ }
+
+ /// Erases the element at position pos.
+ bool erase(size_t pos)
+ {
+ if (pos >= it_vector_.size()) {
+ //lyxerr[Debug::ACTION] << "trying to erase element at "
+ // << pos << " while size is "
+ // << size() << std::endl;
+ // What happened here?
+ return false;
+ }
+
+ if (pos == it_vector_.size() - 1) {
+ pop_back();
+ return true;
+ }
+
+ //lyxerr[Debug::ACTION] << "erasing element from Container at "
+ // << pos << std::endl;
+ container_.erase(it_vector_[pos]);
+ it_vector_.erase(it_vector_.begin() + pos);
+ //lyxerr[Debug::ACTION] << "erasing done"<< std::endl;
+ return true;
+ }
+
+ bool erase(iterator it)
+ {
+ size_t const pos = std::distance(container_.begin(),
+ static_cast<BaseIt>(it));
+ return erase(pos);
+ }
+
+ bool erase(iterator start, iterator end)
+ {
+ size_t const startpos = std::distance(container_.begin(),
+
static_cast<BaseIt>(start));
+ size_t const endpos = std::distance(container_.begin(),
+ static_cast<BaseIt>(end));
+ return erase(startpos, endpos - startpos);
+ }
+
+ void push_back(value_type const & new_element)
+ {
+ //lyxerr[Debug::ACTION] << "push_back new_element in Container"
+ // << std::endl;
+ iterator it = container_.insert(container_.end(), new_element);
+ it_vector_.push_back(it);
+ //lyxerr[Debug::ACTION] << "push_back done"<< std::endl;
+ }
+
+ /// Inserts the contents of an external container at position pos.
+ /**
+ The subsequent elements are shifted toward the end.
+
+ \todo This could be optimized a bit by rebuilding ItVector instead of
multiple insertion.
+ */
+ template<class SomeContainer>
+ bool insert(size_t pos, SomeContainer const & some_container)
+ {
+ bool result = true;
+ size_t i = pos;
+ typedef typename SomeContainer::const_iterator Cit;
+ Cit cit = some_container.begin();
+ Cit cend = some_container.end();
+ for (; cit != cend; ++cit, ++i) {
+ result = result && insert(i, *cit);
+ }
+ return result;
+ }
+
+ /// Inserts an external RandomAccessList at position pos.
+ /**
+ The subsequent elements are shifted toward the end.
+
+ \todo This could be optimized a bit by rebuilding ItVector instead of
multiple insertion
+ and maybe using list::splice.
+ */
+ bool insert(size_t pos, RandomAccessList const & ext_list, size_t
ext_pos, size_t length)
+ {
+ bool result = true;
+ size_t i = pos;
+ size_t const ext_end = ext_pos + length;
+ for (size_t j = ext_pos; j != ext_end; ++j) {
+ result = result && insert(i, ext_list[j]);
+ ++i;
+ }
+ return result;
+ }
+
+ /// Inserts external elements pointed by iterator it_start and it_end
at position pos.
+ /**
+ The subsequent elements are shifted toward the end.
+ \return the position after the last inserted element.
+
+ \todo This could be optimized a bit by rebuilding ItVector instead of
multiple insertion
+ and maybe using list::splice.
+ */
+ template<class It>
+ size_t insert(size_t pos, It it_start, It it_end)
+ {
+ bool result = true;
+ size_t i = pos;
+ for (It it = it_start; it != it_end; ++it) {
+ result = result && insert(i, *it);
+ ++i;
+ }
+ if (result)
+ return i;
+
+ return size();
+ }
+
+ /// Inserts external elements pointed by iterator it_start and it_end
before element pointed by it.
+ /**
+ The subsequent elements are shifted toward the end.
+ \return the iterator after the last inserted element.
+
+ \todo This could be optimized a bit by rebuilding ItVector instead of
multiple insertion
+ and maybe using list::splice.
+ */
+ template<class It>
+ iterator insert(iterator it, It it_start, It it_end)
+ {
+ size_t pos = std::distance(container_.begin(),
+ static_cast<BaseIt>(it));
+ pos = insert(pos, it_start, it_end);
+ if (pos < size())
+ return it_vector_[pos];
+
+ return container_.end();
+ }
+
+ /// Inserts new_element at position pos.
+ /// The subsequent value_types are shifted toward the end.
+ bool insert(size_t pos, value_type const & new_element)
+ {
+ if (pos > it_vector_.size()) {
+ //lyxerr[Debug::ACTION] << "trying to insert element at " << pos << "
while size is "<< size() << std::endl;
+ // What happened here?
+ return false;
+ }
+
+ if (pos == it_vector_.size()) {
+ push_back(new_element);
+ return true;
+ }
+
+ //lyxerr[Debug::ACTION]
+ // << "inserting new_element in Container at "
+ // << pos << std::endl;
+ iterator it = container_.insert(it_vector_[pos], new_element);
+ it_vector_.insert(it_vector_.begin() + pos, it);
+ //lyxerr[Debug::ACTION] << "insertion done"<< std::endl;
+ return true;
+ }
+
+ /// Inserts new_element before element pointed by iterator it.
+ /**
+ \return The iterator pointing to the newly inserted element
+ or container_.end() if the insertion did not succeed.
+ */
+ iterator insert(iterator it, value_type const & new_element)
+ {
+ size_t const pos = std::distance(container_.begin(),
+ static_cast<BaseIt>(it));
+ if (insert(pos, new_element))
+ return it_vector_[pos];
+
+ return container_.end();
+ }
+
+}; // RandomAccessList
+
+#endif
Index: src/pariterator.h
===================================================================
--- src/pariterator.h (revision 13351)
+++ src/pariterator.h (working copy)
@@ -13,6 +13,7 @@
#define PARITERATOR_H
#include "dociterator.h"
+#include "ParagraphList_fwd.h"
#include "support/types.h"
@@ -24,7 +25,6 @@
class InsetBase;
class LyXText;
-class ParagraphList;
class ParIterator : public std::iterator<std::forward_iterator_tag, Paragraph>,
Index: src/output_linuxdoc.C
===================================================================
--- src/output_linuxdoc.C (revision 13351)
+++ src/output_linuxdoc.C (working copy)
@@ -17,7 +17,7 @@
#include "bufferparams.h"
#include "paragraph.h"
#include "paragraph_funcs.h"
-#include "ParagraphList_fwd.h"
+#include "ParagraphList.h"
#include "ParagraphParameters.h"
#include "sgml.h"
Index: src/ParagraphList.h
===================================================================
--- src/ParagraphList.h (revision 0)
+++ src/ParagraphList.h (revision 0)
@@ -0,0 +1,22 @@
+// -*- C++ -*-
+/**
+ * \file ParagraphList_fwd.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Angus Leeming
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef PARAGRAPH_LIST_H
+#define PARAGRAPH_LIST_H
+
+#include "paragraph.h"
+
+#include "support/RandomAccessList.h"
+
+/// Container for all kind of Paragraphs used in Lyx.
+typedef RandomAccessList<Paragraph> ParagraphList;
+
+#endif
Index: src/paragraph_funcs.h
===================================================================
--- src/paragraph_funcs.h (revision 13351)
+++ src/paragraph_funcs.h (working copy)
@@ -12,6 +12,8 @@
#ifndef PARAGRAPH_FUNCS_H
#define PARAGRAPH_FUNCS_H
+#include "ParagraphList_fwd.h"
+
#include "support/types.h"
class Buffer;
@@ -19,7 +21,6 @@
class InsetBase;
class LyXFont;
class Paragraph;
-class ParagraphList;
/**
* This breaks a paragraph at the specified position.
Index: src/output_docbook.C
===================================================================
--- src/output_docbook.C (revision 13351)
+++ src/output_docbook.C (working copy)
@@ -20,7 +20,7 @@
#include "debug.h"
#include "paragraph.h"
#include "paragraph_funcs.h"
-#include "ParagraphList_fwd.h"
+#include "ParagraphList.h"
#include "ParagraphParameters.h"
#include "sgml.h"
Index: src/output_linuxdoc.h
===================================================================
--- src/output_linuxdoc.h (revision 13351)
+++ src/output_linuxdoc.h (working copy)
@@ -13,10 +13,11 @@
#ifndef OUTPUT_LINUXDOC_H
#define OUTPUT_LINUXDOC_H
+#include "ParagraphList_fwd.h"
+
#include <iosfwd>
class Buffer;
-class ParagraphList;
class OutputParams;
///
Index: src/output_docbook.h
===================================================================
--- src/output_docbook.h (revision 13351)
+++ src/output_docbook.h (working copy)
@@ -13,11 +13,12 @@
#ifndef OUTPUT_DOCBOOK_H
#define OUTPUT_DOCBOOK_H
+#include "ParagraphList_fwd.h"
+
#include <iosfwd>
class Buffer;
class OutputParams;
-class ParagraphList;
///
void docbookParagraphs(ParagraphList const & subset,
Index: src/paragraph.C
===================================================================
--- src/paragraph.C (revision 13351)
+++ src/paragraph.C (working copy)
@@ -66,10 +66,6 @@
using std::ostringstream;
-ParagraphList::ParagraphList()
-{}
-
-
Paragraph::Paragraph()
: begin_of_body_(0), pimpl_(new Paragraph::Pimpl(this))
{
Index: src/buffer_funcs.C
===================================================================
--- src/buffer_funcs.C (revision 13351)
+++ src/buffer_funcs.C (working copy)
@@ -27,7 +27,7 @@
#include "lyxtextclass.h"
#include "paragraph.h"
#include "paragraph_funcs.h"
-#include "ParagraphList_fwd.h"
+#include "ParagraphList.h"
#include "ParagraphParameters.h"
#include "pariterator.h"
#include "lyxvc.h"
------------------------------------------------------------------------