diff --git a/src/circularbuffer.hpp b/src/circularbuffer.hpp
new file mode 100644
index 0000000..b808b37
--- /dev/null
+++ b/src/circularbuffer.hpp
@@ -0,0 +1,63 @@
+/*
+ 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 .
+
+*/
+
+#ifndef idF67A018826604CAFBE25BCA939A1FBC9
+#define idF67A018826604CAFBE25BCA939A1FBC9
+
+#include
+#include
+#include
+#include
+
+namespace cloonel {
+ template
+ class CircularBuffer : public boost::noncopyable {
+ public:
+ typedef size_t size_type;
+ typedef typename std::iterator_traits::value_type value_type;
+ typedef typename std::iterator_traits::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
diff --git a/src/circularbuffer.inl b/src/circularbuffer.inl
new file mode 100644
index 0000000..c03c262
--- /dev/null
+++ b/src/circularbuffer.inl
@@ -0,0 +1,68 @@
+namespace cloonel {
+ template
+ CircularBuffer::CircularBuffer (Iterator parFirst, Iterator parLast) :
+ m_start(parFirst),
+ m_end(parLast),
+ m_curr(parFirst),
+ m_used(0)
+ {
+ }
+
+ template
+ void CircularBuffer::push (value_type&& parObj) {
+ *m_curr = std::move(parObj);
+ ++m_curr;
+ ++m_used;
+ if (m_curr == m_end) {
+ m_curr = m_start;
+ m_used = capacity();
+ }
+ }
+
+ template
+ void CircularBuffer::reset() {
+ m_used = 0;
+ m_curr = m_start;
+ }
+
+ template
+ void CircularBuffer::reset (Iterator parFirst, Iterator parLast) {
+ m_start = parFirst;
+ m_end = parLast;
+ reset();
+ }
+
+ template
+ typename CircularBuffer::reference CircularBuffer::front() {
+ if (empty())
+ throw std::out_of_range("The circular buffer is empty, but front() was called.");
+ if (m_curr == m_start)
+ return *(m_start + (capacity() - 1));
+ else
+ return *(m_curr - 1);
+ }
+
+ template
+ typename CircularBuffer::reference CircularBuffer::back() {
+ if (empty())
+ throw std::out_of_range("The circular buffer is empty, but back() was called.");
+ const auto cap = capacity();
+ if (m_used != cap) {
+ return *m_start;
+ }
+ else {
+ const auto currPos = m_curr - m_start;
+ const auto index = (currPos + cap - 1) % cap;
+ return *(m_start + index);
+ }
+ }
+
+ template
+ typename CircularBuffer::reference CircularBuffer::operator[] (size_type parIndex) {
+ if (parIndex < 0 or parIndex >= size())
+ throw std::out_of_range("Index out of range in CircularBuffer");
+
+ const auto index = (m_curr - m_start + parIndex) % capacity();
+ return *(m_start + index);
+ }
+} //namespace cloonel