# HG changeset patch
# User Neil <nyamatongwe@gmail.com>
# Date 1519102919 -39600
#      Tue Feb 20 16:01:59 2018 +1100
# Node ID f28d452553a8b6c375fd3fb6fe09480b0bf456c0
# Parent  1e13baeb3f82064a2384bfaa77f48e112c7f2e93
Templatize data structures that hold positions and lines so they can later be
switched between 32-bits and 64-bits.

diff -r 1e13baeb3f82 -r f28d452553a8 src/CellBuffer.cxx
--- a/src/CellBuffer.cxx	Tue Feb 20 15:31:38 2018 +1100
+++ b/src/CellBuffer.cxx	Tue Feb 20 16:01:59 2018 +1100
@@ -45,8 +45,9 @@
 
 using namespace Scintilla;
 
+template <typename POS>
 class LineVector : public ILineVector {
-	Partitioning<int> starts;
+	Partitioning<POS> starts;
 	PerLine *perLine;
 public:
 	LineVector() : starts(256), perLine(0) {
@@ -65,10 +66,10 @@
 		perLine = pl;
 	}
 	void InsertText(Sci::Line line, Sci::Position delta) override {
-		starts.InsertText(line, delta);
+		starts.InsertText(static_cast<POS>(line), static_cast<POS>(delta));
 	}
 	void InsertLine(Sci::Line line, Sci::Position position, bool lineStart) override {
-		starts.InsertPartition(line, position);
+		starts.InsertPartition(static_cast<POS>(line), static_cast<POS>(position));
 		if (perLine) {
 			if ((line > 0) && lineStart)
 				line--;
@@ -76,10 +77,10 @@
 		}
 	}
 	void SetLineStart(Sci::Line line, Sci::Position position) override {
-		starts.SetPartitionStartPosition(line, position);
+		starts.SetPartitionStartPosition(static_cast<POS>(line), static_cast<POS>(position));
 	}
 	void RemoveLine(Sci::Line line) override {
-		starts.RemovePartition(line);
+		starts.RemovePartition(static_cast<POS>(line));
 		if (perLine) {
 			perLine->RemoveLine(line);
 		}
@@ -88,10 +89,10 @@
 		return starts.Partitions();
 	}
 	Sci::Line LineFromPosition(Sci::Position pos) const override {
-		return starts.PartitionFromPosition(pos);
+		return starts.PartitionFromPosition(static_cast<POS>(pos));
 	}
 	Sci::Position LineStart(Sci::Line line) const override {
-		return starts.PositionFromPartition(line);
+		return starts.PositionFromPartition(static_cast<POS>(line));
 	}
 };
 
@@ -368,7 +369,7 @@
 	readOnly = false;
 	utf8LineEnds = 0;
 	collectingUndo = true;
