# HG changeset patch
# User Neil <nyamatongwe@gmail.com>
# Date 1522194824 -39600
#      Wed Mar 28 10:53:44 2018 +1100
# Node ID 34c198741fc0922833014fa845bebdf828609d76
# Parent  ee311138a03981cf9bca527d4eeed1f0207d33e0
Templatize decorations to allow 32-bit or 64-bit positions.

diff -r ee311138a039 -r 34c198741fc0 src/Decoration.cxx
--- a/src/Decoration.cxx	Wed Mar 28 10:08:25 2018 +1100
+++ b/src/Decoration.cxx	Wed Mar 28 10:53:44 2018 +1100
@@ -28,10 +28,11 @@
 
 namespace {
 
+template <typename POS>
 class Decoration : public IDecoration {
 	int indicator;
 public:
-	RunStyles<Sci::Position, int> rs;
+	RunStyles<POS, int> rs;
 
 	explicit Decoration(int indicator_) : indicator(indicator_) {
 	}
@@ -48,37 +49,38 @@
 		return rs.Length();
 	}
 	int ValueAt(Sci::Position position) const override {
-		return rs.ValueAt(static_cast<Sci::Position>(position));
+		return rs.ValueAt(static_cast<POS>(position));
 	}
 	Sci::Position StartRun(Sci::Position position) const override {
-		return rs.StartRun(static_cast<Sci::Position>(position));
+		return rs.StartRun(static_cast<POS>(position));
 	}
 	Sci::Position EndRun(Sci::Position position) const override {
-		return rs.EndRun(static_cast<Sci::Position>(position));
+		return rs.EndRun(static_cast<POS>(position));
 	}
 	void SetValueAt(Sci::Position position, int value) override {
-		rs.SetValueAt(static_cast<Sci::Position>(position), value);
+		rs.SetValueAt(static_cast<POS>(position), value);
 	}
 	void InsertSpace(Sci::Position position, Sci::Position insertLength) override {
-		rs.InsertSpace(static_cast<Sci::Position>(position), static_cast<Sci::Position>(insertLength));
+		rs.InsertSpace(static_cast<POS>(position), static_cast<POS>(insertLength));
 	}
 	Sci::Position Runs() const override {
 		return rs.Runs();
 	}
 };
 
+template <typename POS>
 class DecorationList : public IDecorationList {
 	int currentIndicator;
 	int currentValue;
-	Decoration *current;	// Cached so FillRange doesn't have to search for each call.
+	Decoration<POS> *current;	// Cached so FillRange doesn't have to search for each call.
 	Sci::Position lengthDocument;
 	// Ordered by indicator
-	std::vector<std::unique_ptr<Decoration>> decorationList;
+	std::vector<std::unique_ptr<Decoration<POS>>> decorationList;
 	std::vector<const IDecoration*> decorationView;	// Read-only view of decorationList
 	bool clickNotified;
 
-	Decoration *DecorationFromIndicator(int indicator);
-	Decoration *Create(int indicator, Sci::Position length);
+	Decoration<POS> *DecorationFromIndicator(int indicator);
+	Decoration<POS> *Create(int indicator, Sci::Position length);
 	void Delete(int indicator);
 	void DeleteAnyEmpty();
 	void SetView();
@@ -118,16 +120,19 @@
 	}
 };
 
-DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(nullptr),
+template <typename POS>
+DecorationList<POS>::DecorationList() : currentIndicator(0), currentValue(1), current(nullptr),
 	lengthDocument(0), clickNotified(false) {
 }
 
