aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/SparseVector.h
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2019-12-01 20:41:27 +1100
committerNeil <nyamatongwe@gmail.com>2019-12-01 20:41:27 +1100
commit2892e0d04bcf02fe249939f7c22fe8c6d780233a (patch)
tree8df27d8568a6a1ef7c07eb77819bd589b298e464 /src/SparseVector.h
parent7153448eb8dfe267f96eb55aee683172f15cc283 (diff)
downloadscintilla-mirror-2892e0d04bcf02fe249939f7c22fe8c6d780233a.tar.gz
Backport: Allow setting value at end of a SparseVector.
Change representation of SparseVector in tests so last value can be seen. Backport of changeset 7778:b7842ad8047b.
Diffstat (limited to 'src/SparseVector.h')
-rw-r--r--src/SparseVector.h39
1 files changed, 23 insertions, 16 deletions
diff --git a/src/SparseVector.h b/src/SparseVector.h
index 67ad1e1e3..6dd02ba8b 100644
--- a/src/SparseVector.h
+++ b/src/SparseVector.h
@@ -12,13 +12,17 @@ namespace Scintilla {
// SparseVector is similar to RunStyles but is more efficient for cases where values occur
// for one position instead of over a range of positions.
+// There are always elements at the start and end, so the element type should have
+// a reasonable empty value that will cause no problems.
+// The element type should have a noexcept default constructor as that allows methods to
+// be noexcept.
template <typename T>
class SparseVector {
private:
std::unique_ptr<Partitioning<Sci::Position>> starts;
std::unique_ptr<SplitVector<T>> values;
- T empty;
- void ClearValue(Sci::Position partition) {
+ T empty; // Return from ValueAt when no element at a position.
+ void ClearValue(Sci::Position partition) noexcept {
values->SetValueAt(partition, T());
}
public:
@@ -40,18 +44,25 @@ public:
}
values.reset();
}
- Sci::Position Length() const {
- return starts->PositionFromPartition(starts->Partitions());
+ Sci::Position Length() const noexcept {
+ return starts->Length();
}
- Sci::Position Elements() const {
+ Sci::Position Elements() const noexcept {
return starts->Partitions();
}
- Sci::Position PositionOfElement(int element) const {
+ Sci::Position PositionOfElement(Sci::Position element) const noexcept {
return starts->PositionFromPartition(element);
}
- const T& ValueAt(Sci::Position position) const {
- assert(position < Length());
- const Sci::Position partition = starts->PartitionFromPosition(position);
+ Sci::Position ElementFromPosition(Sci::Position position) const noexcept {
+ if (position < Length()) {
+ return starts->PartitionFromPosition(position);
+ } else {
+ return starts->Partitions();
+ }
+ }
+ const T& ValueAt(Sci::Position position) const noexcept {
+ assert(position <= Length());
+ const Sci::Position partition = ElementFromPosition(position);
const Sci::Position startPartition = starts->PositionFromPartition(partition);
if (startPartition == position) {
return values->ValueAt(partition);
@@ -61,8 +72,8 @@ public:
}
template <typename ParamType>
void SetValueAt(Sci::Position position, ParamType &&value) {
- assert(position < Length());
- const Sci::Position partition = starts->PartitionFromPosition(position);
+ assert(position <= Length());
+ const Sci::Position partition = ElementFromPosition(position);
const Sci::Position startPartition = starts->PositionFromPartition(partition);
if (value == T()) {
// Setting the empty value is equivalent to deleting the position
@@ -88,7 +99,7 @@ public:
}
}
void InsertSpace(Sci::Position position, Sci::Position insertLength) {
- assert(position <= Length()); // Only operation that works at end.
+ assert(position <= Length());
const Sci::Position partition = starts->PartitionFromPosition(position);
const Sci::Position startPartition = starts->PositionFromPartition(partition);
if (startPartition == position) {
@@ -149,10 +160,6 @@ public:
if (starts->Partitions() != values->Length() - 1) {
throw std::runtime_error("SparseVector: Partitions and values different lengths.");
}
- // The final element can not be set
- if (values->ValueAt(values->Length() - 1) != T()) {
- throw std::runtime_error("SparseVector: Unused style at end changed.");
- }
#endif
}
};