-	plv.reset(new LineVector());
+	plv.reset(new LineVector<Sci::Position>());
 }
 
 CellBuffer::~CellBuffer() {
diff -r 1e13baeb3f82 -r f28d452553a8 src/ContractionState.cxx
--- a/src/ContractionState.cxx	Tue Feb 20 15:31:38 2018 +1100
+++ b/src/ContractionState.cxx	Tue Feb 20 16:01:59 2018 +1100
@@ -35,11 +35,11 @@
 
 void ContractionState::EnsureData() {
 	if (OneToOne()) {
-		visible.reset(new RunStyles<int, int>());
-		expanded.reset(new RunStyles<int, int>());
-		heights.reset(new RunStyles<int, int>());
+		visible.reset(new RunStyles<Sci::Line, char>());
+		expanded.reset(new RunStyles<Sci::Line, char>());
+		heights.reset(new RunStyles<Sci::Line, int>());
 		foldDisplayTexts.reset(new SparseVector<UniqueString>());
-		displayLines.reset(new Partitioning<int>(4));
+		displayLines.reset(new Partitioning<Sci::Line>(4));
 		InsertLines(0, linesInDocument);
 	}
 }
diff -r 1e13baeb3f82 -r f28d452553a8 src/ContractionState.h
--- a/src/ContractionState.h	Tue Feb 20 15:31:38 2018 +1100
+++ b/src/ContractionState.h	Tue Feb 20 16:01:59 2018 +1100
@@ -17,11 +17,11 @@
  */
 class ContractionState {
 	// These contain 1 element for every document line.
-	std::unique_ptr<RunStyles<int, int>> visible;
-	std::unique_ptr<RunStyles<int, int>> expanded;
-	std::unique_ptr<RunStyles<int, int>> heights;
+	std::unique_ptr<RunStyles<Sci::Line, char>> visible;
+	std::unique_ptr<RunStyles<Sci::Line, char>> expanded;
+	std::unique_ptr<RunStyles<Sci::Line, int>> heights;
 	std::unique_ptr<SparseVector<UniqueString>> foldDisplayTexts;
-	std::unique_ptr<Partitioning<int>> displayLines;
+	std::unique_ptr<Partitioning<Sci::Line>> displayLines;
 	Sci::Line linesInDocument;
 
 	void EnsureData();
diff -r 1e13baeb3f82 -r f28d452553a8 src/Decoration.cxx
--- a/src/Decoration.cxx	Tue Feb 20 15:31:38 2018 +1100
+++ b/src/Decoration.cxx	Tue Feb 20 16:01:59 2018 +1100
@@ -53,7 +53,7 @@
 	return nullptr;
 }
 
-Decoration *DecorationList::Create(int indicator, int length) {
+Decoration *DecorationList::Create(int indicator, Sci::Position length) {
 	currentIndicator = indicator;
 	std::unique_ptr<Decoration> decoNew(new Decoration(indicator));
 	decoNew->rs.InsertSpace(0, length);
@@ -90,7 +90,7 @@
 	currentValue = value ? value : 1;
 }
 
-bool DecorationList::FillRange(int &position, int value, int &fillLength) {
+bool DecorationList::FillRange(Sci::Position &position, int value, Sci::Position &fillLength) {
 	if (!current) {
 		current = DecorationFromIndicator(currentIndicator);
 		if (!current) {
@@ -104,7 +104,7 @@
 	return changed;
 }
 
-void DecorationList::InsertSpace(int position, int insertLength) {
+void DecorationList::InsertSpace(Sci::Position position, Sci::Position insertLength) {
 	const bool atEnd = position == lengthDocument;
 	lengthDocument += insertLength;
 	for (const std::unique_ptr<Decoration> &deco : decorationList) {
@@ -115,7 +115,7 @@
 	}
 }
 
-void DecorationList::DeleteRange(int position, int deleteLength) {
+void DecorationList::DeleteRange(Sci::Position position, Sci::Position deleteLength) {
 	lengthDocument -= deleteLength;
 	for (const std::unique_ptr<Decoration> &deco : decorationList) {
 		deco->rs.DeleteRange(position, deleteLength);
@@ -155,7 +155,7 @@
 	}
 }
 
-int DecorationList::AllOnFor(int position) const {
+int DecorationList::AllOnFor(Sci::Position position) const {
 	int mask = 0;
 	for (const std::unique_ptr<Decoration> &deco : decorationList) {
 		if (deco->rs.ValueAt(position)) {
@@ -167,7 +167,7 @@
 	return mask;
 }
 
-int DecorationList::ValueAt(int indicator, int position) {
+int DecorationList::ValueAt(int indicator, Sci::Position position) {
 	const Decoration *deco = DecorationFromIndicator(indicator);
 	if (deco) {
 		return deco->rs.ValueAt(position);
@@ -175,7 +175,7 @@
 	return 0;
 }
 
-int DecorationList::Start(int indicator, int position) {
+Sci::Position DecorationList::Start(int indicator, Sci::Position position) {
 	const Decoration *deco = DecorationFromIndicator(indicator);
 	if (deco) {
 		return deco->rs.StartRun(position);
@@ -183,7 +183,7 @@
 	return 0;
 }
 
-int DecorationList::End(int indicator, int position) {
+Sci::Position DecorationList::End(int indicator, Sci::Position position) {
 	const Decoration *deco = DecorationFromIndicator(indicator);
 	if (deco) {
 		return deco->rs.EndRun(position);
diff -r 1e13baeb3f82 -r f28d452553a8 src/Decoration.h
--- a/src/Decoration.h	Tue Feb 20 15:31:38 2018 +1100
+++ b/src/Decoration.h	Tue Feb 20 16:01:59 2018 +1100
@@ -12,7 +12,7 @@
 class Decoration {
 	int indicator;
 public:
-	RunStyles<int, int> rs;
+	RunStyles<Sci::Position, int> rs;
 
 	explicit Decoration(int indicator_);
 	~Decoration();
@@ -27,14 +27,14 @@
 	int currentIndicator;
 	int currentValue;
 	Decoration *current;	// Cached so FillRange doesn't have to search for each call.
-	int lengthDocument;
+	Sci::Position lengthDocument;
 	// Ordered by indicator
 	std::vector<std::unique_ptr<Decoration>> decorationList;
 	std::vector<const Decoration*> decorationView;	// Read-only view of decorationList
 	bool clickNotified;
 
 	Decoration *DecorationFromIndicator(int indicator);
-	Decoration *Create(int indicator, int length);
+	Decoration *Create(int indicator, Sci::Position length);
 	void Delete(int indicator);
 	void DeleteAnyEmpty();
 	void SetView();
@@ -52,17 +52,17 @@
 	int GetCurrentValue() const { return currentValue; }
 
 	// Returns true if some values may have changed
-	bool FillRange(int &position, int value, int &fillLength);
+	bool FillRange(Sci::Position &position, int value, Sci::Position &fillLength);
 
-	void InsertSpace(int position, int insertLength);
-	void DeleteRange(int position, int deleteLength);
+	void InsertSpace(Sci::Position position, Sci::Position insertLength);
+	void DeleteRange(Sci::Position position, Sci::Position deleteLength);
 
 	void DeleteLexerDecorations();
 
-	int AllOnFor(int position) const;
-	int ValueAt(int indicator, int position);
-	int Start(int indicator, int position);
-	int End(int indicator, int position);
+	int AllOnFor(Sci::Position position) const;
+	int ValueAt(int indicator, Sci::Position position);
+	Sci::Position Start(int indicator, Sci::Position position);
+	Sci::Position End(int indicator, Sci::Position position);
 
 	bool ClickNotified() const {
 		return clickNotified;
diff -r 1e13baeb3f82 -r f28d452553a8 src/Position.h
--- a/src/Position.h	Tue Feb 20 15:31:38 2018 +1100
+++ b/src/Position.h	Tue Feb 20 16:01:59 2018 +1100
@@ -11,7 +11,8 @@
 /**
  * A Position is a position within a document between two characters or at the beginning or end.
  * Sometimes used as a character index where it identifies the character after the position.
- * A Line is a document or screen line.
+ * A Line is a document or screen line. Since there are fewer lines in a document than bytes
+ * Line could remain 32-bit when Position is 64-bit.
  */
 
 namespace Sci {
diff -r 1e13baeb3f82 -r f28d452553a8 src/RunStyles.cxx
--- a/src/RunStyles.cxx	Tue Feb 20 15:31:38 2018 +1100
+++ b/src/RunStyles.cxx	Tue Feb 20 16:01:59 2018 +1100
@@ -304,3 +304,6 @@
 }
 
 template class Scintilla::RunStyles<int, int>;
+template class Scintilla::RunStyles<int, char>;
+template class Scintilla::RunStyles<ptrdiff_t, int>;
+template class Scintilla::RunStyles<ptrdiff_t, char>;
diff -r 1e13baeb3f82 -r f28d452553a8 src/SparseVector.h
--- a/src/SparseVector.h	Tue Feb 20 15:31:38 2018 +1100
+++ b/src/SparseVector.h	Tue Feb 20 16:01:59 2018 +1100
@@ -15,42 +15,42 @@
 template <typename T>
 class SparseVector {
 private:
-	std::unique_ptr<Partitioning<int>> starts;
+	std::unique_ptr<Partitioning<Sci::Position>> starts;
 	std::unique_ptr<SplitVector<T>> values;
 	T empty;
 	// Deleted so SparseVector objects can not be copied.
 	SparseVector(const SparseVector &) = delete;
 	void operator=(const SparseVector &) = delete;
-	void ClearValue(int partition) {
+	void ClearValue(Sci::Position partition) {
 		values->SetValueAt(partition, T());
 	}
 public:
 	SparseVector() : empty() {
-		starts.reset(new Partitioning<int>(8));
+		starts.reset(new Partitioning<Sci::Position>(8));
 		values.reset(new SplitVector<T>());
 		values->InsertEmpty(0, 2);
 	}
 	~SparseVector() {
 		starts.reset();
 		// starts dead here but not used by ClearValue.
-		for (int part = 0; part < values->Length(); part++) {
+		for (Sci::Position part = 0; part < values->Length(); part++) {
 			ClearValue(part);
 		}
 		values.reset();
 	}
-	int Length() const {
+	Sci::Position Length() const {
 		return starts->PositionFromPartition(starts->Partitions());
 	}
-	int Elements() const {
+	Sci::Position Elements() const {
 		return starts->Partitions();
 	}
-	int PositionOfElement(int element) const {
+	Sci::Position PositionOfElement(int element) const {
 		return starts->PositionFromPartition(element);
 	}
-	const T& ValueAt(int position) const {
+	const T& ValueAt(Sci::Position position) const {
 		assert(position < Length());
-		const int partition = starts->PartitionFromPosition(position);
-		const int startPartition = starts->PositionFromPartition(partition);
+		const Sci::Position partition = starts->PartitionFromPosition(position);
+		const Sci::Position startPartition = starts->PositionFromPartition(partition);
 		if (startPartition == position) {
 			return values->ValueAt(partition);
 		} else {
@@ -58,10 +58,10 @@
 		}
 	}
 	template <typename ParamType>
-	void SetValueAt(int position, ParamType &&value) {
+	void SetValueAt(Sci::Position position, ParamType &&value) {
 		assert(position < Length());
-		const int partition = starts->PartitionFromPosition(position);
-		const int startPartition = starts->PositionFromPartition(partition);
+		const Sci::Position partition = starts->PartitionFromPosition(position);
+		const Sci::Position startPartition = starts->PositionFromPartition(partition);
 		if (value == T()) {
 			// Setting the empty value is equivalent to deleting the position
 			if (position == 0) {
@@ -85,10 +85,10 @@
 			}
 		}
 	}
-	void InsertSpace(int position, int insertLength) {
+	void InsertSpace(Sci::Position position, Sci::Position insertLength) {
 		assert(position <= Length());	// Only operation that works at end.
-		const int partition = starts->PartitionFromPosition(position);
-		const int startPartition = starts->PositionFromPartition(partition);
+		const Sci::Position partition = starts->PartitionFromPosition(position);
+		const Sci::Position startPartition = starts->PositionFromPartition(partition);
 		if (startPartition == position) {
 			const bool positionOccupied = values->ValueAt(partition) != T();
 			// Inserting at start of run so make previous longer
@@ -111,10 +111,10 @@
 			starts->InsertText(partition, insertLength);
 		}
 	}
-	void DeletePosition(int position) {
+	void DeletePosition(Sci::Position position) {
 		assert(position < Length());
-		int partition = starts->PartitionFromPosition(position);
-		const int startPartition = starts->PositionFromPartition(partition);
+		Sci::Position partition = starts->PartitionFromPosition(position);
+		const Sci::Position startPartition = starts->PositionFromPartition(partition);
 		if (startPartition == position) {
 			if (partition == 0) {
 				ClearValue(0);
@@ -126,7 +126,7 @@
 				ClearValue(partition);
 				starts->RemovePartition(partition);
 				values->Delete(partition);
-				// Its the previous partition now that gets smaller 
+				// Its the previous partition now that gets smaller
 				partition--;
 			}
 		}
diff -r 1e13baeb3f82 -r f28d452553a8 test/unit/testPartitioning.cxx
--- a/test/unit/testPartitioning.cxx	Tue Feb 20 15:31:38 2018 +1100
+++ b/test/unit/testPartitioning.cxx	Tue Feb 20 16:01:59 2018 +1100
@@ -49,7 +49,7 @@
 
 TEST_CASE("Partitioning") {
 
-	Partitioning<int> part(growSize);
+	Partitioning<Sci::Position> part(growSize);
 
 	SECTION("IsEmptyInitially") {
 		REQUIRE(1 == part.Partitions());
