diff options
| author | Neil <nyamatongwe@gmail.com> | 2019-12-01 20:41:27 +1100 | 
|---|---|---|
| committer | Neil <nyamatongwe@gmail.com> | 2019-12-01 20:41:27 +1100 | 
| commit | 2892e0d04bcf02fe249939f7c22fe8c6d780233a (patch) | |
| tree | 8df27d8568a6a1ef7c07eb77819bd589b298e464 | |
| parent | 7153448eb8dfe267f96eb55aee683172f15cc283 (diff) | |
| download | scintilla-mirror-2892e0d04bcf02fe249939f7c22fe8c6d780233a.tar.gz | |
Backport: Allow setting value at end of a SparseVector.
Change representation of SparseVector in tests so last value can be seen.
Backport of changeset 7778:b7842ad8047b.
| -rw-r--r-- | src/SparseVector.h | 39 | ||||
| -rw-r--r-- | test/unit/testContractionState.cxx | 6 | ||||
| -rw-r--r-- | test/unit/testSparseVector.cxx | 65 | 
3 files changed, 74 insertions, 36 deletions
diff --git a/src/SparseVector.h b/src/SparseVector.h index 67ad1e1e3..6dd02ba8b 100644 --- a/src/SparseVector.h +++ b/src/SparseVector.h @@ -12,13 +12,17 @@ namespace Scintilla {  // SparseVector is similar to RunStyles but is more efficient for cases where values occur  // for one position instead of over a range of positions. +// There are always elements at the start and end, so the element type should have +// a reasonable empty value that will cause no problems. +// The element type should have a noexcept default constructor as that allows methods to +// be noexcept.  template <typename T>  class SparseVector {  private:  	std::unique_ptr<Partitioning<Sci::Position>> starts;  	std::unique_ptr<SplitVector<T>> values; -	T empty; -	void ClearValue(Sci::Position partition) { +	T empty;	// Return from ValueAt when no element at a position. +	void ClearValue(Sci::Position partition) noexcept {  		values->SetValueAt(partition, T());  	}  public: @@ -40,18 +44,25 @@ public:  		}  		values.reset();  	} -	Sci::Position Length() const { -		return starts->PositionFromPartition(starts->Partitions()); +	Sci::Position Length() const noexcept { +		return starts->Length();  	} -	Sci::Position Elements() const { +	Sci::Position Elements() const noexcept {  		return starts->Partitions();  	} -	Sci::Position PositionOfElement(int element) const { +	Sci::Position PositionOfElement(Sci::Position element) const noexcept {  		return starts->PositionFromPartition(element);  	} -	const T& ValueAt(Sci::Position position) const { -		assert(position < Length()); -		const Sci::Position partition = starts->PartitionFromPosition(position); +	Sci::Position ElementFromPosition(Sci::Position position) const noexcept { +		if (position < Length()) { +			return starts->PartitionFromPosition(position); +		} else { +			return starts->Partitions(); +		} +	} +	const T& ValueAt(Sci::Position position) const noexcept { +		assert(position <= Length()); +		const Sci::Position partition = ElementFromPosition(position);  		const Sci::Position startPartition = starts->PositionFromPartition(partition);  		if (startPartition == position) {  			return values->ValueAt(partition); @@ -61,8 +72,8 @@ public:  	}  	template <typename ParamType>  	void SetValueAt(Sci::Position position, ParamType &&value) { -		assert(position < Length()); -		const Sci::Position partition = starts->PartitionFromPosition(position); +		assert(position <= Length()); +		const Sci::Position partition = ElementFromPosition(position);  		const Sci::Position startPartition = starts->PositionFromPartition(partition);  		if (value == T()) {  			// Setting the empty value is equivalent to deleting the position @@ -88,7 +99,7 @@ public:  		}  	}  	void InsertSpace(Sci::Position position, Sci::Position insertLength) { -		assert(position <= Length());	// Only operation that works at end. +		assert(position <= Length());  		const Sci::Position partition = starts->PartitionFromPosition(position);  		const Sci::Position startPartition = starts->PositionFromPartition(partition);  		if (startPartition == position) { @@ -149,10 +160,6 @@ public:  		if (starts->Partitions() != values->Length() - 1) {  			throw std::runtime_error("SparseVector: Partitions and values different lengths.");  		} -		// The final element can not be set -		if (values->ValueAt(values->Length() - 1) != T()) { -			throw std::runtime_error("SparseVector: Unused style at end changed."); -		}  #endif  	}  }; diff --git a/test/unit/testContractionState.cxx b/test/unit/testContractionState.cxx index fcee90287..5fada7645 100644 --- a/test/unit/testContractionState.cxx +++ b/test/unit/testContractionState.cxx @@ -147,12 +147,18 @@ TEST_CASE("ContractionState") {  	SECTION("SetFoldDisplayText") {  		pcs->InsertLines(0, 4); +		REQUIRE(5 == pcs->LinesInDoc());  		pcs->SetFoldDisplayText(1, "abc");  		REQUIRE(strcmp(pcs->GetFoldDisplayText(1), "abc") == 0);  		pcs->SetFoldDisplayText(1, "def");  		REQUIRE(strcmp(pcs->GetFoldDisplayText(1), "def") == 0);  		pcs->SetFoldDisplayText(1, nullptr);  		REQUIRE(static_cast<const char *>(nullptr) == pcs->GetFoldDisplayText(1)); +		// At end +		pcs->SetFoldDisplayText(5, "xyz"); +		REQUIRE(strcmp(pcs->GetFoldDisplayText(5), "xyz") == 0); +		pcs->DeleteLines(4, 1); +		REQUIRE(strcmp(pcs->GetFoldDisplayText(4), "xyz") == 0);  	}  } diff --git a/test/unit/testSparseVector.cxx b/test/unit/testSparseVector.cxx index df7b412ce..4d3b872e1 100644 --- a/test/unit/testSparseVector.cxx +++ b/test/unit/testSparseVector.cxx @@ -27,7 +27,7 @@ using namespace Scintilla;  // to simplify checks.  static std::string Representation(const SparseVector<UniqueString> &st) {  	std::string ret; -	for (int i = 0;i < st.Length();i++) { +	for (int i = 0;i <= st.Length();i++) {  		const char *value = st.ValueAt(i).get();  		if (value && *value)  			ret += value; @@ -44,6 +44,7 @@ TEST_CASE("SparseVector") {  	SECTION("IsEmptyInitially") {  		REQUIRE(1 == st.Elements());  		REQUIRE(0 == st.Length()); +		REQUIRE("-" == Representation(st));  		st.Check();  	} @@ -60,7 +61,7 @@ TEST_CASE("SparseVector") {  		st.InsertSpace(0, 5);  		st.SetValueAt(3, UniqueStringCopy("3"));  		REQUIRE(2 == st.Elements()); -		REQUIRE("---3-" == Representation(st)); +		REQUIRE("---3--" == Representation(st));  		st.Check();  	} @@ -74,7 +75,7 @@ TEST_CASE("SparseVector") {  		st.DeletePosition(3);  		REQUIRE(1 == st.Elements());  		REQUIRE(4 == st.Length()); -		REQUIRE("----" == Representation(st)); +		REQUIRE("-----" == Representation(st));  		st.Check();  	} @@ -83,7 +84,13 @@ TEST_CASE("SparseVector") {  		st.InsertSpace(0, 5);  		st.SetValueAt(0, UniqueStringCopy("3"));  		REQUIRE(1 == st.Elements()); -		REQUIRE("3----" == Representation(st)); +		REQUIRE("3-----" == Representation(st)); +		st.DeletePosition(0); +		REQUIRE(1 == st.Elements()); +		REQUIRE("-----" == Representation(st)); +		st.SetValueAt(0, UniqueStringCopy("4")); +		REQUIRE(1 == st.Elements()); +		REQUIRE("4----" == Representation(st));  		st.DeletePosition(0);  		REQUIRE(1 == st.Elements());  		REQUIRE("----" == Representation(st)); @@ -101,10 +108,10 @@ TEST_CASE("SparseVector") {  		st.InsertSpace(0, 5);  		st.SetValueAt(0, UniqueStringCopy("3"));  		REQUIRE(1 == st.Elements()); -		REQUIRE("3----" == Representation(st)); +		REQUIRE("3-----" == Representation(st));  		st.InsertSpace(0, 1);  		REQUIRE(2 == st.Elements()); -		REQUIRE("-3----" == Representation(st)); +		REQUIRE("-3-----" == Representation(st));  		st.Check();  	} @@ -113,10 +120,10 @@ TEST_CASE("SparseVector") {  		st.InsertSpace(0, 5);  		st.SetValueAt(1, UniqueStringCopy("1"));  		REQUIRE(2 == st.Elements()); -		REQUIRE("-1---" == Representation(st)); +		REQUIRE("-1----" == Representation(st));  		st.InsertSpace(1, 1);  		REQUIRE(2 == st.Elements()); -		REQUIRE("--1---" == Representation(st)); +		REQUIRE("--1----" == Representation(st));  		st.Check();  	} @@ -125,10 +132,10 @@ TEST_CASE("SparseVector") {  		st.InsertSpace(0, 5);  		st.SetValueAt(1, UniqueStringCopy("9"));  		REQUIRE(2 == st.Elements()); -		REQUIRE("-9---" == Representation(st)); +		REQUIRE("-9----" == Representation(st));  		st.InsertSpace(0, 1);  		REQUIRE(2 == st.Elements()); -		REQUIRE("--9---" == Representation(st)); +		REQUIRE("--9----" == Representation(st));  		// Initial st has allocation of 9 values so this should cause reallocation  		const std::string letters("ABCDEFGHIJKLMNOP");	// 16 letters  		for (const char letter : letters) { @@ -136,7 +143,7 @@ TEST_CASE("SparseVector") {  			st.InsertSpace(0, 1);  			st.SetValueAt(1, UniqueStringCopy(sLetter));  		} -		REQUIRE("-PONMLKJIHGFEDCBA-9---" == Representation(st)); +		REQUIRE("-PONMLKJIHGFEDCBA-9----" == Representation(st));  		st.Check();  	} @@ -145,10 +152,16 @@ TEST_CASE("SparseVector") {  		st.InsertSpace(0, 5);  		st.SetValueAt(4, UniqueStringCopy("5"));  		REQUIRE(2 == st.Elements()); -		REQUIRE("----5" == Representation(st)); +		REQUIRE("----5-" == Representation(st)); +		st.SetValueAt(5, UniqueStringCopy("6")); +		REQUIRE(2 == st.Elements()); +		REQUIRE("----56" == Representation(st));  		st.DeletePosition(4);  		REQUIRE(1 == st.Elements()); -		REQUIRE("----" == Representation(st)); +		REQUIRE("----6" == Representation(st)); +		st.SetValueAt(4, UniqueStringCopy("7")); +		REQUIRE(1 == st.Elements()); +		REQUIRE("----7" == Representation(st));  		st.Check();  	} @@ -157,10 +170,10 @@ TEST_CASE("SparseVector") {  		st.InsertSpace(0, 5);  		st.SetValueAt(4, UniqueStringCopy("5"));  		REQUIRE(2 == st.Elements()); -		REQUIRE("----5" == Representation(st)); +		REQUIRE("----5-" == Representation(st));  		st.SetValueAt(4, nullptr);  		REQUIRE(1 == st.Elements()); -		REQUIRE("-----" == Representation(st)); +		REQUIRE("------" == Representation(st));  		st.Check();  	} @@ -168,16 +181,16 @@ TEST_CASE("SparseVector") {  		REQUIRE(1 == st.Elements());  		st.InsertSpace(0, 1);  		st.SetValueAt(0, UniqueStringCopy("1")); -		REQUIRE("1" == Representation(st)); +		REQUIRE("1-" == Representation(st));  		REQUIRE(1 == st.Elements());  		st.InsertSpace(1, 1);  		st.SetValueAt(1, UniqueStringCopy("2")); -		REQUIRE("12" == Representation(st)); +		REQUIRE("12-" == Representation(st));  		st.DeletePosition(0); -		REQUIRE("2" == Representation(st)); +		REQUIRE("2-" == Representation(st));  		REQUIRE(1 == st.Elements());  		st.DeletePosition(0); -		REQUIRE("" == Representation(st)); +		REQUIRE("-" == Representation(st));  	}  	SECTION("DeleteAll") { @@ -188,10 +201,22 @@ TEST_CASE("SparseVector") {  		st.SetValueAt(4, UniqueStringCopy("4"));  		st.SetValueAt(3, UniqueStringCopy("3"));  		REQUIRE(5 == st.Elements()); -		REQUIRE("---34--7-9" == Representation(st)); +		REQUIRE("---34--7-9-" == Representation(st));  		st.Check();  	} +	SECTION("DeleteStarting") { +		REQUIRE(1 == st.Elements()); +		st.InsertSpace(0, 2); +		st.SetValueAt(0, UniqueStringCopy("1")); +		st.SetValueAt(1, UniqueStringCopy("2")); +		REQUIRE("12-" == Representation(st)); +		st.DeletePosition(0); +		REQUIRE("2-" == Representation(st)); +		st.DeletePosition(0); +		REQUIRE("-" == Representation(st)); +	} +  }  TEST_CASE("SparseTextInt") {  | 
