make functions constexpr or noexcept when possible

This commit is contained in:
Ferdinand Bachmann
2020-04-18 13:11:55 +02:00
parent 5feb3f4f60
commit 8cfb62f315
3 changed files with 62 additions and 55 deletions

View File

@@ -2,9 +2,11 @@
#define _RING_BUFFER_CONFIG_H #define _RING_BUFFER_CONFIG_H
#ifdef RING_BUFFER_NOEXCEPT #ifdef RING_BUFFER_NOEXCEPT
#define NOEXCEPT(x) noexcept(x) #define NOEXCEPT noexcept
#define COND_NOEXCEPT(x) noexcept(x)
#else #else
#define NOEXCEPT(x) #define NOEXCEPT
#define COND_NOEXCEPT(x)
#endif #endif
#ifdef RING_BUFFER_CONSTEXPR #ifdef RING_BUFFER_CONSTEXPR

View File

@@ -2,6 +2,7 @@
#define _RING_BUFFER_ITERATOR_H #define _RING_BUFFER_ITERATOR_H
#include <iterator> #include <iterator>
#include <utility>
#include <ring-buffer-config.h> #include <ring-buffer-config.h>
template <typename Container> template <typename Container>
@@ -20,79 +21,81 @@ private:
public: public:
ring_buffer_iterator() = default; ring_buffer_iterator() = default;
~ring_buffer_iterator() = default; ~ring_buffer_iterator() = default;
ring_buffer_iterator(Container& container, size_type front = 0, size_type index = 0) : container(&container), front(front), index(index) {} CONSTEXPR ring_buffer_iterator(Container& container, size_type front = 0, size_type index = 0)
NOEXCEPT(noexcept(container(&container)))
: container(&container), front(front), index(index) {}
ring_buffer_iterator(const ring_buffer_iterator&) = default; ring_buffer_iterator(const ring_buffer_iterator&) = default;
ring_buffer_iterator(ring_buffer_iterator&&) = default; ring_buffer_iterator(ring_buffer_iterator&&) = default;
ring_buffer_iterator& operator=(const ring_buffer_iterator&) = default; ring_buffer_iterator& operator=(const ring_buffer_iterator&) = default;
ring_buffer_iterator& operator=(ring_buffer_iterator&&) = default; ring_buffer_iterator& operator=(ring_buffer_iterator&&) = default;
ring_buffer_iterator& operator+=(difference_type n) { CONSTEXPR ring_buffer_iterator& operator+=(difference_type n) NOEXCEPT {
index += n; index += n;
} }
ring_buffer_iterator& operator-=(difference_type n) { CONSTEXPR ring_buffer_iterator& operator-=(difference_type n) NOEXCEPT {
index -= n; index -= n;
} }
ring_buffer_iterator operator+(difference_type n) const { CONSTEXPR ring_buffer_iterator operator+(difference_type n) const NOEXCEPT {
return {container, front, index + n}; return {container, front, index + n};
} }
ring_buffer_iterator operator-(difference_type n) const { CONSTEXPR ring_buffer_iterator operator-(difference_type n) const NOEXCEPT {
return {container, front, index - n}; return {container, front, index - n};
} }
reference operator*() { CONSTEXPR reference operator*() COND_NOEXCEPT(noexcept(container->begin()) && noexcept(container->size())) {
return *(container->begin() + (front + index) % container->size()); return *(container->begin() + (front + index) % container->size());
} }
pointer operator->() { CONSTEXPR pointer operator->() COND_NOEXCEPT(noexcept(container->begin()) && noexcept(container->size())) {
return &**this; return &**this;
} }
reference operator[](difference_type n) { CONSTEXPR reference operator[](difference_type n) COND_NOEXCEPT(noexcept(container->begin()) && noexcept(container->size())) {
return *(*this + n); return *(*this + n);
} }
ring_buffer_iterator& operator++() { CONSTEXPR ring_buffer_iterator& operator++() NOEXCEPT {
index++; index++;
return *this; return *this;
} }
ring_buffer_iterator operator++(int) { CONSTEXPR ring_buffer_iterator operator++(int) NOEXCEPT {
ring_buffer_iterator old = *this; ring_buffer_iterator old = *this;
*this++; *this++;
return old; return old;
} }
ring_buffer_iterator& operator--() { CONSTEXPR ring_buffer_iterator& operator--() NOEXCEPT {
index--; index--;
return *this; return *this;
} }
ring_buffer_iterator operator--(int) { CONSTEXPR ring_buffer_iterator operator--(int) NOEXCEPT {
ring_buffer_iterator old = *this; ring_buffer_iterator old = *this;
*this--; *this--;
return old; return old;
} }
bool operator==(const ring_buffer_iterator& other) const { CONSTEXPR bool operator==(const ring_buffer_iterator& other) const NOEXCEPT {
return index == other.index; return index == other.index;
} }
bool operator!=(const ring_buffer_iterator& other) const { CONSTEXPR bool operator!=(const ring_buffer_iterator& other) const NOEXCEPT {
return index != other.index; return index != other.index;
} }
bool operator<(const ring_buffer_iterator& other) const { CONSTEXPR bool operator<(const ring_buffer_iterator& other) const NOEXCEPT {
return index < other.index; return index < other.index;
} }
bool operator>(const ring_buffer_iterator& other) const { CONSTEXPR bool operator>(const ring_buffer_iterator& other) const NOEXCEPT {
return index > other.index; return index > other.index;
} }
bool operator<=(const ring_buffer_iterator& other) const { CONSTEXPR bool operator<=(const ring_buffer_iterator& other) const NOEXCEPT {
return index <= other.index; return index <= other.index;
} }
bool operator>=(const ring_buffer_iterator& other) const { CONSTEXPR bool operator>=(const ring_buffer_iterator& other) const NOEXCEPT {
return index >= other.index; return index >= other.index;
} }
friend ring_buffer_iterator operator+( difference_type n, const ring_buffer_iterator& it) { CONSTEXPR friend ring_buffer_iterator operator+( difference_type n, const ring_buffer_iterator& it) NOEXCEPT {
return it + n; return it + n;
} }
friend void swap(ring_buffer_iterator& a, ring_buffer_iterator& b) { CONSTEXPR friend void swap(ring_buffer_iterator& a, ring_buffer_iterator& b) COND_NOEXCEPT(noexcept(std::swap(a.container, b.container))) {
using std::swap; using std::swap;
swap(a.container, b.container); swap(a.container, b.container);
swap(a.front, b.front); swap(a.front, b.front);
@@ -110,85 +113,87 @@ private:
using pointer = typename std::iterator_traits<ring_buffer_const_iterator>::pointer; using pointer = typename std::iterator_traits<ring_buffer_const_iterator>::pointer;
const Container* container; const Container* container;
size_type front{}; size_type front;
size_type index{}; size_type index;
public: public:
ring_buffer_const_iterator() = default; ring_buffer_const_iterator() = default;
~ring_buffer_const_iterator() = default; ~ring_buffer_const_iterator() = default;
ring_buffer_const_iterator(const Container& container, size_type front = 0, size_type index = 0) : container(&container), front(front), index(index) {} CONSTEXPR ring_buffer_const_iterator(const Container& container, size_type front = 0, size_type index = 0)
NOEXCEPT(noexcept(container(&container)))
: container(&container), front(front), index(index) {}
ring_buffer_const_iterator(const ring_buffer_const_iterator&) = default; ring_buffer_const_iterator(const ring_buffer_const_iterator&) = default;
ring_buffer_const_iterator(ring_buffer_const_iterator&&) = default; ring_buffer_const_iterator(ring_buffer_const_iterator&&) = default;
ring_buffer_const_iterator& operator=(const ring_buffer_const_iterator&) = default; ring_buffer_const_iterator& operator=(const ring_buffer_const_iterator&) = default;
ring_buffer_const_iterator& operator=(ring_buffer_const_iterator&&) = default; ring_buffer_const_iterator& operator=(ring_buffer_const_iterator&&) = default;
ring_buffer_const_iterator& operator+=(difference_type n) { CONSTEXPR ring_buffer_const_iterator& operator+=(difference_type n) NOEXCEPT {
index += n; index += n;
} }
ring_buffer_const_iterator& operator-=(difference_type n) { CONSTEXPR ring_buffer_const_iterator& operator-=(difference_type n) NOEXCEPT {
index -= n; index -= n;
} }
ring_buffer_const_iterator operator+(difference_type n) const { CONSTEXPR ring_buffer_const_iterator operator+(difference_type n) const NOEXCEPT {
return {container, front, index + n}; return {container, front, index + n};
} }
ring_buffer_const_iterator operator-(difference_type n) const { CONSTEXPR ring_buffer_const_iterator operator-(difference_type n) const NOEXCEPT {
return {container, front, index - n}; return {container, front, index - n};
} }
reference operator*() const { CONSTEXPR reference operator*() const COND_NOEXCEPT(noexcept(container->cbegin()) && noexcept(container->size())) {
return *(container->begin() + (front + index) % container->size()); return *(container->cbegin() + (front + index) % container->size());
} }
pointer operator->() const { CONSTEXPR pointer operator->() const COND_NOEXCEPT(noexcept(container->cbegin()) && noexcept(container->size())) {
return &**this; return &**this;
} }
reference operator[](difference_type n) const { CONSTEXPR reference operator[](difference_type n) COND_NOEXCEPT(noexcept(container->cbegin()) && noexcept(container->size())) {
return *(*this + n); return *(*this + n);
} }
ring_buffer_const_iterator& operator++() { CONSTEXPR ring_buffer_const_iterator& operator++() NOEXCEPT {
index++; index++;
return *this; return *this;
} }
ring_buffer_const_iterator operator++(int) { CONSTEXPR ring_buffer_const_iterator operator++(int) NOEXCEPT {
ring_buffer_const_iterator old = *this; ring_buffer_const_iterator old = *this;
*this++; *this++;
return old; return old;
} }
ring_buffer_const_iterator& operator--() { CONSTEXPR ring_buffer_const_iterator& operator--() NOEXCEPT {
index--; index--;
return *this; return *this;
} }
ring_buffer_const_iterator operator--(int) { CONSTEXPR ring_buffer_const_iterator operator--(int) NOEXCEPT {
ring_buffer_const_iterator old = *this; ring_buffer_const_iterator old = *this;
*this--; *this--;
return old; return old;
} }
bool operator==(const ring_buffer_const_iterator& other) const { CONSTEXPR bool operator==(const ring_buffer_const_iterator& other) const NOEXCEPT {
return index == other.index; return index == other.index;
} }
bool operator!=(const ring_buffer_const_iterator& other) const { CONSTEXPR bool operator!=(const ring_buffer_const_iterator& other) const NOEXCEPT {
return index != other.index; return index != other.index;
} }
bool operator<(const ring_buffer_const_iterator& other) const { CONSTEXPR bool operator<(const ring_buffer_const_iterator& other) const NOEXCEPT {
return index < other.index; return index < other.index;
} }
bool operator>(const ring_buffer_const_iterator& other) const { CONSTEXPR bool operator>(const ring_buffer_const_iterator& other) const NOEXCEPT {
return index > other.index; return index > other.index;
} }
bool operator<=(const ring_buffer_const_iterator& other) const { CONSTEXPR bool operator<=(const ring_buffer_const_iterator& other) const NOEXCEPT {
return index <= other.index; return index <= other.index;
} }
bool operator>=(const ring_buffer_const_iterator& other) const { CONSTEXPR bool operator>=(const ring_buffer_const_iterator& other) const NOEXCEPT {
return index >= other.index; return index >= other.index;
} }
friend ring_buffer_const_iterator operator+( difference_type n, const ring_buffer_const_iterator& it) { CONSTEXPR friend ring_buffer_const_iterator operator+( difference_type n, const ring_buffer_const_iterator& it) NOEXCEPT {
return it + n; return it + n;
} }
friend void swap(ring_buffer_const_iterator& a, ring_buffer_const_iterator& b) { CONSTEXPR friend void swap(ring_buffer_const_iterator& a, ring_buffer_const_iterator& b) COND_NOEXCEPT(noexcept(std::swap(a.container, b.container))) {
using std::swap; using std::swap;
swap(a.container, b.container); swap(a.container, b.container);
swap(a.front, b.front); swap(a.front, b.front);

View File

@@ -1,6 +1,7 @@
#ifndef _RING_BUFFER_H #ifndef _RING_BUFFER_H
#define _RING_BUFFER_H #define _RING_BUFFER_H
#include <array>
#include <ring-buffer-config.h> #include <ring-buffer-config.h>
#include <ring-buffer-iterator.h> #include <ring-buffer-iterator.h>
@@ -17,41 +18,40 @@ private:
size_type front_index{}; size_type front_index{};
public: public:
CONSTEXPR basic_ring_buffer() NOEXCEPT() = default; basic_ring_buffer() = default;
CONSTEXPR_D ~basic_ring_buffer() NOEXCEPT() = default; ~basic_ring_buffer() = default;
basic_ring_buffer(const basic_ring_buffer& other) = default; basic_ring_buffer(const basic_ring_buffer& other) = default;
basic_ring_buffer(basic_ring_buffer&& other) = default; basic_ring_buffer(basic_ring_buffer&& other) = default;
basic_ring_buffer& operator=(const basic_ring_buffer& other) = default; basic_ring_buffer& operator=(const basic_ring_buffer& other) = default;
basic_ring_buffer& operator=(basic_ring_buffer&& other) = default; basic_ring_buffer& operator=(basic_ring_buffer&& other) = default;
Container& buffer() { CONSTEXPR Container& buffer() NOEXCEPT {
return container; return container;
} }
const Container& buffer() const { CONSTEXPR const Container& buffer() const NOEXCEPT {
return container; return container;
} }
void push_back(const value_type& value) { CONSTEXPR void push_back(const value_type& value) COND_NOEXCEPT(noexcept(container[front_index] = value)) {
container[front_index] = value; container[front_index] = value;
front_index = (front_index + 1) % container.size(); front_index = (front_index + 1) % container.size();
} }
iterator begin() { CONSTEXPR iterator begin() NOEXCEPT {
return {container, front_index, 0}; return {container, front_index, 0};
} }
iterator end() { CONSTEXPR iterator end() COND_NOEXCEPT(noexcept(container.size())) {
return {container, front_index, container.size()}; return {container, front_index, container.size()};
} }
const_iterator cbegin() const { CONSTEXPR const_iterator cbegin() const NOEXCEPT {
return {container, front_index, 0}; return {container, front_index, 0};
} }
const_iterator cend() const { CONSTEXPR const_iterator cend() const COND_NOEXCEPT(noexcept(container.size())) {
return {container, front_index, container.size()}; return {container, front_index, container.size()};
} }
}; };
#include <array>
template <typename T, size_t N> template <typename T, size_t N>
using ring_buffer = basic_ring_buffer<std::array<T, N>>; using ring_buffer = basic_ring_buffer<std::array<T, N>>;