-DecorationList::~DecorationList() {
+template <typename POS>
+DecorationList<POS>::~DecorationList() {
 	current = nullptr;
 }
 
-Decoration *DecorationList::DecorationFromIndicator(int indicator) {
-	for (const std::unique_ptr<Decoration> &deco : decorationList) {
+template <typename POS>
+Decoration<POS> *DecorationList<POS>::DecorationFromIndicator(int indicator) {
+	for (const std::unique_ptr<Decoration<POS>> &deco : decorationList) {
 		if (deco->Indicator() == indicator) {
 			return deco.get();
 		}
@@ -135,17 +140,18 @@
 	return nullptr;
 }
 
-Decoration *DecorationList::Create(int indicator, Sci::Position length) {
+template <typename POS>
+Decoration<POS> *DecorationList<POS>::Create(int indicator, Sci::Position length) {
 	currentIndicator = indicator;
-	std::unique_ptr<Decoration> decoNew = std::make_unique<Decoration>(indicator);
-	decoNew->rs.InsertSpace(0, length);
+	std::unique_ptr<Decoration<POS>> decoNew = std::make_unique<Decoration<POS>>(indicator);
+	decoNew->rs.InsertSpace(0, static_cast<POS>(length));
 
-	std::vector<std::unique_ptr<Decoration>>::iterator it = std::lower_bound(
+	typename std::vector<std::unique_ptr<Decoration<POS>>>::iterator it = std::lower_bound(
 		decorationList.begin(), decorationList.end(), decoNew,
-		[](const std::unique_ptr<Decoration> &a, const std::unique_ptr<Decoration> &b) {
+		[](const std::unique_ptr<Decoration<POS>> &a, const std::unique_ptr<Decoration<POS>> &b) {
 		return a->Indicator() < b->Indicator();
 	});
-	std::vector<std::unique_ptr<Decoration>>::iterator itAdded =
+	typename std::vector<std::unique_ptr<Decoration<POS>>>::iterator itAdded =
 		decorationList.insert(it, std::move(decoNew));
 
 	SetView();
@@ -153,54 +159,62 @@
 	return itAdded->get();
 }
 
-void DecorationList::Delete(int indicator) {
+template <typename POS>
+void DecorationList<POS>::Delete(int indicator) {
 	decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(),
-		[=](const std::unique_ptr<Decoration> &deco) {
+		[=](const std::unique_ptr<Decoration<POS>> &deco) {
 		return deco->Indicator() == indicator;
 	}), decorationList.end());
 	current = nullptr;
 	SetView();
 }
 
-void DecorationList::SetCurrentIndicator(int indicator) {
+template <typename POS>
+void DecorationList<POS>::SetCurrentIndicator(int indicator) {
 	currentIndicator = indicator;
 	current = DecorationFromIndicator(indicator);
 	currentValue = 1;
 }
 
-void DecorationList::SetCurrentValue(int value) {
+template <typename POS>
+void DecorationList<POS>::SetCurrentValue(int value) {
 	currentValue = value ? value : 1;
 }
 
-FillResult<Sci::Position> DecorationList::FillRange(Sci::Position position, int value, Sci::Position fillLength) {
+template <typename POS>
+FillResult<Sci::Position> DecorationList<POS>::FillRange(Sci::Position position, int value, Sci::Position fillLength) {
 	if (!current) {
 		current = DecorationFromIndicator(currentIndicator);
 		if (!current) {
 			current = Create(currentIndicator, lengthDocument);
 		}
 	}
-	const FillResult<Sci::Position> fr = current->rs.FillRange(position, value, fillLength);
-	if (current->Empty()) {
+	// Converting result from POS to Sci::Position as callers not polymorphic.
+	const FillResult<POS> frInPOS = current->rs.FillRange(static_cast<POS>(position), value, static_cast<POS>(fillLength));
+	const FillResult<Sci::Position> fr { frInPOS.changed, frInPOS.position, frInPOS.fillLength };
+		if (current->Empty()) {
 		Delete(currentIndicator);
 	}
 	return fr;
 }
 
-void DecorationList::InsertSpace(Sci::Position position, Sci::Position insertLength) {
+template <typename POS>
+void DecorationList<POS>::InsertSpace(Sci::Position position, Sci::Position insertLength) {
 	const bool atEnd = position == lengthDocument;
 	lengthDocument += insertLength;
-	for (const std::unique_ptr<Decoration> &deco : decorationList) {
-		deco->rs.InsertSpace(position, insertLength);
+	for (const std::unique_ptr<Decoration<POS>> &deco : decorationList) {
+		deco->rs.InsertSpace(static_cast<POS>(position), static_cast<POS>(insertLength));
 		if (atEnd) {
-			deco->rs.FillRange(position, 0, insertLength);
+			deco->rs.FillRange(static_cast<POS>(position), 0, static_cast<POS>(insertLength));
 		}
 	}
 }
 
-void DecorationList::DeleteRange(Sci::Position position, Sci::Position deleteLength) {
+template <typename POS>
+void DecorationList<POS>::DeleteRange(Sci::Position position, Sci::Position deleteLength) {
 	lengthDocument -= deleteLength;
-	for (const std::unique_ptr<Decoration> &deco : decorationList) {
-		deco->rs.DeleteRange(position, deleteLength);
+	for (const std::unique_ptr<Decoration<POS>> &deco : decorationList) {
+		deco->rs.DeleteRange(static_cast<POS>(position), static_cast<POS>(deleteLength));
 	}
 	DeleteAnyEmpty();
 	if (decorationList.size() != decorationView.size()) {
@@ -210,37 +224,41 @@
 	}
 }
 
-void DecorationList::DeleteLexerDecorations() {
+template <typename POS>
+void DecorationList<POS>::DeleteLexerDecorations() {
 	decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(),
-		[=](const std::unique_ptr<Decoration> &deco) {
+		[=](const std::unique_ptr<Decoration<POS>> &deco) {
 		return deco->Indicator() < INDIC_CONTAINER;
 	}), decorationList.end());
 	current = nullptr;
 	SetView();
 }
 
-void DecorationList::DeleteAnyEmpty() {
+template <typename POS>
+void DecorationList<POS>::DeleteAnyEmpty() {
 	if (lengthDocument == 0) {
 		decorationList.clear();
 	} else {
 		decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(),
-			[=](const std::unique_ptr<Decoration> &deco) {
+			[=](const std::unique_ptr<Decoration<POS>> &deco) {
 			return deco->Empty();
 		}), decorationList.end());
 	}
 }
 
-void DecorationList::SetView() {
+template <typename POS>
+void DecorationList<POS>::SetView() {
 	decorationView.clear();
-	for (const std::unique_ptr<Decoration> &deco : decorationList) {
+	for (const std::unique_ptr<Decoration<POS>> &deco : decorationList) {
 		decorationView.push_back(deco.get());
 	}
 }
 
-int DecorationList::AllOnFor(Sci::Position position) const {
+template <typename POS>
+int DecorationList<POS>::AllOnFor(Sci::Position position) const {
 	int mask = 0;
-	for (const std::unique_ptr<Decoration> &deco : decorationList) {
-		if (deco->rs.ValueAt(position)) {
+	for (const std::unique_ptr<Decoration<POS>> &deco : decorationList) {
+		if (deco->rs.ValueAt(static_cast<POS>(position))) {
 			if (deco->Indicator() < INDIC_IME) {
 				mask |= 1 << deco->Indicator();
 			}
@@ -249,26 +267,29 @@
 	return mask;
 }
 
-int DecorationList::ValueAt(int indicator, Sci::Position position) {
-	const Decoration *deco = DecorationFromIndicator(indicator);
+template <typename POS>
+int DecorationList<POS>::ValueAt(int indicator, Sci::Position position) {
+	const Decoration<POS> *deco = DecorationFromIndicator(indicator);
 	if (deco) {
-		return deco->rs.ValueAt(position);
+		return deco->rs.ValueAt(static_cast<POS>(position));
 	}
 	return 0;
 }
 
-Sci::Position DecorationList::Start(int indicator, Sci::Position position) {
-	const Decoration *deco = DecorationFromIndicator(indicator);
+template <typename POS>
+Sci::Position DecorationList<POS>::Start(int indicator, Sci::Position position) {
+	const Decoration<POS> *deco = DecorationFromIndicator(indicator);
 	if (deco) {
-		return deco->rs.StartRun(position);
+		return deco->rs.StartRun(static_cast<POS>(position));
 	}
 	return 0;
 }
 
-Sci::Position DecorationList::End(int indicator, Sci::Position position) {
-	const Decoration *deco = DecorationFromIndicator(indicator);
+template <typename POS>
+Sci::Position DecorationList<POS>::End(int indicator, Sci::Position position) {
+	const Decoration<POS> *deco = DecorationFromIndicator(indicator);
 	if (deco) {
-		return deco->rs.EndRun(position);
+		return deco->rs.EndRun(static_cast<POS>(position));
 	}
 	return 0;
 }
@@ -277,12 +298,18 @@
 
 namespace Scintilla {
 
-std::unique_ptr<IDecoration> DecorationCreate(int indicator) {
-	return std::make_unique<Decoration>(indicator);
+std::unique_ptr<IDecoration> DecorationCreate(bool largeDocument, int indicator) {
+	if (largeDocument)
+		return std::make_unique<Decoration<Sci::Position>>(indicator);
+	else
+		return std::make_unique<Decoration<int>>(indicator);
 }
 
-std::unique_ptr<IDecorationList> DecorationListCreate() {
-	return std::make_unique<DecorationList>();
+std::unique_ptr<IDecorationList> DecorationListCreate(bool largeDocument) {
+	if (largeDocument)
+		return std::make_unique<DecorationList<Sci::Position>>();
+	else
+		return std::make_unique<DecorationList<int>>();
 }
 
 }
diff -r ee311138a039 -r 34c198741fc0 src/Decoration.h
--- a/src/Decoration.h	Wed Mar 28 10:08:25 2018 +1100
+++ b/src/Decoration.h	Wed Mar 28 10:53:44 2018 +1100
@@ -50,9 +50,9 @@
 	virtual void SetClickNotified(bool notified) = 0;
 };
 
-std::unique_ptr<IDecoration> DecorationCreate(int indicator);
+std::unique_ptr<IDecoration> DecorationCreate(bool largeDocument, int indicator);
 
-std::unique_ptr<IDecorationList> DecorationListCreate();
+std::unique_ptr<IDecorationList> DecorationListCreate(bool largeDocument);
 
 }
 
diff -r ee311138a039 -r 34c198741fc0 src/Document.cxx
--- a/src/Document.cxx	Wed Mar 28 10:08:25 2018 +1100
+++ b/src/Document.cxx	Wed Mar 28 10:53:44 2018 +1100
@@ -121,7 +121,7 @@
 	perLineData[ldMargin] = std::make_unique<LineAnnotation>();
 	perLineData[ldAnnotation] = std::make_unique<LineAnnotation>();
 
-	decorations = DecorationListCreate();
+	decorations = DecorationListCreate(true);
 
 	cb.SetPerLine(this);
 }
diff -r ee311138a039 -r 34c198741fc0 test/unit/testDecoration.cxx
--- a/test/unit/testDecoration.cxx	Wed Mar 28 10:08:25 2018 +1100
+++ b/test/unit/testDecoration.cxx	Wed Mar 28 10:53:44 2018 +1100
@@ -26,7 +26,7 @@
 
 TEST_CASE("Decoration") {
 
-	std::unique_ptr<IDecoration> deco = DecorationCreate(indicator);
+	std::unique_ptr<IDecoration> deco = DecorationCreate(false, indicator);
 
 	SECTION("HasCorrectIndicator") {
 		REQUIRE(indicator == deco->Indicator());
@@ -54,7 +54,7 @@
 
 TEST_CASE("DecorationList") {
 
-	std::unique_ptr<IDecorationList> decol = DecorationListCreate();
+	std::unique_ptr<IDecorationList> decol = DecorationListCreate(false);
 
 	SECTION("HasCorrectIndicator") {
 		decol->SetCurrentIndicator(indicator);
