Skip to content

Instantly share code, notes, and snippets.

@croepha
Created March 16, 2018 02:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save croepha/08478bd1041b9f9c67d7d59702ff58f9 to your computer and use it in GitHub Desktop.
Save croepha/08478bd1041b9f9c67d7d59702ff58f9 to your computer and use it in GitHub Desktop.
cpp_template_stretchy_buffers
template<typename T> struct buf_Meta {
size_t len;
size_t cap;
T buf[0];
};
template <typename T> inline buf_Meta<T>& buf__meta(T*b) {
return *(buf_Meta<T>*)((size_t)(b) - __builtin_offsetof(buf_Meta<T>, buf));
}
template <typename T> inline void buf_push(T*&b, T v) {
if (!b) {
b = (T*)((u8*)malloc(sizeof(T) + sizeof(buf_Meta<T>)) + sizeof(buf_Meta<T>)) ;
buf__meta(b).len = 0;
buf__meta(b).cap = 1;
}
buf__meta(b).len++;
if (buf__meta(b).len > buf__meta(b).cap) {
buf__meta(b).cap = buf__meta(b).len;
void* base = &buf__meta(b);
base = realloc(base, buf__meta(b).cap * sizeof(T) + sizeof(buf_Meta<T>)) ;
assert(base);
b = (T*)((size_t)base + sizeof(buf_Meta<T>));
}
b[buf__meta(b).len-1] = v;
}
template <typename T> inline size_t buf_len(T*b) {
return buf__meta(b).len;
}
template<typename T> struct DynamicArray {
size_t len = 0;
size_t cap = 0;
T *buf = 0;
void cap_set(size_t new_cap) {
system_alloc(buf, new_cap);
cap = new_cap;
}
auto& append() {
len++;
if (len > cap) cap_set(MAX(len, cap *2));
return buf[len-1];
}
auto& append (T v ) { return append() = v; }
auto& operator[](size_t i) { assert(i<len); return buf[i]; }
~DynamicArray ( ) { cap_set(0); }
auto begin ( ) { return buf; }
auto end ( ) { return buf + len; }
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment