Skip to content

Instantly share code, notes, and snippets.

@jstimpfle
Created January 8, 2019 21:02
Show Gist options
  • Select an option

  • Save jstimpfle/2146f84c9620616502e818a25bcc84a2 to your computer and use it in GitHub Desktop.

Select an option

Save jstimpfle/2146f84c9620616502e818a25bcc84a2 to your computer and use it in GitHub Desktop.
SOA experiments
/*
Dynamic array with an independently allocated count.
This is nice for relational and SOA (structure of arrays) programming.
We can share a count value across multiple dynamic arrays.
This is how it should be! (Except, it's still abstract, and quite a bit of boilerplate)
*/
#include <cassert>
#include <cstdio>
#include <cstdlib>
template<typename Idx, typename T, size_t& X>
class Vec {
size_t size;
T *buf;
public:
Vec() {
buf = nullptr;
size = 0;
}
void allocate() {
T *newbuf = (T *) realloc(buf, X * sizeof (T));
if (newbuf == NULL) {
fprintf(stderr, "OOM!\n");
abort();
}
buf = newbuf;
size = X;
}
void deallocate() {
if (buf != NULL) {
free(buf);
buf = NULL;
size = NULL;
}
}
T& operator[](const Idx& idx) {
assert(size == X);
assert(idx.get_id() < X);
return buf[idx.get_id()];
};
};
struct Person {
size_t id;
size_t get_id() const { return id; }
};
struct Dog {
size_t id;
size_t get_id() const { return id; }
};
// count is used as template argument, so must have static storage duration
size_t personCnt = 0;
size_t dogCnt = 0;
int main(void)
{
Vec<Person, char *, personCnt> personName;
Vec<Person, int, personCnt> personAge;
Person p { personCnt++ };
Dog d { dogCnt++ };
personName.allocate();
personAge.allocate();
// should not compile
//personName[d] = "Snoopy";
personName[p] = "John Doe";
personAge[p] = 31;
printf("%s is %d years old\n", personName[p], personAge[p]);
fflush(stdout);
personName.deallocate();
personAge.deallocate();
// should crash
personName[p];
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment