uint8_fast_buffer
Opened this issue · 0 comments
divinity76 commented
// buffer which should be faster than std::vector<uint8_t> when resizing a lot because it does not do byte initialization when resizing
class uint8_fast_buffer
{
public:
uint8_fast_buffer(const size_t initial_size)
{
// .. i don't really like the idea of buf being nullptr, this avoids that issue.
this->internal_reserve(std::max(initial_size,(decltype(initial_size))1));
this->buf_size=initial_size;
}
~uint8_fast_buffer() noexcept
{
free(this->buf);
}
size_t size(void) noexcept
{
return this->buf_size;
}
void reserve(const size_t reserve_size)
{
if(reserve_size > this->buf_cap)
{
this->internal_reserve(reserve_size);
}
}
// this function is supposed to be very fast when newlen is smaller than the biggest it has ever been before.
void resize(const size_t newlen)
{
if(__builtin_expect(newlen > this->buf_cap,0))
{
this->internal_reserve(newlen);
}
this->buf_size=newlen;
}
void append(const uint8_t *data, const size_t len)
{
const size_t pos=this->size();
const size_t new_pos=this->size()+len;
this->resize(new_pos);
memcpy(&this->buf[pos],data,len);
}
void reset(void) noexcept
{
this->buf_size=0;
}
bool empty(void) noexcept
{
return (this->buf_size==0);
}
uint8_t* data(void) noexcept
{
return this->buf;
}
uint8_t& at(const size_t pos)
{
if(__builtin_expect(pos >= this->size(),0))
{
throw std::out_of_range(std::to_string(pos)+std::string(" >= ")+std::to_string(this->size()));
}
return this->buf[pos];
}
uint8_t& operator[](const size_t pos) noexcept
{
return this->buf[pos];
}
private:
void internal_reserve(const size_t reserve_size)
{
uint8_t *newbuf=(uint8_t*)realloc(this->buf,reserve_size);
if(__builtin_expect(newbuf == nullptr,0))
{
throw std::bad_alloc();
}
this->buf_cap=reserve_size;
this->buf=newbuf;
}
size_t buf_size=0;
size_t buf_cap=0;
uint8_t *buf=nullptr;
};