size_t _item_index = 0;
protected:
- inline explicit basic_iterator(chunk* c);
- inline basic_iterator(chunk* c, size_t item_index);
+ inline explicit basic_iterator(chunk* c) noexcept;
+ inline basic_iterator(chunk* c, size_t item_index) noexcept;
public:
- inline bool operator==(const basic_iterator& o) const;
- inline bool operator!=(const basic_iterator& o) const;
- inline pointer operator->() const;
- inline reference operator*() const;
- inline basic_iterator operator++(int);
- basic_iterator& operator++();
+ inline bool operator==(const basic_iterator& o) const noexcept;
+ inline bool operator!=(const basic_iterator& o) const noexcept;
+ inline pointer operator->() const noexcept;
+ inline reference operator*() const noexcept;
+ inline basic_iterator operator++(int) noexcept;
+ basic_iterator& operator++() noexcept;
};
public:
class iterator : public basic_iterator<T> {
using basic_iterator<T>::basic_iterator;
public:
- iterator() = default;
+ iterator() noexcept = default;
};
class const_iterator : public basic_iterator<const T> {
using basic_iterator<T>::basic_iterator;
public:
- const_iterator() = default;
- inline const_iterator(iterator o);
+ const_iterator() noexcept = default;
+ inline const_iterator(iterator o) noexcept;
};
public:
- chunked_fifo() = default;
+ chunked_fifo() noexcept = default;
chunked_fifo(chunked_fifo&& x) noexcept;
chunked_fifo(const chunked_fifo& X) = delete;
~chunked_fifo();
chunked_fifo& operator=(chunked_fifo&&) noexcept;
inline void push_back(const T& data);
inline void push_back(T&& data);
- T& back();
- const T& back() const;
+ T& back() noexcept;
+ const T& back() const noexcept;
template <typename... A>
inline void emplace_back(A&&... args);
inline T& front() const noexcept;
void reserve(size_t n);
// shrink_to_fit() frees memory held, but unused, by the queue. Such
// unused memory might exist after pops, or because of reserve().
- void shrink_to_fit();
- inline iterator begin();
- inline iterator end();
- inline const_iterator begin() const;
- inline const_iterator end() const;
- inline const_iterator cbegin() const;
- inline const_iterator cend() const;
+ void shrink_to_fit() noexcept;
+ inline iterator begin() noexcept;
+ inline iterator end() noexcept;
+ inline const_iterator begin() const noexcept;
+ inline const_iterator end() const noexcept;
+ inline const_iterator cbegin() const noexcept;
+ inline const_iterator cend() const noexcept;
private:
void back_chunk_new();
void front_chunk_delete() noexcept;
inline void ensure_room_back();
- void undo_room_back();
+ void undo_room_back() noexcept;
static inline size_t mask(size_t idx) noexcept;
};
template <typename T, size_t items_per_chunk>
template <typename U>
inline
-chunked_fifo<T, items_per_chunk>::basic_iterator<U>::basic_iterator(chunk* c) : _chunk(c), _item_index(_chunk ? _chunk->begin : 0) {
+chunked_fifo<T, items_per_chunk>::basic_iterator<U>::basic_iterator(chunk* c) noexcept : _chunk(c), _item_index(_chunk ? _chunk->begin : 0) {
}
template <typename T, size_t items_per_chunk>
template <typename U>
inline
-chunked_fifo<T, items_per_chunk>::basic_iterator<U>::basic_iterator(chunk* c, size_t item_index) : _chunk(c), _item_index(item_index) {
+chunked_fifo<T, items_per_chunk>::basic_iterator<U>::basic_iterator(chunk* c, size_t item_index) noexcept : _chunk(c), _item_index(item_index) {
}
template <typename T, size_t items_per_chunk>
template <typename U>
inline bool
-chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator==(const basic_iterator& o) const {
+chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator==(const basic_iterator& o) const noexcept {
return _chunk == o._chunk && _item_index == o._item_index;
}
template <typename T, size_t items_per_chunk>
template <typename U>
inline bool
-chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator!=(const basic_iterator& o) const {
+chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator!=(const basic_iterator& o) const noexcept {
return !(*this == o);
}
template <typename T, size_t items_per_chunk>
template <typename U>
inline typename chunked_fifo<T, items_per_chunk>::template basic_iterator<U>::pointer
-chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator->() const {
+chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator->() const noexcept {
return &_chunk->items[chunked_fifo::mask(_item_index)].data;
}
template <typename T, size_t items_per_chunk>
template <typename U>
inline typename chunked_fifo<T, items_per_chunk>::template basic_iterator<U>::reference
-chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator*() const {
+chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator*() const noexcept {
return _chunk->items[chunked_fifo::mask(_item_index)].data;
}
template <typename T, size_t items_per_chunk>
template <typename U>
inline typename chunked_fifo<T, items_per_chunk>::template basic_iterator<U>
-chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator++(int) {
+chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator++(int) noexcept {
auto it = *this;
++(*this);
return it;
template <typename T, size_t items_per_chunk>
template <typename U>
typename chunked_fifo<T, items_per_chunk>::template basic_iterator<U>&
-chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator++() {
+chunked_fifo<T, items_per_chunk>::basic_iterator<U>::operator++() noexcept {
++_item_index;
if (_item_index == _chunk->end) {
_chunk = _chunk->next;
template <typename T, size_t items_per_chunk>
inline
-chunked_fifo<T, items_per_chunk>::const_iterator::const_iterator(chunked_fifo<T, items_per_chunk>::iterator o)
+chunked_fifo<T, items_per_chunk>::const_iterator::const_iterator(chunked_fifo<T, items_per_chunk>::iterator o) noexcept
: basic_iterator<const T>(o._chunk, o._item_index) {
}
}
template <typename T, size_t items_per_chunk> void
-chunked_fifo<T, items_per_chunk>::shrink_to_fit() {
+chunked_fifo<T, items_per_chunk>::shrink_to_fit() noexcept {
while (_free_chunks) {
auto next = _free_chunks->next;
delete _free_chunks;
template <typename T, size_t items_per_chunk>
void
-chunked_fifo<T, items_per_chunk>::undo_room_back() {
+chunked_fifo<T, items_per_chunk>::undo_room_back() noexcept {
// If we failed creating a new item after ensure_room_back() created a
// new empty chunk, we must remove it, or empty() will be incorrect
// (either immediately, if the fifo was empty, or when all the items are
template <typename T, size_t items_per_chunk>
inline
T&
-chunked_fifo<T, items_per_chunk>::back() {
+chunked_fifo<T, items_per_chunk>::back() noexcept {
return _back_chunk->items[mask(_back_chunk->end - 1)].data;
}
template <typename T, size_t items_per_chunk>
inline
const T&
-chunked_fifo<T, items_per_chunk>::back() const {
+chunked_fifo<T, items_per_chunk>::back() const noexcept {
return _back_chunk->items[mask(_back_chunk->end - 1)].data;
}
void chunked_fifo<T, items_per_chunk>::reserve(size_t n) {
// reserve() guarantees that (n - size()) additional push()es will
// succeed without reallocation:
+ if (n <= size()) {
+ return;
+ }
size_t need = n - size();
// If we already have a back chunk, it might have room for some pushes
// before filling up, so decrease "need":
if (_back_chunk) {
- need -= items_per_chunk - (_back_chunk->end - _back_chunk->begin);
+ size_t back_chunk_n = items_per_chunk - (_back_chunk->end - _back_chunk->begin);
+ need -= std::min(back_chunk_n, need);
}
size_t needed_chunks = (need + items_per_chunk - 1) / items_per_chunk;
// If we already have some freed chunks saved, we need to allocate fewer
template <typename T, size_t items_per_chunk>
inline typename chunked_fifo<T, items_per_chunk>::iterator
-chunked_fifo<T, items_per_chunk>::begin() {
+chunked_fifo<T, items_per_chunk>::begin() noexcept {
return iterator(_front_chunk);
}
template <typename T, size_t items_per_chunk>
inline typename chunked_fifo<T, items_per_chunk>::iterator
-chunked_fifo<T, items_per_chunk>::end() {
+chunked_fifo<T, items_per_chunk>::end() noexcept {
return iterator(nullptr);
}
template <typename T, size_t items_per_chunk>
inline typename chunked_fifo<T, items_per_chunk>::const_iterator
-chunked_fifo<T, items_per_chunk>::begin() const {
+chunked_fifo<T, items_per_chunk>::begin() const noexcept {
return const_iterator(_front_chunk);
}
template <typename T, size_t items_per_chunk>
inline typename chunked_fifo<T, items_per_chunk>::const_iterator
-chunked_fifo<T, items_per_chunk>::end() const {
+chunked_fifo<T, items_per_chunk>::end() const noexcept {
return const_iterator(nullptr);
}
template <typename T, size_t items_per_chunk>
inline typename chunked_fifo<T, items_per_chunk>::const_iterator
-chunked_fifo<T, items_per_chunk>::cbegin() const {
+chunked_fifo<T, items_per_chunk>::cbegin() const noexcept {
return const_iterator(_front_chunk);
}
template <typename T, size_t items_per_chunk>
inline typename chunked_fifo<T, items_per_chunk>::const_iterator
-chunked_fifo<T, items_per_chunk>::cend() const {
+chunked_fifo<T, items_per_chunk>::cend() const noexcept {
return const_iterator(nullptr);
}