Le 08/01/2016 08:59, Jean-Marc Lasgouttes a écrit :
The following patch fixes compilation for me with clang and libc++ (with
autotools I set CXX="clang++ --stdlib=libc++").

This is a workaround to https://llvm.org/bugs/show_bug.cgi?id=24137
to be fixed in 3.7.1 or 3.8.0.

Can someone confirm that adding the default constructor like that is
harmless?



I tried to look it up. It might work right now but I think we should
get rid of this subclassing entirely. It is just used for
forward-declaration and defining helper functions. I have a bad feeling
about starting to define custom constructors for STL containers
explicitly. The helper functions should not be there in the first place
and instead of forward-declaring we can just typedef Toc in a new header
file Toc.h. Anyway TocBackend.h has too many classes. I would say that
the attached patch is the proper solution, if you are willing to have a
look. This should be done independently of whether there is a bug in clang.


Guillaume
>From aeaf633f7449f6fa44b0d7c0aa9b1d542be276e8 Mon Sep 17 00:00:00 2001
From: Guillaume Munch <g...@lyx.org>
Date: Fri, 8 Jan 2016 19:06:50 +0000
Subject: [PATCH] Simplify class structure in TocBackend

Deriving from std::vector to provide helper functions appears a touch
excessive. Use typedef instead and move helper functions to the base class. New
header Toc.h provided to replace forward-declarations.

Remove TocIterator which is useless.

Factor code with the recent method DocIterator::getInnerText(). Small correction
in the latter to check for emptiness.
---
 src/Buffer.cpp                 |  4 ++--
 src/BufferView.cpp             |  4 ++--
 src/Changes.cpp                |  2 +-
 src/DocIterator.cpp            |  2 +-
 src/Makefile.am                |  1 +
 src/Paragraph.h                |  1 -
 src/Toc.h                      | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/TocBackend.cpp             | 36 +++++++++++++++---------------------
 src/TocBackend.h               | 40 ++++++++--------------------------------
 src/frontends/qt4/TocModel.cpp |  3 ++-
 src/frontends/qt4/TocModel.h   |  4 ++--
 src/insets/InsetTOC.h          |  3 ++-
 12 files changed, 78 insertions(+), 64 deletions(-)
 create mode 100644 src/Toc.h

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 115a542..aae1e43 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -2226,8 +2226,8 @@ void Buffer::getLabelList(vector<docstring> & list) const
 
 	list.clear();
 	shared_ptr<Toc> toc = d->toc_backend.toc("label");
