aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/SparseVector.h
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2017-05-21 23:08:04 +1000
committerNeil <nyamatongwe@gmail.com>2017-05-21 23:08:04 +1000
commit3debda34b8aa21a770142a055b8fa7e4a8a7355f (patch)
tree64079ad63efbe256cac9639d58a38c9d6fd41e5b /src/SparseVector.h
parent8ef4f3d54de1328a1d9753f4317a5d7692a72ae8 (diff)
downloadscintilla-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.h105
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