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/SplitVector.h | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'src/SplitVector.h') 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