Sometimes we prefer to use circular buffer: “like CircularBuffer, but NOT use size and next index, but use front and rear”, so an impletametation here.
See also
– Write a CircularBuffer
– std::queue
– Full impletametation: circularqueue.hpp
/**
* Var capacity circular queue.
* NOTE:
* - Like CircularBuffer, but if full, enque(push) will FAIL!
* - And like CircularBuffer, but NOT use size and next index, but use front
* and rear.
* - When use in multi-threads, should add lock or some other to sync.
* @tparam T data type.
* @sa CircularBuffer
* @todo
* - Add full CircularBuffer like features.
* - Add iterators.
*/
template<typename T>
class CircularQueue {
public:
/**
* Ctor.
* @param capacity the buffer capacity, should >= 1.
* @throw std::logic_error when capacity invalid.
*/
CircularQueue(int32_t capacity = 1, const T& initValue = T{});
/**
* Test whether container is empty
* @return True if queue is empty, false otherwise.
*/
inline bool empty() const noexcept;
/**
* Test whether container is empty
* @return True if queue if full, false otherwise.
*/
inline bool full() const noexcept;
/// @return data size.
inline int32_t size() const noexcept;
/// @return queue capacity.
inline int32_t capacity() const noexcept;
/**
* Inserts a new element at the end of the queue, after its current last
* element. The content of this new element is initialized to value.
* @param value Value to which the inserted element is initialized.
* Member type value_type is the type of the elements in the container
* (defined as an alias of the first class template parameter, T).
*/
bool push(const T& value) noexcept;
bool push(T&& value) noexcept;
bool pop() noexcept;
bool pop(T& value) noexcept;
/// @throw std::logic_error when queue empty.
T pop_front();
/**
* Get queue head(front) when not empty.
* @return queue head(front) when not empty.
* @throw std::logic_error when empty.
*/
const T& front() const;
T& front();
private:
/// Pop index(current or next readable), init as empty.
int32_t currRFront{ -1 };
int32_t lastWRear{ -1 };///< Push index(last writeable), init as empty
int32_t capa{ 1 };///< The buffer capacity, > 0.
std::vector<T> buffer;///< The internal buffer.
};