aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2021-07-15 14:04:44 +1000
committerNeil <nyamatongwe@gmail.com>2021-07-15 14:04:44 +1000
commit65ea703cfbf8d5660c59e8b1ab756ed7ddde50a9 (patch)
treee58a68dcffce08cd7dadc1686d592896d5b90c28 /src
parent0a5f16edd287fba222214b89661285191e7af898 (diff)
downloadscintilla-mirror-65ea703cfbf8d5660c59e8b1ab756ed7ddde50a9.tar.gz
Feature [feature-requests:#1381] Move SplitView to header so it can be used more
widely. Ensure that case where all text is after the gap is as efficient as when all text is before the gap.
Diffstat (limited to 'src')
-rw-r--r--src/CellBuffer.cxx15
-rw-r--r--src/CellBuffer.h29
-rw-r--r--src/Document.cxx34
-rw-r--r--src/SplitVector.h10
4 files changed, 55 insertions, 33 deletions
diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx
index 375fe2201..f02d5348a 100644
--- a/src/CellBuffer.cxx
+++ b/src/CellBuffer.cxx
@@ -642,6 +642,21 @@ Sci::Position CellBuffer::GapPosition() const noexcept {
return substance.GapPosition();
}
+SplitView CellBuffer::AllView() const noexcept {
+ const size_t length = substance.Length();
+ size_t length1 = substance.GapPosition();
+ if (length1 == 0) {
+ // Assign segment2 to segment1 / length1 to avoid useless test against 0 length1
+ length1 = length;
+ }
+ return SplitView {
+ substance.ElementPointer(0),
+ length1,
+ substance.ElementPointer(length1) - length1,
+ length
+ };
+}
+
// The char* returned is to an allocation owned by the undo history
const char *CellBuffer::InsertString(Sci::Position position, const char *s, Sci::Position insertLength, bool &startSequence) {
// InsertString and DeleteChars are the bottleneck though which all changes occur
diff --git a/src/CellBuffer.h b/src/CellBuffer.h
index 361c285ad..637d0a6b5 100644
--- a/src/CellBuffer.h
+++ b/src/CellBuffer.h
@@ -102,6 +102,34 @@ public:
void CompletedRedoStep();
};
+struct SplitView {
+ const char *segment1 = nullptr;
+ size_t length1 = 0;
+ const char *segment2 = nullptr;
+ size_t length = 0;
+
+ SplitView() = default;
+
+ bool operator==(const SplitView &other) const noexcept {
+ return segment1 == other.segment1 && length1 == other.length1 &&
+ segment2 == other.segment2 && length == other.length;
+ }
+ bool operator!=(const SplitView &other) const noexcept {
+ return !(*this == other);
+ }
+
+ char CharAt(size_t position) const noexcept {
+ if (position < length1) {
+ return segment1[position];
+ }
+ if (position < length) {
+ return segment2[position];
+ }
+ return 0;
+ }
+};
+
+
/**
* Holder for an expandable array of characters that supports undo and line markers.
* Based on article "Data Structures in a Bit-Mapped Text Editor"
@@ -150,6 +178,7 @@ public:
const char *BufferPointer();
const char *RangePointer(Sci::Position position, Sci::Position rangeLength) noexcept;
Sci::Position GapPosition() const noexcept;
+ SplitView AllView() const noexcept;
Sci::Position Length() const noexcept;
void Allocate(Sci::Position newSize);
diff --git a/src/Document.cxx b/src/Document.cxx
index e0fd78eda..45e0799e8 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -1986,38 +1986,6 @@ Document::CharacterExtracted Document::ExtractCharacter(Sci::Position position)
namespace {
-struct SplitView {
- const char *segment1 = nullptr;
- size_t length1 = 0;
- const char *segment2 = nullptr;
- size_t length = 0;
-
- SplitView() = default;
- SplitView(CellBuffer &cb) noexcept {
- segment1 = cb.RangePointer(0, 0);
- length1 = cb.GapPosition();
- segment2 = cb.RangePointer(length1, 0) - length1;
- length = cb.Length();
- }
- bool operator==(const SplitView &other) const noexcept {
- return segment1 == other.segment1 && length1 == other.length1 &&
- segment2 == other.segment2 && length == other.length;
- }
- bool operator!=(const SplitView &other) const noexcept {
- return !(*this == other);
- }
-
- char CharAt(size_t position) const noexcept {
- if (position < length1) {
- return segment1[position];
- }
- if (position < length) {
- return segment2[position];
- }
- return 0;
- }
-};
-
// Equivalent of memchr over the split view
ptrdiff_t SplitFindChar(const SplitView &view, size_t start, size_t length, int ch) noexcept {
size_t range1Length = 0;
@@ -2086,7 +2054,7 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con
// Back all of a character
pos = NextPosition(pos, increment);
}
- const SplitView cbView(cb);
+ const SplitView cbView = cb.AllView();
if (caseSensitive) {
const Sci::Position endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
const unsigned char charStartSearch = search[0];
diff --git a/src/SplitVector.h b/src/SplitVector.h
index 2b4aed4be..885055bd1 100644
--- a/src/SplitVector.h
+++ b/src/SplitVector.h
@@ -328,6 +328,16 @@ public:
}
}
+ /// Return a pointer to a single element.
+ /// Does not rearrange the buffer.
+ const T *ElementPointer(ptrdiff_t position) const noexcept {
+ if (position < part1Length) {
+ return body.data() + position;
+ } else {
+ return body.data() + position + gapLength;
+ }
+ }
+
/// Return the position of the gap within the buffer.
ptrdiff_t GapPosition() const noexcept {
return part1Length;