-	TocIterator toc_it = toc->begin();
-	TocIterator end = toc->end();
+	Toc::const_iterator toc_it = toc->begin();
+	Toc::const_iterator end = toc->end();
 	for (; toc_it != end; ++toc_it) {
 		if (toc_it->depth() == 0)
 			list.push_back(toc_it->str());
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 7332ec5..b0801bf 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -2397,8 +2397,8 @@ void BufferView::gotoLabel(docstring const & label)
 
 		// find label
 		shared_ptr<Toc> toc = buf->tocBackend().toc("label");
-		TocIterator toc_it = toc->begin();
-		TocIterator end = toc->end();
+		Toc::const_iterator toc_it = toc->begin();
+		Toc::const_iterator end = toc->end();
 		for (; toc_it != end; ++toc_it) {
 			if (label == toc_it->str()) {
 				lyx::dispatch(toc_it->action());
diff --git a/src/Changes.cpp b/src/Changes.cpp
index 832ccac..9fa46f9 100644
--- a/src/Changes.cpp
+++ b/src/Changes.cpp
@@ -501,7 +501,7 @@ void Changes::addToToc(DocIterator const & cdit, Buffer const & buffer,
 			// ¶ U+00B6 PILCROW SIGN
 			str.push_back(0xb6);
 		docstring const & author = author_list.get(it->change.author).name();
-		Toc::iterator it = change_list->item(0, author);
+		Toc::iterator it = TocBackend::findItem(*change_list, 0, author);
 		if (it == change_list->end()) {
 			change_list->push_back(TocItem(dit, 0, author, true));
 			change_list->push_back(TocItem(dit, 1, str, output_active,
diff --git a/src/DocIterator.cpp b/src/DocIterator.cpp
index a059ad1..2ef8ddd 100644
--- a/src/DocIterator.cpp
+++ b/src/DocIterator.cpp
@@ -229,7 +229,7 @@ CursorSlice const & DocIterator::innerTextSlice() const
 DocIterator DocIterator::getInnerText() const
 {
 	DocIterator texted = *this;
-	while (!texted.inTexted()) 
+	while (texted.inMathed()) 
 		texted.pop_back();
 	return texted;
 }
diff --git a/src/Makefile.am b/src/Makefile.am
index 9446d17..098c70d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -289,6 +289,7 @@ HEADERFILESCORE = \
 	Text.h \
 	TextClass.h \
 	TextMetrics.h \
+	Toc.h \
 	TocBackend.h \
 	Trans.h \
 	Undo.h \
diff --git a/src/Paragraph.h b/src/Paragraph.h
index d0ed94b..73de6c1 100644
--- a/src/Paragraph.h
+++ b/src/Paragraph.h
@@ -49,7 +49,6 @@ class MetricsInfo;
 class OutputParams;
 class PainterInfo;
 class ParagraphParameters;
-class Toc;
 class WordLangTuple;
 class XHTMLStream;
 class otexstream;
diff --git a/src/Toc.h b/src/Toc.h
new file mode 100644
index 0000000..525b708
--- /dev/null
+++ b/src/Toc.h
@@ -0,0 +1,42 @@
+// -*- C++ -*-
+/**
+ * \file TocBackend.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Jean-Marc Lasgouttes
+ * \author Angus Leeming
+ * \author Abdelrazak Younes
+ * \author Guillaume Munch
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef TOC_H
+#define TOC_H
+
+#include "support/shared_ptr.h"
+
+#include <map>
+#include <vector>
+#include <string>
+
+
+namespace lyx {
+
+// TocItem is defined in TocBackend.h
+class TocItem;
+
+typedef std::vector<TocItem> Toc;
+
+class TocList : public std::map<std::string, shared_ptr<Toc> >
+{
+private:
+	// we forbid null pointers
+	using std::map<std::string, shared_ptr<Toc> >::operator[];
+};
+
+
+} // namespace lyx
+
+#endif // TOC_H
diff --git a/src/TocBackend.cpp b/src/TocBackend.cpp
index 9bd435f..9c12113 100644
--- a/src/TocBackend.cpp
+++ b/src/TocBackend.cpp
@@ -107,21 +107,15 @@ FuncRequest TocItem::action() const
 //
 ///////////////////////////////////////////////////////////////////////////
 
-TocIterator Toc::item(DocIterator const & dit) const
+Toc::const_iterator TocBackend::findItem(Toc const & toc,
+                                         DocIterator const & dit)
 {
-	TocIterator last = begin();
-	TocIterator it = end();
+	Toc::const_iterator last = toc.begin();
+	Toc::const_iterator it = toc.end();
 	if (it == last)
 		return it;
-
 	--it;
-
-	DocIterator dit_text = dit;
-	if (dit_text.inMathed()) {
-		// We are only interested in text so remove the math CursorSlice.
-		while (dit_text.inMathed())
-			dit_text.pop_back();
-	}
+	DocIterator dit_text = dit.getInnerText();
 
 	for (; it != last; --it) {
 		// We verify that we don't compare contents of two
@@ -138,12 +132,12 @@ TocIterator Toc::item(DocIterator const & dit) const
 }
 
 
-Toc::iterator Toc::item(int depth, docstring const & str)
+Toc::iterator TocBackend::findItem(Toc & toc, int depth, docstring const & str)
 {
-	if (empty())
-		return end();
-	iterator it = begin();
-	iterator itend = end();
+	if (toc.empty())
+		return toc.end();
+	Toc::iterator it = toc.begin();
+	Toc::iterator itend = toc.end();
 	for (; it != itend; ++it) {
 		if (it->depth() == depth && it->str() == str)
 			break;
@@ -286,7 +280,7 @@ bool TocBackend::updateItem(DocIterator const & dit_in)
 	BufferParams const & bufparams = buffer_->params();
 	const int min_toclevel = bufparams.documentClass().min_toclevel();
 
-	TocIterator toc_item = item("tableofcontents", dit);
+	Toc::const_iterator toc_item = item("tableofcontents", dit);
 
 	docstring tocstring;
 
@@ -336,14 +330,14 @@ void TocBackend::update(bool output_active, UpdateType utype)
 }
 
 
-TocIterator TocBackend::item(string const & type,
+Toc::const_iterator TocBackend::item(string const & type,
 		DocIterator const & dit) const
 {
 	TocList::const_iterator toclist_it = tocs_.find(type);
 	// Is the type supported?
 	// We will try to make the best of it in release mode
 	LASSERT(toclist_it != tocs_.end(), toclist_it = tocs_.begin());
-	return toclist_it->second->item(dit);
+	return findItem(*toclist_it->second, dit);
 }
 
 
@@ -352,8 +346,8 @@ void TocBackend::writePlaintextTocList(string const & type,
 {
 	TocList::const_iterator cit = tocs_.find(type);
 	if (cit != tocs_.end()) {
-		TocIterator ccit = cit->second->begin();
-		TocIterator end = cit->second->end();
+		Toc::const_iterator ccit = cit->second->begin();
+		Toc::const_iterator end = cit->second->end();
 		for (; ccit != end; ++ccit) {
 			os << ccit->asString() << from_utf8("\n");
 			if (os.str().size() > max_length)
diff --git a/src/TocBackend.h b/src/TocBackend.h
index d5dfae4..2520927 100644
--- a/src/TocBackend.h
+++ b/src/TocBackend.h
@@ -18,14 +18,11 @@
 #include "DocIterator.h"
 #include "FuncRequest.h"
 #include "OutputEnums.h"
+#include "Toc.h"
 
-#include "support/shared_ptr.h"
 #include "support/strfwd.h"
 
-#include <map>
-#include <vector>
 #include <stack>
-#include <string>
 
 
 namespace lyx {
@@ -67,7 +64,6 @@ enum TocType {
 */
 class TocItem
 {
-	friend class Toc;
 	friend class TocBackend;
 	friend class TocBuilder;
 
@@ -123,22 +119,6 @@ private:
 };
 
 
-///
-class Toc : public std::vector<TocItem>
-{
-public:
-	typedef std::vector<TocItem>::const_iterator const_iterator;
-	typedef std::vector<TocItem>::iterator iterator;
-	const_iterator item(DocIterator const & dit) const;
-	/// Look for a TocItem given its depth and string.
-	/// \return The first matching item.
-	/// \retval end() if no item was found.
-	iterator item(int depth, docstring const & str);
-};
-
-typedef Toc::const_iterator TocIterator;
-
-
 /// Caption-enabled TOC builders
 class TocBuilder
 {
@@ -166,16 +146,6 @@ private:
 };
 
 
-/// The ToC list.
-/// A class and no typedef because we want to forward declare it.
-class TocList : public std::map<std::string, shared_ptr<Toc> >
-{
-private:
-	// this can create null pointers
-	using std::map<std::string, shared_ptr<Toc> >::operator[];
-};
-
-
 ///
 class TocBuilderStore
 {
@@ -197,6 +167,12 @@ private:
 class TocBackend
 {
 public:
+	static Toc::const_iterator findItem(Toc const & toc,
+	                                    DocIterator const & dit);
+	/// Look for a TocItem given its depth and string.
+	/// \return The first matching item.
+	/// \retval end() if no item was found.
+	static Toc::iterator findItem(Toc & toc, int depth, docstring const & str);
 	///
 	TocBackend(Buffer const * buffer) : buffer_(buffer) {}
 	///
@@ -213,7 +189,7 @@ public:
 	/// nevel null
 	shared_ptr<TocBuilder> builder(std::string const & type);
 	/// Return the first Toc Item before the cursor
-	TocIterator item(
+	Toc::const_iterator item(
 		std::string const & type, ///< Type of Toc.
 		DocIterator const & dit ///< The cursor location in the document.
 	) const;
diff --git a/src/frontends/qt4/TocModel.cpp b/src/frontends/qt4/TocModel.cpp
index 7b4a38b..025913f 100644
--- a/src/frontends/qt4/TocModel.cpp
+++ b/src/frontends/qt4/TocModel.cpp
@@ -133,7 +133,8 @@ QModelIndex TocModel::modelIndex(DocIterator const & dit) const
 	if (toc_->empty())
 		return QModelIndex();
 
-	unsigned int const toc_index = toc_->item(dit) - toc_->begin();
+	unsigned int const toc_index = TocBackend::findItem(*toc_, dit) -
+	                               toc_->begin();
 
 	QModelIndexList list = model()->match(model()->index(0, 0), Qt::UserRole,
 		QVariant(toc_index), 1,
diff --git a/src/frontends/qt4/TocModel.h b/src/frontends/qt4/TocModel.h
index 4d4d442..c959aba 100644
--- a/src/frontends/qt4/TocModel.h
+++ b/src/frontends/qt4/TocModel.h
@@ -12,6 +12,8 @@
 #ifndef TOCMODEL_H
 #define TOCMODEL_H
 
+#include "Toc.h"
+
 #include "support/shared_ptr.h"
 
 #include <QHash>
@@ -22,8 +24,6 @@ namespace lyx {
 class Buffer;
 class BufferView;
 class DocIterator;
-class Toc;
-class TocItem;
 
 namespace frontend {
 
diff --git a/src/insets/InsetTOC.h b/src/insets/InsetTOC.h
index 074ad53..ba04b9f 100644
--- a/src/insets/InsetTOC.h
+++ b/src/insets/InsetTOC.h
@@ -14,11 +14,12 @@
 
 #include "InsetCommand.h"
 
+#include "Toc.h"
+
 
 namespace lyx {
 
 class Paragraph;
-class Toc;
 
 /// Used to insert table of contents and similar lists
 /// at present, supports only \tableofcontents and \listoflistings.
-- 
2.1.4

Reply via email to