#ifndef __RING_BUFFER_H__
#define __RING_BUFFER_H__

#include "types.h"


// N must be a power of 2

template <typename T, sig_atomic_t N>
class RingBuffer
{
	public:
		RingBuffer(void) : _head(0), _tail(0) {}

		bool Empty(void) const {
			return _head == _tail;
		}

		bool Full(void) {
			return (((_tail + 1) & _size)  == _size);
		}

		T Front(void) {
			return _buffer[_head];
		}

		void Pop(void) {
			if (++_head >= _size) {
				_head = 0;
			}
		}

		void Push(T element) {
			sig_atomic_t new_tail = _tail;
			if (++new_tail >= _size)
				new_tail = 0;
			if (new_tail != _head){
				_buffer[_tail] = element;
				_tail = new_tail;
			}
		}

	private:
		enum 			{ _size = N };
		T				_buffer[_size];
		sig_atomic_t	_head;
		sig_atomic_t	_tail;
};

#endif // __RING_BUFFER_H__
