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/SparseVector.h | |
| 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/SparseVector.h')
| -rw-r--r-- | src/SparseVector.h | 105 | 
1 files changed, 38 insertions, 67 deletions
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  | 
