1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
#pragma once
#include <cstring>
#include <mutex>
/*
Simple resizeable buffer.
This was made for usecases where manual management is fine,
and std::vector too slow... Such as all the image processing.
The aim is not to automate memory management, but rather to be a
wrapper around reszing, without any performance impact compared
to a native array.
Operator overloading is utilized not to complexify things. This
should still be usable like a normal array.
*/
template <typename T>
class ResizeableBuffer
{
private:
size_t d_size;
size_t d_width;
size_t d_headroom;
public:
std::mutex buffer_lock;
T *buf;
bool destroyed = true;
public:
ResizeableBuffer() { d_size = 0; }
~ResizeableBuffer() { destroy(); }
void destroy()
{
if (!destroyed)
delete[] buf;
destroyed = true;
}
size_t size() { return d_size; }
T &operator[](int i)
{
// check(i / d_width);
return buf[i];
}
void create(size_t width, size_t headroom = 1000)
{
d_width = width;
d_headroom = headroom;
d_size = d_width * d_headroom;
buf = new T[d_size];
destroyed = false;
}
void resize(size_t newSize)
{
buffer_lock.lock();
if (newSize > d_size)
{
T *newBuffer = new T[newSize];
std::memcpy(newBuffer, buf, d_size * sizeof(T));
delete[] buf;
buf = newBuffer;
d_size = newSize;
}
buffer_lock.unlock();
}
void check(size_t lines)
{
if (lines * d_width >= d_size) // Check for 1 extra!
resize(d_width * (lines + d_headroom));
}
};
|