Skip to content

Commit

Permalink
buffer.h c++17 improvements
Browse files Browse the repository at this point in the history
1) ensure data is properly aligned
2) add move constructor (useful for zstrings)
  • Loading branch information
nunoplopes committed May 23, 2021
1 parent 34e8a2f commit 79201e5
Showing 1 changed file with 25 additions and 22 deletions.
47 changes: 25 additions & 22 deletions src/util/buffer.h
Expand Up @@ -27,19 +27,19 @@ Revision History:
template<typename T, bool CallDestructors=true, unsigned INITIAL_SIZE=16>
class buffer {
protected:
T * m_buffer;
unsigned m_pos;
unsigned m_capacity;
char m_initial_buffer[INITIAL_SIZE * sizeof(T)];
T * m_buffer = reinterpret_cast<T*>(m_initial_buffer);
unsigned m_pos = 0;
unsigned m_capacity = INITIAL_SIZE;
typename std::aligned_storage<sizeof(T), alignof(T)>::type m_initial_buffer[INITIAL_SIZE];

void free_memory() {
if (m_buffer != reinterpret_cast<T*>(m_initial_buffer)) {
dealloc_svect(m_buffer);
}
}

void expand() {
static_assert(std::is_nothrow_move_constructible<T>::value, "");
static_assert(std::is_nothrow_move_constructible<T>::value);
unsigned new_capacity = m_capacity << 1;
T * new_buffer = reinterpret_cast<T*>(memory::allocate(sizeof(T) * new_capacity));
for (unsigned i = 0; i < m_pos; ++i) {
Expand Down Expand Up @@ -73,26 +73,29 @@ class buffer {
typedef T * iterator;
typedef const T * const_iterator;

buffer():
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
m_pos(0),
m_capacity(INITIAL_SIZE) {
}
buffer() = default;

buffer(const buffer & source):
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
m_pos(0),
m_capacity(INITIAL_SIZE) {
unsigned sz = source.size();
for(unsigned i = 0; i < sz; i++) {
buffer(const buffer & source) {
for (unsigned i = 0, sz = source.size(); i < sz; ++i) {
push_back(source.m_buffer[i]);
}
}

buffer(unsigned sz, const T & elem):
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
m_pos(0),
m_capacity(INITIAL_SIZE) {

buffer(buffer && source) {
if (source.m_buffer == reinterpret_cast<T*>(source.m_initial_buffer)) {
for (unsigned i = 0, sz = source.size(); i < sz; ++i) {
push_back(std::move(source.m_buffer[i]));
}
} else {
m_pos = source.m_pos;
m_capacity = source.m_capacity;
m_buffer = source.m_buffer;
source.m_buffer = reinterpret_cast<T*>(source.m_initial_buffer);
source.m_pos = 0;
}
}

buffer(unsigned sz, const T & elem) {
for (unsigned i = 0; i < sz; i++) {
push_back(elem);
}
Expand Down

0 comments on commit 79201e5

Please sign in to comment.