This is untested and evil, so only use it if you have to ;-)
My C is also very rusty, so this may not compile in vanilla C; it should be easy to adapt from the C++ conventions though.
struct MemberInfo
{
void* array;
unsigned size;
};
void AOStoSOA(void* arraybegin, unsigned arraycount, unsigned arraystride, MemberInfo outarrays[], unsigned nummembers)
{
char* arrayptr = (char*)(arraybegin);
for(unsigned i = 0; i < arraycount; ++i)
{
unsigned offset = 0;
for(unsigned j = 0; j < nummembers; ++j)
{
memcpy(&outarrays[j].array, arrayptr + offset, outarrays[j].size);
offset += outarrays[j].size;
}
arrayptr += arraystride;
}
}
// PACKING IS MANDATORY HERE
#pragma pack(push)
#pragma pack(1)
struct Foo
{
int Test;
char Blah;
};
#pragma pack(pop)
struct SOAForm
{
int* TestArray;
char* BlahArray;
};
#define COUNT 10
void SomeFunction()
{
Foo aos[COUNT];
SOAForm soa;
soa.TestArray = malloc(sizeof(int) * COUNT);
soa.BlahArray = malloc(sizeof(char) * COUNT);
MemberInfo arrays[] =
{
{ soa.TestArray, sizeof(int) },
{ soa.BlahArray, sizeof(char) }
};
AOStoSOA(&aos[0], COUNT, (char*)(&aos[1]) - (char*)(&aos[0]), arrays, 2);
printf("Third Blah is '%c'\n", soa.BlahArray[2]);
free(soa.TestArray);
free(soa.BlahArray);
}
You could automatically generate most of this code using macros, as I alluded to above. If you're interested in that route, I might have time to hack something up later this afternoon.
Holy shit, you are the man.
This is pretty much exactly what I was going for, you took the freakin' code right out of my mind!
Just out of curiosity however, you use the following to get the stride:
(char*)(&aos[1]) - (char*)(&aos[0])
Why not just do sizeof(Foo), it's not likely there is padding within the array, right?
Additionally, if you'd like to do the macro code it'd be mostly academic, but for people who might need something like this, it would be a good reference post.
I think this would be good enough for me though, I don't even know how to convey how grateful I am. Just doing some prelim tests, I am convinced your solution works (if there are any nit picky bugs I could figure them out from here).
I "liked" your posts, but I am not sure how the reputation granting works anymore, is this what reputation has become here?
Thanks a million more times.
AfroFire | Brin"The only thing that interferes with my learning is my education."-Albert Einstein