diff options
| author | Neil <nyamatongwe@gmail.com> | 2017-05-21 23:08:04 +1000 | 
|---|---|---|
| committer | Neil <nyamatongwe@gmail.com> | 2017-05-21 23:08:04 +1000 | 
| commit | 3debda34b8aa21a770142a055b8fa7e4a8a7355f (patch) | |
| tree | 64079ad63efbe256cac9639d58a38c9d6fd41e5b /src | |
| parent | 8ef4f3d54de1328a1d9753f4317a5d7692a72ae8 (diff) | |
| download | scintilla-mirror-3debda34b8aa21a770142a055b8fa7e4a8a7355f.tar.gz | |
Make SparseVector work with move-only types.
Define UniqueString as a move-only string and use in a SparseVector for
ContractionState.
Remove SparseVector method specializations that are no longer needed.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ContractionState.cxx | 13 | ||||
| -rw-r--r-- | src/ContractionState.h | 2 | ||||
| -rw-r--r-- | src/EditModel.cxx | 2 | ||||
| -rw-r--r-- | src/EditView.cxx | 1 | ||||
| -rw-r--r-- | src/Editor.cxx | 1 | ||||
| -rw-r--r-- | src/MarginView.cxx | 1 | ||||
| -rw-r--r-- | src/PositionCache.cxx | 1 | ||||
| -rw-r--r-- | src/ScintillaBase.cxx | 1 | ||||
| -rw-r--r-- | src/SparseVector.h | 105 | ||||
| -rw-r--r-- | src/UniqueString.h | 34 | 
10 files changed, 87 insertions, 74 deletions
| diff --git a/src/ContractionState.cxx b/src/ContractionState.cxx index 6fca2ec4e..c56c5647b 100644 --- a/src/ContractionState.cxx +++ b/src/ContractionState.cxx @@ -17,6 +17,7 @@  #include "Platform.h"  #include "Position.h" +#include "UniqueString.h"  #include "SplitVector.h"  #include "Partitioning.h"  #include "RunStyles.h" @@ -39,7 +40,7 @@ void ContractionState::EnsureData() {  		visible.reset(new RunStyles());  		expanded.reset(new RunStyles());  		heights.reset(new RunStyles()); -		foldDisplayTexts.reset(new SparseVector<const char *>()); +		foldDisplayTexts.reset(new SparseVector<UniqueString>());  		displayLines.reset(new Partitioning(4));  		InsertLines(0, linesInDocument);  	} @@ -111,7 +112,7 @@ void ContractionState::InsertLine(Sci::Line lineDoc) {  		heights->InsertSpace(lineDoc, 1);  		heights->SetValueAt(lineDoc, 1);  		foldDisplayTexts->InsertSpace(lineDoc, 1); -		foldDisplayTexts->SetValueAt(lineDoc, NULL); +		foldDisplayTexts->SetValueAt(lineDoc, nullptr);  		Sci::Line lineDisplay = DisplayFromDoc(lineDoc);  		displayLines->InsertPartition(lineDoc, lineDisplay);  		displayLines->InsertText(lineDoc, 1); @@ -191,14 +192,14 @@ bool ContractionState::HiddenLines() const {  const char *ContractionState::GetFoldDisplayText(Sci::Line lineDoc) const {  	Check(); -	return foldDisplayTexts->ValueAt(lineDoc); +	return foldDisplayTexts->ValueAt(lineDoc).get();  }  bool ContractionState::SetFoldDisplayText(Sci::Line lineDoc, const char *text) {  	EnsureData(); -	const char *foldText = foldDisplayTexts->ValueAt(lineDoc); -	if (!foldText || 0 != strcmp(text, foldText)) { -		foldDisplayTexts->SetValueAt(lineDoc, text); +	const char *foldText = foldDisplayTexts->ValueAt(lineDoc).get(); +	if (!foldText || !text || 0 != strcmp(text, foldText)) { +		foldDisplayTexts->SetValueAt(lineDoc, UniqueStringCopy(text));  		Check();  		return true;  	} else { diff --git a/src/ContractionState.h b/src/ContractionState.h index 1e4c3f58f..1070fb59f 100644 --- a/src/ContractionState.h +++ b/src/ContractionState.h @@ -22,7 +22,7 @@ class ContractionState {  	std::unique_ptr<RunStyles> visible;  	std::unique_ptr<RunStyles> expanded;  	std::unique_ptr<RunStyles> heights; -	std::unique_ptr<SparseVector<const char *>> foldDisplayTexts; +	std::unique_ptr<SparseVector<UniqueString>> foldDisplayTexts;  	std::unique_ptr<Partitioning> displayLines;  	Sci::Line linesInDocument; diff --git a/src/EditModel.cxx b/src/EditModel.cxx index 292ce954c..faf21623e 100644 --- a/src/EditModel.cxx +++ b/src/EditModel.cxx @@ -8,6 +8,7 @@  #include <cstddef>  #include <cstdlib>  #include <cassert> +#include <cstring>  #include <cmath>  #include <stdexcept> @@ -24,6 +25,7 @@  #include "StringCopy.h"  #include "Position.h" +#include "UniqueString.h"  #include "SplitVector.h"  #include "Partitioning.h"  #include "RunStyles.h" diff --git a/src/EditView.cxx b/src/EditView.cxx index 808daa6fa..089862515 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -28,6 +28,7 @@  #include "StringCopy.h"  #include "CharacterSet.h"  #include "Position.h" +#include "UniqueString.h"  #include "SplitVector.h"  #include "Partitioning.h"  #include "RunStyles.h" diff --git a/src/Editor.cxx b/src/Editor.cxx index 63ec27786..2ad440db3 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -27,6 +27,7 @@  #include "StringCopy.h"  #include "Position.h" +#include "UniqueString.h"  #include "SplitVector.h"  #include "Partitioning.h"  #include "RunStyles.h" diff --git a/src/MarginView.cxx b/src/MarginView.cxx index e371a4891..7ecc85c7b 100644 --- a/src/MarginView.cxx +++ b/src/MarginView.cxx @@ -27,6 +27,7 @@  #include "StringCopy.h"  #include "Position.h" +#include "UniqueString.h"  #include "SplitVector.h"  #include "Partitioning.h"  #include "RunStyles.h" diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx index 2099046b8..591cf2254 100644 --- a/src/PositionCache.cxx +++ b/src/PositionCache.cxx @@ -22,6 +22,7 @@  #include "Scintilla.h"  #include "Position.h" +#include "UniqueString.h"  #include "SplitVector.h"  #include "Partitioning.h"  #include "RunStyles.h" diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx index 0fbf555d1..3979354eb 100644 --- a/src/ScintillaBase.cxx +++ b/src/ScintillaBase.cxx @@ -34,6 +34,7 @@  #endif  #include "Position.h" +#include "UniqueString.h"  #include "SplitVector.h"  #include "Partitioning.h"  #include "RunStyles.h" diff --git a/src/SparseVector.h b/src/SparseVector.h index ce38d0da1..230871ccc 100644 --- a/src/SparseVector.h +++ b/src/SparseVector.h @@ -19,45 +19,18 @@ class SparseVector {  private:  	std::unique_ptr<Partitioning> 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) {  		values->SetValueAt(partition, T());  	} -	void CommonSetValueAt(int position, T value) { -		// Do the work of setting the value to allow for specialization of SetValueAt. -		assert(position < Length()); -		const int partition = starts->PartitionFromPosition(position); -		const int startPartition = starts->PositionFromPartition(partition); -		if (value == T()) { -			// Setting the empty value is equivalent to deleting the position -			if (position == 0) { -				ClearValue(partition); -			} else if (position == startPartition) { -				// Currently an element at this position, so remove -				ClearValue(partition); -				starts->RemovePartition(partition); -				values->Delete(partition); -			} -			// Else element remains empty -		} else { -			if (position == startPartition) { -				// Already a value at this position, so replace -				ClearValue(partition); -				values->SetValueAt(partition, value); -			} else { -				// Insert a new element -				starts->InsertPartition(partition + 1, position); -				values->InsertValue(partition + 1, 1, value); -			} -		} -	}  public: -	SparseVector() { +	SparseVector() : empty() {  		starts.reset(new Partitioning(8));  		values.reset(new SplitVector<T>()); -		values->InsertValue(0, 2, T()); +		values->InsertEmpty(0, 2);  	}  	~SparseVector() {  		starts.reset(); @@ -76,39 +49,60 @@ public:  	int PositionOfElement(int element) const {  		return starts->PositionFromPartition(element);  	} -	T ValueAt(int position) const { +	const T& ValueAt(int position) const {  		assert(position < Length());  		const int partition = starts->PartitionFromPosition(position);  		const int startPartition = starts->PositionFromPartition(partition);  		if (startPartition == position) {  			return values->ValueAt(partition);  		} else { -			return T(); +			return empty;  		}  	} -	void SetValueAt(int position, T value) { -		CommonSetValueAt(position, value); +	template <typename ParamType> +	void SetValueAt(int position, ParamType &&value) { +		assert(position < Length()); +		const int partition = starts->PartitionFromPosition(position); +		const int startPartition = starts->PositionFromPartition(partition); +		if (value == T()) { +			// Setting the empty value is equivalent to deleting the position +			if (position == 0) { +				ClearValue(partition); +			} else if (position == startPartition) { +				// Currently an element at this position, so remove +				ClearValue(partition); +				starts->RemovePartition(partition); +				values->Delete(partition); +			} +			// Else element remains empty +		} else { +			if (position == startPartition) { +				// Already a value at this position, so replace +				ClearValue(partition); +				values->SetValueAt(partition, std::move(value)); +			} else { +				// Insert a new element +				starts->InsertPartition(partition + 1, position); +				values->Insert(partition + 1, std::move(value)); +			} +		}  	}  	void InsertSpace(int position, int insertLength) {  		assert(position <= Length());	// Only operation that works at end.  		const int partition = starts->PartitionFromPosition(position);  		const int startPartition = starts->PositionFromPartition(partition);  		if (startPartition == position) { -			T valueCurrent = values->ValueAt(partition); +			const bool positionOccupied = values->ValueAt(partition) != T();  			// Inserting at start of run so make previous longer  			if (partition == 0) { -				// Inserting at start of document so ensure 0 -				if (valueCurrent != T()) { -					// Since valueCurrent is needed again, should not ClearValue -					values->SetValueAt(0, T()); +				// Inserting at start of document so ensure start empty +				if (positionOccupied) {  					starts->InsertPartition(1, 0); -					values->InsertValue(1, 1, valueCurrent); -					starts->InsertText(0, insertLength); -				} else { -					starts->InsertText(partition, insertLength); +					values->InsertEmpty(0, 1);  				} +				starts->InsertText(partition, insertLength);  			} else { -				if (valueCurrent != T()) { +				if (positionOccupied) {  					starts->InsertText(partition - 1, insertLength);  				} else {  					// Insert at end of run so do not extend style @@ -157,29 +151,6 @@ public:  	}  }; -// The specialization for const char * makes copies and deletes them as needed. - -template<> -inline void SparseVector<const char *>::ClearValue(int partition) { -	const char *value = values->ValueAt(partition); -	delete []value; -	value = nullptr; -	values->SetValueAt(partition, value); -} - -template<> -inline void SparseVector<const char *>::SetValueAt(int position, const char *value) { -	// Make a copy of the string -	if (value) { -		const size_t len = strlen(value); -		char *valueCopy = new char[len + 1](); -		std::copy(value, value + len, valueCopy); -		CommonSetValueAt(position, valueCopy); -	} else { -		CommonSetValueAt(position, nullptr); -	} -} -  #ifdef SCI_NAMESPACE  }  #endif diff --git a/src/UniqueString.h b/src/UniqueString.h new file mode 100644 index 000000000..07da0f171 --- /dev/null +++ b/src/UniqueString.h @@ -0,0 +1,34 @@ +// Scintilla source code edit control +/** @file UniqueString.h + ** Define UniqueString, a unique_ptr based string type for storage in containers + ** and an allocator for UniqueString. + **/ +// Copyright 2017 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef UNIQUESTRING_H +#define UNIQUESTRING_H + +#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + +using UniqueString = std::unique_ptr<const char[]>; + +/// Equivalent to strdup but produces a std::unique_ptr<const char[]> allocation to go +/// into collections. +inline UniqueString UniqueStringCopy(const char *text) { +	if (!text) { +		return UniqueString(); +	} +	const size_t len = strlen(text); +	char *sNew = new char[len + 1]; +	std::copy(text, text + len + 1, sNew); +	return UniqueString(sNew); +} + +#ifdef SCI_NAMESPACE +} +#endif + +#endif | 
