I've recently finished implementing a ring queue based on std::array
in C++11. I tried to write the code as if I were going to submit it to the C++ Standard committee to have a RingQueue
as part of the standard while keeping the implementation as simple and fast as possible. Please let me know if there are any changes I should make or any bugs you spot. I've tested the ring queue pretty well and I couldn't find anything outstandingly buggy/wrong about it.
#ifndef __RING_QUEUE_H__
#define __RING_QUEUE_H__
#include <array>
template <class T, size_t N>
class RingQueue {
public:
typedef T value_type;
typedef const T const_value_type;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef std::array<T, N> Container;
typedef typename Container::iterator iterator;
typedef typename Container::const_iterator const_iterator;
typedef typename Container::reverse_iterator reverse_iterator;
typedef typename Container::const_reverse_iterator const_reverse_iterator;
RingQueue(): p(0) {}
~RingQueue(){}
RingQueue(const RingQueue&) = default;
RingQueue& operator=(const RingQueue&) = default;
inline reference operator[](size_t i) { return arr[i]; }
inline const_reference operator[](size_t i) const { return arr[i]; }
inline reference at(size_t i) { return arr.at(i); }
inline const_reference at(size_t i) const { return arr.at(i); }
inline reference front() { return arr.front(); }
inline const_reference front() const { return arr.front(); }
inline reference back() { return arr.back(); }
inline const_reference back() const { return arr.back(); }
inline value_type* data () { return arr.data(); }
inline const value_type* data() const { return arr.data(); }
inline bool empty() const { return arr.empty(); }
inline void fill(const value_type& val) { arr.fill(val); }
inline void enqueue(const value_type& i) { p %= arr.size(); arr[p] = i; ++p; }
void dequeue()
{
if (empty()) return;
for (auto i = arr.begin() + 1; i != arr.end(); ++i){ *(i - 1) = *i; }
--p;
}
inline size_type size() const { return arr.size(); }
inline size_type max_size() const { return arr.max_size(); }
inline void swap(RingQueue<T, N>& x) { arr.swap(x.arr); }
inline friend bool operator<(const RingQueue<T, N>& a, const RingQueue<T, N>& b) { return a.arr < b.arr; }
inline friend bool operator==(const RingQueue<T, N>& a, const RingQueue<T, N>& b) { return a.arr == b.arr; }
inline friend bool operator!=(const RingQueue<T, N>& a, const RingQueue<T, N>& b) { return a.arr != b.arr; }
inline friend bool operator<=(const RingQueue<T, N>& a, const RingQueue<T, N>& b) { return a.arr <= b.arr; }
inline friend bool operator>(const RingQueue<T, N>& a, const RingQueue<T, N>& b) { return a.arr > b.arr; }
inline friend bool operator>=(const RingQueue<T, N>& a, const RingQueue<T, N>& b) { return a.arr >= b.arr; }
inline iterator begin() { return arr.begin(); }
inline const_iterator begin() const { return arr.begin(); }
inline const_iterator cbegin() const { return arr.cbegin(); }
inline reverse_iterator rbegin() { return arr.rbegin(); }
inline const_reverse_iterator rbegin() const { return arr.rbegin(); }
inline const_iterator crbegin() const { return arr.crbegin(); }
inline iterator end() { return arr.end(); }
inline const_iterator end() const { return arr.end(); }
inline const_iterator cend() const { return arr.cend(); }
inline reverse_iterator rend() { return arr.rend(); }
inline const_reverse_iterator rend() const { return arr.rend(); }
inline const_iterator crend() const { return arr.crend(); }
private:
Container arr;
size_t p;
};
#endif