# HG changeset patch
# User Neil <nyamatongwe@gmail.com>
# Date 1516951707 -39600
#      Fri Jan 26 18:28:27 2018 +1100
# Node ID 71961187dbc2dad60a3eefe6eea308b31a2e76d5
# Parent  705ebd7a7e3636264c1069793365ba2a0eb19108
Split LineVector into interface and implementation classes to allow future
choice between 32-bit and 64-bit position implementations.

diff -r 705ebd7a7e36 -r 71961187dbc2 src/CellBuffer.cxx
--- a/src/CellBuffer.cxx	Fri Jan 26 18:04:38 2018 +1100
+++ b/src/CellBuffer.cxx	Fri Jan 26 18:28:27 2018 +1100
@@ -25,54 +25,75 @@
 #include "CellBuffer.h"
 #include "UniConversion.h"
 
-using namespace Scintilla;
-
-LineVector::LineVector() : starts(256), perLine(0) {
-	Init();
-}
-
-LineVector::~LineVector() {
-	starts.DeleteAll();
-}
+namespace Scintilla {
 
-void LineVector::Init() {
-	starts.DeleteAll();
-	if (perLine) {
-		perLine->Init();
-	}
-}
+class ILineVector {
+public:
+	virtual void Init() = 0;
+	virtual void SetPerLine(PerLine *pl) = 0;
+	virtual void InsertText(Sci::Line line, Sci::Position delta) = 0;
+	virtual void InsertLine(Sci::Line line, Sci::Position position, bool lineStart) = 0;
+	virtual void SetLineStart(Sci::Line line, Sci::Position position) = 0;
+	virtual void RemoveLine(Sci::Line line) = 0;
+	virtual Sci::Line Lines() const = 0;
+	virtual Sci::Line LineFromPosition(Sci::Position pos) const = 0;
+	virtual Sci::Position LineStart(Sci::Line line) const = 0;
+	virtual ~ILineVector() {}
+};
 
-void LineVector::SetPerLine(PerLine *pl) {
-	perLine = pl;
 }
 
-void LineVector::InsertText(Sci::Line line, Sci::Position delta) {
-	starts.InsertText(line, delta);
-}
-
-void LineVector::InsertLine(Sci::Line line, Sci::Position position, bool lineStart) {
-	starts.InsertPartition(line, position);
-	if (perLine) {
-		if ((line > 0) && lineStart)
-			line--;
-		perLine->InsertLine(line);
-	}
-}
+using namespace Scintilla;
 
-void LineVector::SetLineStart(Sci::Line line, Sci::Position position) {
-	starts.SetPartitionStartPosition(line, position);
-}
-
-void LineVector::RemoveLine(Sci::Line line) {
-	starts.RemovePartition(line);
-	if (perLine) {
-		perLine->RemoveLine(line);
+class LineVector : public ILineVector {
+	Partitioning starts;
+	PerLine *perLine;
+public:
+	LineVector() : starts(256), perLine(0) {
+		Init();
+ 	}
+	~LineVector() {
+		starts.DeleteAll();
+ 	}
+	void Init() override {
+		starts.DeleteAll();
+		if (perLine) {
+			perLine->Init();
+		}
+ 	}
+	void SetPerLine(PerLine *pl) override {
+		perLine = pl;
+	}
+	void InsertText(Sci::Line line, Sci::Position delta) override {
+		starts.InsertText(line, delta);
 	}
-}
-
-Sci::Line LineVector::LineFromPosition(Sci::Position pos) const {
-	return starts.PartitionFromPosition(pos);
-}
+	void InsertLine(Sci::Line line, Sci::Position position, bool lineStart) override {
+		starts.InsertPartition(line, position);
+		if (perLine) {
+			if ((line > 0) && lineStart)
+				line--;
+			perLine->InsertLine(line);
+		}
+	}
+	void SetLineStart(Sci::Line line, Sci::Position position) override {
+		starts.SetPartitionStartPosition(line, position);
+	}
+	void RemoveLine(Sci::Line line) override {
+		starts.RemovePartition(line);
+		if (perLine) {
+			perLine->RemoveLine(line);
+		}
+	}
+	Sci::Line Lines() const override {
+		return starts.Partitions();
+	}
+	Sci::Line LineFromPosition(Sci::Position pos) const override {
+		return starts.PartitionFromPosition(pos);
+	}
+	Sci::Position LineStart(Sci::Line line) const override {
+		return starts.PositionFromPartition(line);
+	}
+};
 
 Action::Action() {
 	at = startAction;
@@ -347,6 +368,7 @@
 	readOnly = false;
 	utf8LineEnds = 0;
 	collectingUndo = true;
+	plv.reset(new LineVector());
 }
 
 CellBuffer::~CellBuffer() {
@@ -505,11 +527,11 @@
 }
 
 void CellBuffer::SetPerLine(PerLine *pl) {
-	lv.SetPerLine(pl);
+	plv->SetPerLine(pl);
 }
 
 Sci::Line CellBuffer::Lines() const {
-	return lv.Lines();
+	return plv->Lines();
 }
 
 Sci::Position CellBuffer::LineStart(Sci::Line line) const {
@@ -518,7 +540,11 @@
 	else if (line >= Lines())
 		return Length();
 	else
-		return lv.LineStart(line);
+		return plv->LineStart(line);
+}
+
+Sci::Line CellBuffer::LineFromPosition(Sci::Position pos) const {
+	return plv->LineFromPosition(pos); 
 }
 
 bool CellBuffer::IsReadOnly() const {
@@ -556,11 +582,11 @@
 // Without undo
 
 void CellBuffer::InsertLine(Sci::Line line, Sci::Position position, bool lineStart) {
-	lv.InsertLine(line, position, lineStart);
+	plv->InsertLine(line, position, lineStart);
 }
 
 void CellBuffer::RemoveLine(Sci::Line line) {
-	lv.RemoveLine(line);
+	plv->RemoveLine(line);
 }
 
 bool CellBuffer::UTF8LineEndOverlaps(Sci::Position position) const {
@@ -575,13 +601,13 @@
 
 void CellBuffer::ResetLineEnds() {
 	// Reinitialize line data -- too much work to preserve
-	lv.Init();
+	plv->Init();
 
 	Sci::Position position = 0;
 	Sci::Position length = Length();
 	Sci::Line lineInsert = 1;
 	bool atLineStart = true;
-	lv.InsertText(lineInsert-1, length);
+	plv->InsertText(lineInsert-1, length);
 	unsigned char chBeforePrev = 0;
 	unsigned char chPrev = 0;
 	for (Sci::Position i = 0; i < length; i++) {
@@ -592,7 +618,7 @@
 		} else if (ch == '\n') {
 			if (chPrev == '\r') {
 				// Patch up what was end of line
-				lv.SetLineStart(lineInsert - 1, (position + i) + 1);
+				plv->SetLineStart(lineInsert - 1, (position + i) + 1);
 			} else {
 				InsertLine(lineInsert, (position + i) + 1, atLineStart);
 				lineInsert++;
@@ -625,10 +651,10 @@
 		style.InsertValue(position, insertLength, 0);
 	}
 
-	Sci::Line lineInsert = lv.LineFromPosition(position) + 1;
-	bool atLineStart = lv.LineStart(lineInsert-1) == position;
+	Sci::Line lineInsert = plv->LineFromPosition(position) + 1;
+	bool atLineStart = plv->LineStart(lineInsert-1) == position;
 	// Point all the lines after the insertion point further along in the buffer
-	lv.InsertText(lineInsert-1, insertLength);
+	plv->InsertText(lineInsert-1, insertLength);
 	unsigned char chBeforePrev = substance.ValueAt(position - 2);
 	unsigned char chPrev = substance.ValueAt(position - 1);
 	if (chPrev == '\r' && chAfter == '\n') {
@@ -648,7 +674,7 @@
 		} else if (ch == '\n') {
 			if (chPrev == '\r') {
 				// Patch up what was end of line
-				lv.SetLineStart(lineInsert - 1, (position + i) + 1);
+				plv->SetLineStart(lineInsert - 1, (position + i) + 1);
 			} else {
 				InsertLine(lineInsert, (position + i) + 1, atLineStart);
 				lineInsert++;
@@ -695,20 +721,20 @@
 	if ((position == 0) && (deleteLength == substance.Length())) {
 		// If whole buffer is being deleted, faster to reinitialise lines data
 		// than to delete each line.
-		lv.Init();
+		plv->Init();
 	} else {
 		// Have to fix up line positions before doing deletion as looking at text in buffer
 		// to work out which lines have been removed
 
-		Sci::Line lineRemove = lv.LineFromPosition(position) + 1;
-		lv.InsertText(lineRemove-1, - (deleteLength));
+		Sci::Line lineRemove = plv->LineFromPosition(position) + 1;
+		plv->InsertText(lineRemove-1, - (deleteLength));
 		const unsigned char chPrev = substance.ValueAt(position - 1);
 		const unsigned char chBefore = chPrev;
 		unsigned char chNext = substance.ValueAt(position);
 		bool ignoreNL = false;
 		if (chPrev == '\r' && chNext == '\n') {
 			// Move back one
-			lv.SetLineStart(lineRemove, position);
+			plv->SetLineStart(lineRemove, position);
 			lineRemove++;
 			ignoreNL = true; 	// First \n is not real deletion
 		}
@@ -749,7 +775,7 @@
 		if (chBefore == '\r' && chAfter == '\n') {
 			// Using lineRemove-1 as cr ended line before start of deletion
 			RemoveLine(lineRemove - 1);
-			lv.SetLineStart(lineRemove - 1, position + 1);
+			plv->SetLineStart(lineRemove - 1, position + 1);
 		}
 	}
 	substance.DeleteRange(position, deleteLength);
diff -r 705ebd7a7e36 -r 71961187dbc2 src/CellBuffer.h
--- a/src/CellBuffer.h	Fri Jan 26 18:04:38 2018 +1100
+++ b/src/CellBuffer.h	Fri Jan 26 18:28:27 2018 +1100
@@ -22,33 +22,7 @@
 /**
  * The line vector contains information about each of the lines in a cell buffer.
  */
-class LineVector {
-
-	Partitioning starts;
-	PerLine *perLine;
-
-public:
-
-	LineVector();
-	// Deleted so LineVector objects can not be copied.
-	LineVector(const LineVector &) = delete;
-	void operator=(const LineVector &) = delete;
-	~LineVector();
-	void Init();
-	void SetPerLine(PerLine *pl);
-
-	void InsertText(Sci::Line line, Sci::Position delta);
-	void InsertLine(Sci::Line line, Sci::Position position, bool lineStart);
-	void SetLineStart(Sci::Line line, Sci::Position position);
-	void RemoveLine(Sci::Line line);
-	Sci::Line Lines() const {
-		return starts.Partitions();
-	}
-	Sci::Line LineFromPosition(Sci::Position pos) const;
-	Sci::Position LineStart(Sci::Line line) const {
-		return starts.PositionFromPartition(line);
-	}
-};
+class ILineVector;
 
 enum actionType { insertAction, removeAction, startAction, containerAction };
 
@@ -142,7 +116,7 @@
 	bool collectingUndo;
 	UndoHistory uh;
 
-	LineVector lv;
+	std::unique_ptr<ILineVector> plv;
 
 	bool UTF8LineEndOverlaps(Sci::Position position) const;
 	void ResetLineEnds();
@@ -175,7 +149,7 @@
 	void SetPerLine(PerLine *pl);
 	Sci::Line Lines() const;
 	Sci::Position LineStart(Sci::Line line) const;
-	Sci::Line LineFromPosition(Sci::Position pos) const { return lv.LineFromPosition(pos); }
+	Sci::Line LineFromPosition(Sci::Position pos) const;
 	void InsertLine(Sci::Line line, Sci::Position position, bool lineStart);
 	void RemoveLine(Sci::Line line);
 	const char *InsertString(Sci::Position position, const char *s, Sci::Position insertLength, bool &startSequence);
