Witam!
Chciałbym by ktoś z bardziej doświadczonych kolegów zrobił mi review mojego kodu. Jest to implementacja bufora cyklicznego, który ma mi posłużyć do zbierania logów.
#ifndef ROUNDBUFFER_H
#define ROUNDBUFFER_H
#include <iostream>
template <typename T>
class RoundBuffer
{
public:
RoundBuffer() = delete;
explicit RoundBuffer(std::size_t size);
RoundBuffer(const RoundBuffer<T>& rhs);
RoundBuffer& operator=(RoundBuffer<T> copy);
RoundBuffer& operator=(RoundBuffer<T>&& copy);
RoundBuffer(RoundBuffer<T> && rhs);
~RoundBuffer();
T const& operator[](std::size_t index) const;
void pushObject(const T& object);
void resize(std::size_t newSize);
std::size_t getSize() const;
template <typename Y>
friend void swap(RoundBuffer<Y>& lhs, RoundBuffer<Y>& rhs) noexcept;
template <typename Y>
friend std::ostream& operator<<(std::ostream& stream, const RoundBuffer<Y>& object);
private:
std::size_t index;
std::size_t size;
T* buffer;
void writeToBuffer(std::size_t& index, std::size_t& size, T* buffer, const T& data);
};
template <typename T>
RoundBuffer<T>::RoundBuffer(std::size_t size) : index(0), size(size), buffer(size ? new T[size] : nullptr) {}
template <typename T>
RoundBuffer<T>::RoundBuffer(const RoundBuffer<T> &rhs) : index(rhs.index), size(rhs.size), buffer(size ? new T[size] : nullptr)
{
std::copy(rhs.buffer, rhs.buffer + size, buffer);
}
template <typename T>
RoundBuffer<T>& RoundBuffer<T>::operator =(RoundBuffer<T> copy)
{
swap(*this, copy);
return *this;
}
template <typename T>
RoundBuffer<T>& RoundBuffer<T>::operator =(RoundBuffer<T>&& copy)
{
swap(*this, copy);
return *this;
}
template <typename T>
RoundBuffer<T>::RoundBuffer(RoundBuffer<T> && rhs)
{
swap(*this,rhs);
rhs.buffer = nullptr;
}
template <typename T>
RoundBuffer<T>::~RoundBuffer()
{
if(buffer) delete[] buffer;
}
template <typename T>
T const& RoundBuffer<T>::operator [](std::size_t index) const
{
if(index > this->index)
{
throw std::out_of_range("Index is out of possible range");
}
else
{
return buffer[index];
}
}
template <typename T>
std::size_t RoundBuffer<T>::getSize() const
{
return size;
}
template <typename T>
void RoundBuffer<T>::writeToBuffer(std::size_t& index, std::size_t& size, T *buffer, const T& data)
{
if (index != size)
{
buffer[index] = data;
index++;
}
else
{
index = 0;
buffer[index] = data;
index++;
}
}
template <typename T>
void RoundBuffer<T>::pushObject(const T &object)
{
writeToBuffer(index, size, buffer, object);
}
template <typename T>
void RoundBuffer<T>::resize(std::size_t newSize)
{
if(newSize == size) return;
T* newBuffer = newSize ? new T[newSize] : nullptr;
std::copy(buffer,buffer+size,newBuffer);
T* oldBuffer = this->buffer;
this->buffer = newBuffer;
this->size = newSize;
delete[] oldBuffer;
}
template <typename T>
std::ostream& operator<<(std::ostream& stream, const RoundBuffer<T>& object)
{
{
for (std::size_t i = 0; i < object.size; ++i)
{
stream << "buff[" << i << "] = " << object.buffer[i] << std::endl;
}
return stream;
}
}
template <typename T>
void swap(RoundBuffer<T>& lhs, RoundBuffer<T>& rhs) noexcept
{
using std::swap; //enable ADL
swap(lhs.buffer, rhs.buffer);
swap(lhs.index, rhs.index);
swap(lhs.size, rhs.size);
}
#endif // ROUNDBUFFER_H