Created
January 7, 2022 19:16
-
-
Save yatharthb97/2211c7898382eb4f9ae819b8f490311b to your computer and use it in GitHub Desktop.
Implementation of simple Circular Buffer with bounded index random accessor.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <sstream> | |
/* CIRCULAR BUFFER | |
Implementation of simple Circular Buffer with bounded index random accessor. | |
--- | |
Author : Yatharth Bhasin | |
Licence : MIT Licence (Text → https://opensource.org/licenses/MIT) | |
--- | |
*/ | |
/** @brief Implementation of simple Circular Buffer with bounded index random accessor. */ | |
template <typename Type, unsigned int MaxSize> | |
class CircularBuffer | |
{ | |
public: | |
unsigned int head = 0; //! Index / Pointer of the first element of the buffer | |
unsigned int tail = 0; //! Index / Pointer to the last element of the buffer | |
bool is_full_flag = false; //! Flag indicates whether the buffer is running at full capacity | |
/** @brief Adjusts the pointer after addition or push_back() operation. */ | |
void advance_pointer() __attribute__((always_inline)) | |
{ | |
if(is_full_flag) | |
{ | |
if (++tail == MaxSize) | |
{ tail = 0; } | |
} | |
if (++head == MaxSize) | |
{ head = 0; } | |
is_full_flag = (head == tail); | |
} | |
/** @brief Adjusts the pointers after a removal or pop_back() operation. */ | |
void retreat_pointer() __attribute__((always_inline)) | |
{ | |
is_full_flag = false; | |
if (++tail == MaxSize) | |
{ tail = 0; } | |
} | |
public: | |
Type buffer[MaxSize] = {0}; //! Fixed Size Buffer | |
/** @brief Resets the buffer (pointers) without clearing the elements. */ | |
void reset() __attribute__((always_inline)) | |
{ | |
head = 0; | |
tail = 0; | |
is_full_flag = false; | |
} | |
/** @brief Returns whether the buffer is full. */ | |
bool is_full() const __attribute__((always_inline)) | |
{ | |
return is_full_flag; | |
} | |
/** @brief Returns whether the buffer is empty. \note{!is_full() != is_empty()}*/ | |
bool is_empty() const __attribute__((always_inline)) | |
{ | |
return ( head==tail && !is_full_flag ); | |
} | |
/** @brief Returns the maximum capacity of the buffer. */ | |
size_t capacity() const __attribute__((always_inline)) | |
{ | |
return MaxSize; | |
} | |
/** @brief Returns the current size of the buffer. */ | |
size_t size() const __attribute__((always_inline)) | |
{ | |
if(is_full_flag) | |
{ return MaxSize; } | |
else if (head >= tail) | |
{ return (head - tail); } | |
else | |
{ return MaxSize + (head - tail); } | |
} | |
/** @brief Adds a datum to the circular buffer. */ | |
void push_back(const Type data) __attribute__((flatten)) | |
{ | |
this->buffer[head] = data; | |
this->advance_pointer(); | |
} | |
/** @brief Returns the last element from the buffer and deletes it - pop operation. */ | |
Type pop_back() __attribute__((always_inline)) | |
{ | |
if(!is_empty()) | |
{ | |
Type temp = buffer[tail]; | |
retreat_pointer(); | |
return temp; | |
} | |
else | |
return Type(); | |
} | |
/** @brief Random access operator can be used to retrive the nth element in the buffer at any state of the buffer. */ | |
Type operator[] (const size_t index) const __attribute__((always_inline)) | |
{ | |
//assert(index < MaxSize); | |
size_t Remaining = MaxSize - head; //Indices servicible by adding to head pointer. | |
return (Remaining > index) * buffer[head + index] + | |
!(Remaining > index) * (buffer[index - Remaining]); | |
} | |
template <typename Type_, unsigned int MaxSize_> | |
friend std::ostream& operator<< (std::ostream &stream, const CircularBuffer<Type_, MaxSize_> &cbuffer); | |
}; | |
/** @brief Defines a stream operator for the CircularBuffer. */ | |
template <typename Type, unsigned int MaxSize> | |
std::ostream& operator<< (std::ostream &stream, const CircularBuffer<Type, MaxSize> &cbuffer) | |
{ | |
for(unsigned int i = 0; i < cbuffer.size(); i++) | |
{ | |
stream << cbuffer.buffer[i] << ' '; | |
} | |
return stream; | |
} //End of friend overload operator<< |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment