/*
	Copyright 2014 Michele "King_DuckZ" Santullo

	This file is part of CloonelJump.

	CloonelJump is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	CloonelJump is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with CloonelJump.  If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef idF67A018826604CAFBE25BCA939A1FBC9
#define idF67A018826604CAFBE25BCA939A1FBC9

#include <boost/noncopyable.hpp>
#include <iterator>
#include <stdexcept>
#include <ciso646>

namespace cloonel {
	template <typename Iterator>
	class CircularBuffer : public boost::noncopyable {
	public:
		typedef size_t size_type;
		typedef typename std::iterator_traits<Iterator>::value_type value_type;
		typedef typename std::iterator_traits<Iterator>::reference reference;

		CircularBuffer ( Iterator parFirst, Iterator parLast );
		CircularBuffer ( CircularBuffer&& parOther );
		~CircularBuffer ( void ) noexcept = default;
		CircularBuffer& operator= ( CircularBuffer&& parOther );

		reference operator[] ( size_type parIndex );

		size_type size ( void ) const { return (m_used >= capacity() ? capacity() : m_used); }
		bool empty ( void ) const { return 0 == m_used; }
		size_type capacity ( void ) const { return m_end - m_start; }
		void push ( value_type&& parObj );
		void reset ( void );
		void reset ( Iterator parFirst, Iterator parLast );
		reference front ( void );
		reference back ( void );

	private:
		Iterator m_start;
		Iterator m_end;
		Iterator m_curr;
		size_type m_used;
	};
} //namespace cloonel

#include "circularbuffer.inl"

#endif
