aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ContractionState.cxx13
-rw-r--r--src/ContractionState.h2
-rw-r--r--src/EditModel.cxx2
-rw-r--r--src/EditView.cxx1
-rw-r--r--src/Editor.cxx1
-rw-r--r--src/MarginView.cxx1
-rw-r--r--src/PositionCache.cxx1
-rw-r--r--src/ScintillaBase.cxx1
-rw-r--r--src/SparseVector.h105
-rw-r--r--src/UniqueString.h34
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