diff options
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 |