From b9bf45fea55a56203f16a1eea4de7f46d8bbf964 Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 21 Apr 2018 11:22:39 +1000 Subject: Use noexcept in basic data structures where reasonable. Declare the standard member functions in more classes --- src/CellBuffer.h | 2 ++ src/Partitioning.h | 14 +++++++++----- src/PerLine.cxx | 8 ++++---- src/PerLine.h | 10 ++++++---- src/RunStyles.cxx | 20 ++++++++++---------- src/RunStyles.h | 22 ++++++++++++---------- src/SplitVector.h | 25 ++++++++++++------------- 7 files changed, 55 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/CellBuffer.h b/src/CellBuffer.h index 20e81def6..0e2c4f219 100644 --- a/src/CellBuffer.h +++ b/src/CellBuffer.h @@ -130,7 +130,9 @@ public: CellBuffer(bool hasStyles_, bool largeDocument_); // Deleted so CellBuffer objects can not be copied. CellBuffer(const CellBuffer &) = delete; + CellBuffer(CellBuffer &&) = delete; void operator=(const CellBuffer &) = delete; + void operator=(CellBuffer &&) = delete; ~CellBuffer(); /// Retrieving positions outside the range of the buffer works and returns 0 diff --git a/src/Partitioning.h b/src/Partitioning.h index 9237df0fa..c6951388e 100644 --- a/src/Partitioning.h +++ b/src/Partitioning.h @@ -23,10 +23,12 @@ public: } // Deleted so SplitVectorWithRangeAdd objects can not be copied. SplitVectorWithRangeAdd(const SplitVectorWithRangeAdd &) = delete; + SplitVectorWithRangeAdd(SplitVectorWithRangeAdd &&) = delete; void operator=(const SplitVectorWithRangeAdd &) = delete; + void operator=(SplitVectorWithRangeAdd &&) = delete; ~SplitVectorWithRangeAdd() { } - void RangeAddDelta(ptrdiff_t start, ptrdiff_t end, T delta) { + void RangeAddDelta(ptrdiff_t start, ptrdiff_t end, T delta) noexcept { // end is 1 past end, so end-start is number of elements to change ptrdiff_t i = 0; const ptrdiff_t rangeLength = end - start; @@ -63,7 +65,7 @@ private: std::unique_ptr> body; // Move step forward - void ApplyStep(T partitionUpTo) { + void ApplyStep(T partitionUpTo) noexcept { if (stepLength != 0) { body->RangeAddDelta(stepPartition+1, partitionUpTo + 1, stepLength); } @@ -75,7 +77,7 @@ private: } // Move step backward - void BackStep(T partitionDownTo) { + void BackStep(T partitionDownTo) noexcept { if (stepLength != 0) { body->RangeAddDelta(partitionDownTo+1, stepPartition+1, -stepLength); } @@ -91,13 +93,15 @@ private: } public: - explicit Partitioning(int growSize) { + explicit Partitioning(int growSize) : stepPartition(0), stepLength(0) { Allocate(growSize); } // Deleted so Partitioning objects can not be copied. Partitioning(const Partitioning &) = delete; + Partitioning(Partitioning &&) = delete; void operator=(const Partitioning &) = delete; + void operator=(Partitioning &&) = delete; ~Partitioning() { } @@ -114,7 +118,7 @@ public: stepPartition++; } - void SetPartitionStartPosition(T partition, T pos) { + void SetPartitionStartPosition(T partition, T pos) noexcept { ApplyStep(partition+1); if ((partition < 0) || (partition > body->Length())) { return; diff --git a/src/PerLine.cxx b/src/PerLine.cxx index 68677ab22..7a7fc24fa 100644 --- a/src/PerLine.cxx +++ b/src/PerLine.cxx @@ -33,11 +33,11 @@ MarkerHandleSet::~MarkerHandleSet() { mhList.clear(); } -bool MarkerHandleSet::Empty() const { +bool MarkerHandleSet::Empty() const noexcept { return mhList.empty(); } -int MarkerHandleSet::MarkValue() const { +int MarkerHandleSet::MarkValue() const noexcept { unsigned int m = 0; for (const MarkerHandleNumber &mhn : mhList) { m |= (1 << mhn.number); @@ -45,7 +45,7 @@ int MarkerHandleSet::MarkValue() const { return m; } -bool MarkerHandleSet::Contains(int handle) const { +bool MarkerHandleSet::Contains(int handle) const noexcept { for (const MarkerHandleNumber &mhn : mhList) { if (mhn.handle == handle) { return true; @@ -125,7 +125,7 @@ void LineMarkers::MergeMarkers(Sci::Line line) { } } -int LineMarkers::MarkValue(Sci::Line line) { +int LineMarkers::MarkValue(Sci::Line line) noexcept { if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) return markers[line]->MarkValue(); else diff --git a/src/PerLine.h b/src/PerLine.h index 66990799a..c75a83f65 100644 --- a/src/PerLine.h +++ b/src/PerLine.h @@ -32,9 +32,9 @@ public: MarkerHandleSet(const MarkerHandleSet &) = delete; void operator=(const MarkerHandleSet &) = delete; ~MarkerHandleSet(); - bool Empty() const; - int MarkValue() const; ///< Bit set of marker numbers. - bool Contains(int handle) const; + bool Empty() const noexcept; + int MarkValue() const noexcept; ///< Bit set of marker numbers. + bool Contains(int handle) const noexcept; bool InsertHandle(int handle, int markerNum); void RemoveHandle(int handle); bool RemoveNumber(int markerNum, bool all); @@ -50,13 +50,15 @@ public: } // Deleted so Worker objects can not be copied. LineMarkers(const LineMarkers &) = delete; + LineMarkers(LineMarkers &&) = delete; void operator=(const LineMarkers &) = delete; + void operator=(LineMarkers &&) = delete; ~LineMarkers() override; void Init() override; void InsertLine(Sci::Line line) override; void RemoveLine(Sci::Line line) override; - int MarkValue(Sci::Line line); + int MarkValue(Sci::Line line) noexcept; Sci::Line MarkerNext(Sci::Line lineStart, int mask) const; int AddMark(Sci::Line line, int markerNum, Sci::Line lines); void MergeMarkers(Sci::Line line); diff --git a/src/RunStyles.cxx b/src/RunStyles.cxx index 23392436b..95fe10ecd 100644 --- a/src/RunStyles.cxx +++ b/src/RunStyles.cxx @@ -29,7 +29,7 @@ using namespace Scintilla; // Find the first run at a position template -DISTANCE RunStyles::RunFromPosition(DISTANCE position) const { +DISTANCE RunStyles::RunFromPosition(DISTANCE position) const noexcept { DISTANCE run = starts->PartitionFromPosition(position); // Go to first element with this position while ((run > 0) && (position == starts->PositionFromPartition(run-1))) { @@ -88,17 +88,17 @@ RunStyles::~RunStyles() { } template -DISTANCE RunStyles::Length() const { +DISTANCE RunStyles::Length() const noexcept { return starts->PositionFromPartition(starts->Partitions()); } template -STYLE RunStyles::ValueAt(DISTANCE position) const { +STYLE RunStyles::ValueAt(DISTANCE position) const noexcept { return styles->ValueAt(starts->PartitionFromPosition(position)); } template -DISTANCE RunStyles::FindNextChange(DISTANCE position, DISTANCE end) const { +DISTANCE RunStyles::FindNextChange(DISTANCE position, DISTANCE end) const noexcept { const DISTANCE run = starts->PartitionFromPosition(position); if (run < starts->Partitions()) { const DISTANCE runChange = starts->PositionFromPartition(run); @@ -118,12 +118,12 @@ DISTANCE RunStyles::FindNextChange(DISTANCE position, DISTANCE } template -DISTANCE RunStyles::StartRun(DISTANCE position) const { +DISTANCE RunStyles::StartRun(DISTANCE position) const noexcept { return starts->PositionFromPartition(starts->PartitionFromPosition(position)); } template -DISTANCE RunStyles::EndRun(DISTANCE position) const { +DISTANCE RunStyles::EndRun(DISTANCE position) const noexcept { return starts->PositionFromPartition(starts->PartitionFromPosition(position) + 1); } @@ -243,12 +243,12 @@ void RunStyles::DeleteRange(DISTANCE position, DISTANCE deleteL } template -DISTANCE RunStyles::Runs() const { +DISTANCE RunStyles::Runs() const noexcept { return starts->Partitions(); } template -bool RunStyles::AllSame() const { +bool RunStyles::AllSame() const noexcept { for (int run = 1; run < starts->Partitions(); run++) { if (styles->ValueAt(run) != styles->ValueAt(run - 1)) return false; @@ -257,12 +257,12 @@ bool RunStyles::AllSame() const { } template -bool RunStyles::AllSameAs(STYLE value) const { +bool RunStyles::AllSameAs(STYLE value) const noexcept { return AllSame() && (styles->ValueAt(0) == value); } template -DISTANCE RunStyles::Find(STYLE value, DISTANCE start) const { +DISTANCE RunStyles::Find(STYLE value, DISTANCE start) const noexcept { if (start < Length()) { DISTANCE run = start ? RunFromPosition(start) : 0; if (styles->ValueAt(run) == value) diff --git a/src/RunStyles.h b/src/RunStyles.h index af2eb3ec6..97673d04b 100644 --- a/src/RunStyles.h +++ b/src/RunStyles.h @@ -27,7 +27,7 @@ class RunStyles { private: std::unique_ptr> starts; std::unique_ptr> styles; - DISTANCE RunFromPosition(DISTANCE position) const; + DISTANCE RunFromPosition(DISTANCE position) const noexcept; DISTANCE SplitRun(DISTANCE position); void RemoveRun(DISTANCE run); void RemoveRunIfEmpty(DISTANCE run); @@ -36,23 +36,25 @@ public: RunStyles(); // Deleted so RunStyles objects can not be copied. RunStyles(const RunStyles &) = delete; + RunStyles(RunStyles &&) = delete; void operator=(const RunStyles &) = delete; + void operator=(RunStyles &&) = delete; ~RunStyles(); - DISTANCE Length() const; - STYLE ValueAt(DISTANCE position) const; - DISTANCE FindNextChange(DISTANCE position, DISTANCE end) const; - DISTANCE StartRun(DISTANCE position) const; - DISTANCE EndRun(DISTANCE position) const; + DISTANCE Length() const noexcept; + STYLE ValueAt(DISTANCE position) const noexcept; + DISTANCE FindNextChange(DISTANCE position, DISTANCE end) const noexcept; + DISTANCE StartRun(DISTANCE position) const noexcept; + DISTANCE EndRun(DISTANCE position) const noexcept; // Returns changed=true if some values may have changed FillResult FillRange(DISTANCE position, STYLE value, DISTANCE fillLength); void SetValueAt(DISTANCE position, STYLE value); void InsertSpace(DISTANCE position, DISTANCE insertLength); void DeleteAll(); void DeleteRange(DISTANCE position, DISTANCE deleteLength); - DISTANCE Runs() const; - bool AllSame() const; - bool AllSameAs(STYLE value) const; - DISTANCE Find(STYLE value, DISTANCE start) const; + DISTANCE Runs() const noexcept; + bool AllSame() const noexcept; + bool AllSameAs(STYLE value) const noexcept; + DISTANCE Find(STYLE value, DISTANCE start) const noexcept; void Check() const; }; diff --git a/src/SplitVector.h b/src/SplitVector.h index 40061c955..39895a700 100644 --- a/src/SplitVector.h +++ b/src/SplitVector.h @@ -24,7 +24,7 @@ protected: /// Move the gap to a particular position so that insertion and /// deletion at that point will not require much copying and /// hence be fast. - void GapTo(ptrdiff_t position) { + void GapTo(ptrdiff_t position) noexcept { if (position != part1Length) { if (position < part1Length) { // Moving the gap towards start so moving elements towards end @@ -56,21 +56,22 @@ protected: void Init() { body.clear(); body.shrink_to_fit(); - growSize = 8; lengthBody = 0; part1Length = 0; gapLength = 0; + growSize = 8; } public: /// Construct a split buffer. - SplitVector() : empty() { - Init(); + SplitVector() : empty(), lengthBody(0), part1Length(0), gapLength(0), growSize(8) { } // Deleted so SplitVector objects can not be copied. SplitVector(const SplitVector &) = delete; + SplitVector(SplitVector &&) = delete; void operator=(const SplitVector &) = delete; + void operator=(SplitVector &&) = delete; ~SplitVector() { } @@ -124,7 +125,7 @@ public: /// Setting positions outside the range of the buffer performs no assignment /// but asserts in debug builds. template - void SetValueAt(ptrdiff_t position, ParamType&& v) { + void SetValueAt(ptrdiff_t position, ParamType&& v) noexcept { if (position < part1Length) { PLATFORM_ASSERT(position >= 0); if (position < 0) { @@ -250,14 +251,12 @@ public: /// Delete one element from the buffer. void Delete(ptrdiff_t position) { PLATFORM_ASSERT((position >= 0) && (position < lengthBody)); - if ((position < 0) || (position >= lengthBody)) { - return; - } DeleteRange(position, 1); } /// Delete a range from the buffer. /// Deleting positions outside the current range fails. + /// Cannot be noexcept as vector::shrink_to_fit may be called and it may throw. void DeleteRange(ptrdiff_t position, ptrdiff_t deleteLength) { PLATFORM_ASSERT((position >= 0) && (position + deleteLength <= lengthBody)); if ((position < 0) || ((position + deleteLength) > lengthBody)) { @@ -265,8 +264,6 @@ public: } if ((position == 0) && (deleteLength == lengthBody)) { // Full deallocation returns storage and is faster - body.clear(); - body.shrink_to_fit(); Init(); } else if (deleteLength > 0) { GapTo(position); @@ -281,7 +278,7 @@ public: } /// Retrieve a range of elements into an array - void GetRange(T *buffer, ptrdiff_t position, ptrdiff_t retrieveLength) const { + void GetRange(T *buffer, ptrdiff_t position, ptrdiff_t retrieveLength) const noexcept { // Split into up to 2 ranges, before and after the split then use memcpy on each. ptrdiff_t range1Length = 0; if (position < part1Length) { @@ -298,6 +295,8 @@ public: } /// Compact the buffer and return a pointer to the first element. + /// Also ensures there is an empty element beyond logical end in case its + /// passed to a function expecting a NUL terminated string. T *BufferPointer() { RoomFor(1); GapTo(lengthBody); @@ -308,7 +307,7 @@ public: /// Return a pointer to a range of elements, first rearranging the buffer if /// needed to make that range contiguous. - T *RangePointer(ptrdiff_t position, ptrdiff_t rangeLength) { + T *RangePointer(ptrdiff_t position, ptrdiff_t rangeLength) noexcept { if (position < part1Length) { if ((position + rangeLength) > part1Length) { // Range overlaps gap, so move gap to start of range. @@ -323,7 +322,7 @@ public: } /// Return the position of the gap within the buffer. - ptrdiff_t GapPosition() const { + ptrdiff_t GapPosition() const noexcept { return part1Length; } }; -- cgit v1.2.3