util/{Const,Writable}Buffer: add noexcept

This commit is contained in:
Max Kellermann 2020-01-03 15:39:19 +01:00
parent 71ace2fbac
commit 4b0e288f00
2 changed files with 67 additions and 62 deletions

View File

@ -55,32 +55,33 @@ struct ConstBuffer<void> {
ConstBuffer() = default; ConstBuffer() = default;
constexpr ConstBuffer(std::nullptr_t):data(nullptr), size(0) {} constexpr ConstBuffer(std::nullptr_t) noexcept
:data(nullptr), size(0) {}
constexpr ConstBuffer(pointer_type _data, size_type _size) constexpr ConstBuffer(pointer_type _data, size_type _size) noexcept
:data(_data), size(_size) {} :data(_data), size(_size) {}
constexpr static ConstBuffer<void> FromVoid(ConstBuffer<void> other) { constexpr static ConstBuffer<void> FromVoid(ConstBuffer<void> other) noexcept {
return other; return other;
} }
constexpr ConstBuffer<void> ToVoid() const { constexpr ConstBuffer<void> ToVoid() const noexcept {
return *this; return *this;
} }
constexpr bool IsNull() const { constexpr bool IsNull() const noexcept {
return data == nullptr; return data == nullptr;
} }
constexpr bool operator==(std::nullptr_t) const { constexpr bool operator==(std::nullptr_t) const noexcept {
return data == nullptr; return data == nullptr;
} }
constexpr bool operator!=(std::nullptr_t) const { constexpr bool operator!=(std::nullptr_t) const noexcept {
return data != nullptr; return data != nullptr;
} }
constexpr bool empty() const { constexpr bool empty() const noexcept {
return size == 0; return size == 0;
} }
}; };
@ -104,26 +105,27 @@ struct ConstBuffer {
ConstBuffer() = default; ConstBuffer() = default;
constexpr ConstBuffer(std::nullptr_t):data(nullptr), size(0) {} constexpr ConstBuffer(std::nullptr_t) noexcept
:data(nullptr), size(0) {}
constexpr ConstBuffer(pointer_type _data, size_type _size) constexpr ConstBuffer(pointer_type _data, size_type _size) noexcept
:data(_data), size(_size) {} :data(_data), size(_size) {}
constexpr ConstBuffer(pointer_type _data, pointer_type _end) constexpr ConstBuffer(pointer_type _data, pointer_type _end) noexcept
:data(_data), size(_end - _data) {} :data(_data), size(_end - _data) {}
/** /**
* Convert array to ConstBuffer instance. * Convert array to ConstBuffer instance.
*/ */
template<size_type _size> template<size_type _size>
constexpr ConstBuffer(const T (&_data)[_size]) constexpr ConstBuffer(const T (&_data)[_size]) noexcept
:data(_data), size(_size) {} :data(_data), size(_size) {}
/** /**
* Cast a ConstBuffer<void> to a ConstBuffer<T>, rounding down * Cast a ConstBuffer<void> to a ConstBuffer<T>, rounding down
* to the next multiple of T's size. * to the next multiple of T's size.
*/ */
static constexpr ConstBuffer<T> FromVoidFloor(ConstBuffer<void> other) { static constexpr ConstBuffer<T> FromVoidFloor(ConstBuffer<void> other) noexcept {
static_assert(sizeof(T) > 0, "Empty base type"); static_assert(sizeof(T) > 0, "Empty base type");
return ConstBuffer<T>(pointer_type(other.data), return ConstBuffer<T>(pointer_type(other.data),
other.size / sizeof(T)); other.size / sizeof(T));
@ -138,7 +140,7 @@ struct ConstBuffer {
#ifdef NDEBUG #ifdef NDEBUG
constexpr constexpr
#endif #endif
static ConstBuffer<T> FromVoid(ConstBuffer<void> other) { static ConstBuffer<T> FromVoid(ConstBuffer<void> other) noexcept {
static_assert(sizeof(T) > 0, "Empty base type"); static_assert(sizeof(T) > 0, "Empty base type");
#ifndef NDEBUG #ifndef NDEBUG
assert(other.size % sizeof(T) == 0); assert(other.size % sizeof(T) == 0);
@ -146,24 +148,24 @@ struct ConstBuffer {
return FromVoidFloor(other); return FromVoidFloor(other);
} }
constexpr ConstBuffer<void> ToVoid() const { constexpr ConstBuffer<void> ToVoid() const noexcept {
static_assert(sizeof(T) > 0, "Empty base type"); static_assert(sizeof(T) > 0, "Empty base type");
return ConstBuffer<void>(data, size * sizeof(T)); return ConstBuffer<void>(data, size * sizeof(T));
} }
constexpr bool IsNull() const { constexpr bool IsNull() const noexcept {
return data == nullptr; return data == nullptr;
} }
constexpr bool operator==(std::nullptr_t) const { constexpr bool operator==(std::nullptr_t) const noexcept {
return data == nullptr; return data == nullptr;
} }
constexpr bool operator!=(std::nullptr_t) const { constexpr bool operator!=(std::nullptr_t) const noexcept {
return data != nullptr; return data != nullptr;
} }
constexpr bool empty() const { constexpr bool empty() const noexcept {
return size == 0; return size == 0;
} }
@ -177,26 +179,26 @@ struct ConstBuffer {
return false; return false;
} }
constexpr iterator begin() const { constexpr iterator begin() const noexcept {
return data; return data;
} }
constexpr iterator end() const { constexpr iterator end() const noexcept {
return data + size; return data + size;
} }
constexpr const_iterator cbegin() const { constexpr const_iterator cbegin() const noexcept {
return data; return data;
} }
constexpr const_iterator cend() const { constexpr const_iterator cend() const noexcept {
return data + size; return data + size;
} }
#ifdef NDEBUG #ifdef NDEBUG
constexpr constexpr
#endif #endif
reference_type operator[](size_type i) const { reference_type operator[](size_type i) const noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(i < size); assert(i < size);
#endif #endif
@ -211,7 +213,7 @@ struct ConstBuffer {
#ifdef NDEBUG #ifdef NDEBUG
constexpr constexpr
#endif #endif
reference_type front() const { reference_type front() const noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(!empty()); assert(!empty());
#endif #endif
@ -225,7 +227,7 @@ struct ConstBuffer {
#ifdef NDEBUG #ifdef NDEBUG
constexpr constexpr
#endif #endif
reference_type back() const { reference_type back() const noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(!empty()); assert(!empty());
#endif #endif
@ -236,7 +238,7 @@ struct ConstBuffer {
* Remove the first element (by moving the head pointer, does * Remove the first element (by moving the head pointer, does
* not actually modify the buffer). Buffer must not be empty. * not actually modify the buffer). Buffer must not be empty.
*/ */
void pop_front() { void pop_front() noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(!empty()); assert(!empty());
#endif #endif
@ -249,7 +251,7 @@ struct ConstBuffer {
* Remove the last element (by moving the tail pointer, does * Remove the last element (by moving the tail pointer, does
* not actually modify the buffer). Buffer must not be empty. * not actually modify the buffer). Buffer must not be empty.
*/ */
void pop_back() { void pop_back() noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(!empty()); assert(!empty());
#endif #endif
@ -261,13 +263,13 @@ struct ConstBuffer {
* Remove the first element and return a reference to it. * Remove the first element and return a reference to it.
* Buffer must not be empty. * Buffer must not be empty.
*/ */
reference_type shift() { reference_type shift() noexcept {
reference_type result = front(); reference_type result = front();
pop_front(); pop_front();
return result; return result;
} }
void skip_front(size_type n) { void skip_front(size_type n) noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(size >= n); assert(size >= n);
#endif #endif
@ -280,7 +282,7 @@ struct ConstBuffer {
* Move the front pointer to the given address, and adjust the * Move the front pointer to the given address, and adjust the
* size attribute to retain the old end address. * size attribute to retain the old end address.
*/ */
void MoveFront(pointer_type new_data) { void MoveFront(pointer_type new_data) noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(IsNull() == (new_data == nullptr)); assert(IsNull() == (new_data == nullptr));
assert(new_data <= end()); assert(new_data <= end());
@ -294,7 +296,7 @@ struct ConstBuffer {
* Move the end pointer to the given address (by adjusting the * Move the end pointer to the given address (by adjusting the
* size). * size).
*/ */
void SetEnd(pointer_type new_end) { void SetEnd(pointer_type new_end) noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(IsNull() == (new_end == nullptr)); assert(IsNull() == (new_end == nullptr));
assert(new_end >= begin()); assert(new_end >= begin());

View File

@ -56,28 +56,29 @@ struct WritableBuffer<void> {
WritableBuffer() = default; WritableBuffer() = default;
constexpr WritableBuffer(std::nullptr_t):data(nullptr), size(0) {} constexpr WritableBuffer(std::nullptr_t) noexcept
:data(nullptr), size(0) {}
constexpr WritableBuffer(pointer_type _data, size_type _size) constexpr WritableBuffer(pointer_type _data, size_type _size) noexcept
:data(_data), size(_size) {} :data(_data), size(_size) {}
constexpr operator ConstBuffer<void>() const noexcept { constexpr operator ConstBuffer<void>() const noexcept {
return {data, size}; return {data, size};
} }
constexpr bool IsNull() const { constexpr bool IsNull() const noexcept {
return data == nullptr; return data == nullptr;
} }
constexpr bool operator==(std::nullptr_t) const { constexpr bool operator==(std::nullptr_t) const noexcept {
return data == nullptr; return data == nullptr;
} }
constexpr bool operator!=(std::nullptr_t) const { constexpr bool operator!=(std::nullptr_t) const noexcept {
return data != nullptr; return data != nullptr;
} }
constexpr bool empty() const { constexpr bool empty() const noexcept {
return size == 0; return size == 0;
} }
}; };
@ -103,19 +104,21 @@ struct WritableBuffer {
WritableBuffer() = default; WritableBuffer() = default;
constexpr WritableBuffer(std::nullptr_t):data(nullptr), size(0) {} constexpr WritableBuffer(std::nullptr_t) noexcept
:data(nullptr), size(0) {}
constexpr WritableBuffer(pointer_type _data, size_type _size) constexpr WritableBuffer(pointer_type _data, size_type _size) noexcept
:data(_data), size(_size) {} :data(_data), size(_size) {}
constexpr WritableBuffer(pointer_type _data, pointer_type _end) constexpr WritableBuffer(pointer_type _data,
pointer_type _end) noexcept
:data(_data), size(_end - _data) {} :data(_data), size(_end - _data) {}
/** /**
* Convert array to WritableBuffer instance. * Convert array to WritableBuffer instance.
*/ */
template<size_type _size> template<size_type _size>
constexpr WritableBuffer(T (&_data)[_size]) constexpr WritableBuffer(T (&_data)[_size]) noexcept
:data(_data), size(_size) {} :data(_data), size(_size) {}
constexpr operator ConstBuffer<T>() const noexcept { constexpr operator ConstBuffer<T>() const noexcept {
@ -126,7 +129,7 @@ struct WritableBuffer {
* Cast a WritableBuffer<void> to a WritableBuffer<T>, * Cast a WritableBuffer<void> to a WritableBuffer<T>,
* rounding down to the next multiple of T's size. * rounding down to the next multiple of T's size.
*/ */
static constexpr WritableBuffer<T> FromVoidFloor(WritableBuffer<void> other) { static constexpr WritableBuffer<T> FromVoidFloor(WritableBuffer<void> other) noexcept {
static_assert(sizeof(T) > 0, "Empty base type"); static_assert(sizeof(T) > 0, "Empty base type");
return WritableBuffer<T>(pointer_type(other.data), return WritableBuffer<T>(pointer_type(other.data),
other.size / sizeof(T)); other.size / sizeof(T));
@ -141,7 +144,7 @@ struct WritableBuffer {
#ifdef NDEBUG #ifdef NDEBUG
constexpr constexpr
#endif #endif
static WritableBuffer<T> FromVoid(WritableBuffer<void> other) { static WritableBuffer<T> FromVoid(WritableBuffer<void> other) noexcept {
static_assert(sizeof(T) > 0, "Empty base type"); static_assert(sizeof(T) > 0, "Empty base type");
#ifndef NDEBUG #ifndef NDEBUG
assert(other.size % sizeof(T) == 0); assert(other.size % sizeof(T) == 0);
@ -149,47 +152,47 @@ struct WritableBuffer {
return FromVoidFloor(other); return FromVoidFloor(other);
} }
constexpr WritableBuffer<void> ToVoid() const { constexpr WritableBuffer<void> ToVoid() const noexcept {
static_assert(sizeof(T) > 0, "Empty base type"); static_assert(sizeof(T) > 0, "Empty base type");
return WritableBuffer<void>(data, size * sizeof(T)); return WritableBuffer<void>(data, size * sizeof(T));
} }
constexpr bool IsNull() const { constexpr bool IsNull() const noexcept {
return data == nullptr; return data == nullptr;
} }
constexpr bool operator==(std::nullptr_t) const { constexpr bool operator==(std::nullptr_t) const noexcept {
return data == nullptr; return data == nullptr;
} }
constexpr bool operator!=(std::nullptr_t) const { constexpr bool operator!=(std::nullptr_t) const noexcept {
return data != nullptr; return data != nullptr;
} }
constexpr bool empty() const { constexpr bool empty() const noexcept {
return size == 0; return size == 0;
} }
constexpr iterator begin() const { constexpr iterator begin() const noexcept {
return data; return data;
} }
constexpr iterator end() const { constexpr iterator end() const noexcept {
return data + size; return data + size;
} }
constexpr const_iterator cbegin() const { constexpr const_iterator cbegin() const noexcept {
return data; return data;
} }
constexpr const_iterator cend() const { constexpr const_iterator cend() const noexcept {
return data + size; return data + size;
} }
#ifdef NDEBUG #ifdef NDEBUG
constexpr constexpr
#endif #endif
reference_type operator[](size_type i) const { reference_type operator[](size_type i) const noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(i < size); assert(i < size);
#endif #endif
@ -204,7 +207,7 @@ struct WritableBuffer {
#ifdef NDEBUG #ifdef NDEBUG
constexpr constexpr
#endif #endif
reference_type front() const { reference_type front() const noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(!empty()); assert(!empty());
#endif #endif
@ -218,7 +221,7 @@ struct WritableBuffer {
#ifdef NDEBUG #ifdef NDEBUG
constexpr constexpr
#endif #endif
reference_type back() const { reference_type back() const noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(!empty()); assert(!empty());
#endif #endif
@ -229,7 +232,7 @@ struct WritableBuffer {
* Remove the first element (by moving the head pointer, does * Remove the first element (by moving the head pointer, does
* not actually modify the buffer). Buffer must not be empty. * not actually modify the buffer). Buffer must not be empty.
*/ */
void pop_front() { void pop_front() noexcept {
assert(!empty()); assert(!empty());
++data; ++data;
@ -240,7 +243,7 @@ struct WritableBuffer {
* Remove the last element (by moving the tail pointer, does * Remove the last element (by moving the tail pointer, does
* not actually modify the buffer). Buffer must not be empty. * not actually modify the buffer). Buffer must not be empty.
*/ */
void pop_back() { void pop_back() noexcept {
assert(!empty()); assert(!empty());
--size; --size;
@ -250,13 +253,13 @@ struct WritableBuffer {
* Remove the first element and return a reference to it. * Remove the first element and return a reference to it.
* Buffer must not be empty. * Buffer must not be empty.
*/ */
reference_type shift() { reference_type shift() noexcept {
reference_type result = front(); reference_type result = front();
pop_front(); pop_front();
return result; return result;
} }
void skip_front(size_type n) { void skip_front(size_type n) noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(size >= n); assert(size >= n);
#endif #endif
@ -269,7 +272,7 @@ struct WritableBuffer {
* Move the front pointer to the given address, and adjust the * Move the front pointer to the given address, and adjust the
* size attribute to retain the old end address. * size attribute to retain the old end address.
*/ */
void MoveFront(pointer_type new_data) { void MoveFront(pointer_type new_data) noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(IsNull() == (new_data == nullptr)); assert(IsNull() == (new_data == nullptr));
assert(new_data <= end()); assert(new_data <= end());
@ -283,7 +286,7 @@ struct WritableBuffer {
* Move the end pointer to the given address (by adjusting the * Move the end pointer to the given address (by adjusting the
* size). * size).
*/ */
void SetEnd(pointer_type new_end) { void SetEnd(pointer_type new_end) noexcept {
#ifndef NDEBUG #ifndef NDEBUG
assert(IsNull() == (new_end == nullptr)); assert(IsNull() == (new_end == nullptr));
assert(new_end >= begin()); assert(new_end >= begin());