diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d06ccde --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +CXX := g++ +CXX_FLAGS := -Wall -Wextra -std=c++17 -ggdb + +BIN := bin +SRC := src +INCLUDE := include +LIB := lib + +LIBRARIES := +EXECUTABLE := main + + +all: $(BIN)/$(EXECUTABLE) + +run: clean all + clear + ./$(BIN)/$(EXECUTABLE) + +$(BIN)/$(EXECUTABLE): $(SRC)/*.cpp + $(CXX) $(CXX_FLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $@ $(LIBRARIES) + +clean: + -rm $(BIN)/* diff --git a/build.txt b/build.txt new file mode 100644 index 0000000..bc37798 --- /dev/null +++ b/build.txt @@ -0,0 +1,14 @@ +Written using VS Code with Ubuntu WSL on Windows 10. + +In VS Code used Easy C/C++ project for creating the initial C++ project +structure. This creates common C++ structure which is compiled using g++ +(g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0), with bin stored to bin directory. +Easy C/C++ project creates Makefile which can be used on every + +Making of project: +- g++ installed (with support for C++17) +- make installed (GNU Make 4.1 version on my side) +- navigate to the project directory via command line (e.g. using Ubuntu WSL on Windows) +- run make +- binary files stored in bin/ +- run program bin/make \ No newline at end of file diff --git a/include/buffer.h b/include/buffer.h new file mode 100644 index 0000000..89e0c28 --- /dev/null +++ b/include/buffer.h @@ -0,0 +1,52 @@ +#ifndef __BUFFER_H__ +#define __BUFFER_H__ + +#define ARRAY_MAX_SIZE 256 + +#include +#include +#include +#include + +/** + * Class containing Circular buffer implementation + * - fixed array, with max size predefined. + * - user can select the size of an array, but not bigger than predefined max + * size + * - storage policy can be chosen in run-time + * - storage size cannot less than 1 + * - predefined storage type to uint8_t (be aware of type limitations) + * improvements: + * -> support more types + * -> add multiple policies for item manipulation (push_front, pop_front, etc.) + * -> add more policies for buffer + * -> overload operators for operations with two buffers + * -> add more functions for buffer usage + */ +class Buffer +{ + using storageType = std::array; + + size_t storageSize{0}; // size of storage + size_t head{0}; // pointer to head of ring buffer + size_t tail{0}; // pointer to tail of ring buffer + size_t itemsNum{0}; // number of elements inside + + storageType storage; // storage for buffer + + uint8_t storagePolicy{0}; // policy for discard or overwrite data + + public: + Buffer(int); // constructor creating storage of fixed size + + ~Buffer(); // destroying the storage + + void pushBack(int); // push item to back of buffer (after tail pointer) + uint8_t popBack(); // pop item from back (tail pointer) + + void readBuffer(); + + void setPolicy(uint8_t); //setting policy for buffer (0 - overwrite, 1 - discard) +}; + +#endif \ No newline at end of file diff --git a/src/buffer.cpp b/src/buffer.cpp new file mode 100644 index 0000000..f5484b0 --- /dev/null +++ b/src/buffer.cpp @@ -0,0 +1,97 @@ +#include "buffer.h" + +/** + * Since the std::array is created on compile time, here only setting of + * limitations for array is done + */ +Buffer::Buffer(int size) : storageSize(size) +{ + assert((storageSize > 1 && "size must be greater than 1") && (storageSize < ARRAY_MAX_SIZE && "size must be less then ARRAY_MAX_SIZE")); +} + +/** + * Add item to the back of the ring buffer + */ +void Buffer::pushBack(int item) +{ + if(static_cast(0) == itemsNum) + { + /** + * No items in ring buffer, h = t = 0; + */ + storage.at(tail) = static_cast(item); + ++itemsNum; + } + else + { + /** + * There is already items in array, it != 0; + */ + if(itemsNum < storageSize) + { + /** + * But it is not full; + */ + ++tail; + storage.at(tail) = static_cast(item); + ++itemsNum; + } + else if (static_cast(0) == storagePolicy) + { + /** + * It is full; + */ + std::cout<<"Full"; + tail = (tail == static_cast(storageSize-1)) ? static_cast(0) : (tail+1); + head = (head == static_cast(storageSize-1)) ? static_cast(0) : (head+1); + storage.at(tail) = static_cast(item); + } + else + { + std::cout << "Discarded items"; + } + + } +} + +/** + * Return last item in the buffer + */ +uint8_t Buffer::popBack() +{ + uint8_t temp{storage[tail]}; + + tail = (tail == static_cast(0)) ? static_cast(storageSize-1) : (tail-1); + --itemsNum; + + head = (itemsNum == static_cast(0)) ? 0 : head; + tail = (itemsNum == static_cast(0)) ? 0 : tail; + + return temp; +} + +/** + * Print out whole buffer + */ +void Buffer::readBuffer() +{ + for(uint8_t it = 0; it < itemsNum; it++) + { + std::cout << static_cast(storage.at(it)) << ", "; + } + std::cout << std::endl; +} + +/** + * Set policy for adding items in buffer + * 0 - overwrite, 1 - discard + */ +void Buffer::setPolicy(uint8_t pol) +{ + storagePolicy = pol; +} + +Buffer::~Buffer() +{ + std::cout << "In desctructor" << std::endl; +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..0e46716 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,41 @@ +#include +#include "buffer.h" + +#define BUFFER_SIZE_1 10 + +#define BUFFER_TEST_1 30 + +int main() +{ + Buffer buff = Buffer(BUFFER_SIZE_1); + + for(int it = 0; it < BUFFER_TEST_1; it++) + { + buff.pushBack(it); + buff.readBuffer(); + } + + for(int it = 0; it < BUFFER_SIZE_1; it++) + { + int temp = static_cast(buff.popBack()); + buff.readBuffer(); + } + + std::cout << "Different policy for ring buffer!" << std::endl; + + buff.setPolicy(static_cast(1)); + + for(int it = 0; it < BUFFER_TEST_1; it++) + { + buff.pushBack(it); + buff.readBuffer(); + } + + for(int it = 0; it < BUFFER_SIZE_1; it++) + { + int temp = static_cast(buff.popBack()); + buff.readBuffer(); + } + + std::cout << "Hello Easy C++ project! " << std::endl; +} \ No newline at end of file