Open divinity76 opened 5 years ago
// 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; };