diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2019-07-03 12:59:59 +0200 |
---|---|---|
committer | Michael Stahl <Michael.Stahl@cib.de> | 2019-07-03 16:01:52 +0200 |
commit | b5b607cf5afe6ebf5964102770a52965f5b98533 (patch) | |
tree | 1768350ebceaf44578e3976e66de7653ce9ae6bc /sw/inc/IDocumentMarkAccess.hxx | |
parent | 760801be6db08abca69d65f754cb66317168d0cb (diff) |
sw: remove dynamic_cast to MarkBase in MarkManager
Forward port of https://gerrit.libreoffice.org/#/c/74851/
and much smaller because the shared_ptr has been removed in commit
9ff648c691f003a11eba9a22ac37032d72b4b642
The MarkManager always has MarkBase instances in its vectors, so
abstract the vector better in the IDocumentMarkAccess interface by
exposing only a wrapper iterator that converts from MarkBase to
IMark.
There is an unexpected pitfall here in that forward iterator's
operator* is required to return a reference, but at least for a
const_iterator it appears to work to just return a value instead.
The dynamic_cast of every element in some MarkManager functions is
quite expensive and shows as 10-15% in callgrind.
In bubli's measurements, in the 6.1 branch this speeds up loading the
bugdoc by ~40s of the initial 3min 50s.
Change-Id: I65d974bea0301bf7b4cfa25ad6daae10b6768202
Reviewed-on: https://gerrit.libreoffice.org/75033
Tested-by: Jenkins
Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
Diffstat (limited to 'sw/inc/IDocumentMarkAccess.hxx')
-rw-r--r-- | sw/inc/IDocumentMarkAccess.hxx | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx index cbdaa7b35233..207c91caae37 100644 --- a/sw/inc/IDocumentMarkAccess.hxx +++ b/sw/inc/IDocumentMarkAccess.hxx @@ -31,6 +31,7 @@ class SwCursorShell; namespace sw { namespace mark { class SaveBookmark; // FIXME: Ugly: SaveBookmark is a core-internal class, and should not be used in the interface + class MarkBase; }} /** Provides access to the marks of a document. @@ -52,10 +53,59 @@ class IDocumentMarkAccess NAVIGATOR_REMINDER }; - typedef std::vector< ::sw::mark::IMark* > container_t; - typedef container_t::iterator iterator_t; - typedef container_t::const_iterator const_iterator_t; - typedef container_t::const_reverse_iterator const_reverse_iterator_t; + /** wrapper iterator: wraps iterator of implementation while hiding + MarkBase class; only IMark instances can be retrieved directly. + */ + class SW_DLLPUBLIC iterator + { + private: + std::unique_ptr<std::vector<::sw::mark::MarkBase*>::const_iterator> m_pIter; + + public: + // MarkManager implementation needs to get the real iterator + std::vector<::sw::mark::MarkBase*>::const_iterator const& get() const; + + typedef std::ptrdiff_t difference_type; + typedef ::sw::mark::IMark* value_type; + typedef ::sw::mark::IMark* const* pointer; + typedef ::sw::mark::IMark* const& reference; + typedef std::random_access_iterator_tag iterator_category; + + iterator(); + iterator(std::vector<::sw::mark::MarkBase*>::const_iterator const& rIter); + iterator(iterator const& rOther); + iterator& operator=(iterator const& rOther); + iterator(iterator && rOther); + iterator& operator=(iterator && rOther); + ~iterator(); + + // FIXME unfortuntately there's a requirement on input iterator + // and forward iterator to return reference, which isn't + // possible because we have to return a temp value; + // let's try value_type instead, perhaps it's sufficient, + // for a const_iterator... + ::sw::mark::IMark* /*const&*/ operator*() const; + // nope can't do that :( + //::sw::mark::IMark* /* const* */ operator->() const; + iterator& operator++(); + iterator operator++(int); + bool operator==(iterator const& rOther) const; + bool operator!=(iterator const& rOther) const; + iterator& operator--(); + iterator operator--(int); + iterator& operator+=(difference_type); + iterator operator+(difference_type) const; + iterator& operator-=(difference_type); + iterator operator-(difference_type) const; + difference_type operator-(iterator const&) const; + value_type operator[](difference_type) const; + bool operator<(iterator const& rOther) const; + bool operator>(iterator const& rOther) const; + bool operator<=(iterator const& rOther) const; + bool operator>=(iterator const& rOther) const; + }; + + typedef iterator const_iterator_t; /// To avoid recursive calls of deleteMark, the removal of dummy /// characters of fieldmarks has to be delayed; this is the baseclass |