Skip to content

Instantly share code, notes, and snippets.

@JPGygax68
Last active September 18, 2017 19:22
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 JPGygax68/21eab3a29c8dd4bc5cff to your computer and use it in GitHub Desktop.
Save JPGygax68/21eab3a29c8dd4bc5cff to your computer and use it in GitHub Desktop.
Proof-of-concept for something similar to #tuple, but based on struct #composition instead of struct inheritance.
#include <iostream>
template <typename IndexedStruct, int Index>
struct _getter {
using Rest = decltype(std::declval<IndexedStruct>().rest);
static auto& get(IndexedStruct &inst)
{
return _getter<decltype(inst.rest), Index-1>::get(inst.rest);
}
static int offsetof()
{
Rest &rest = static_cast<IndexedStruct*>(nullptr)->rest;
int rest_offset = reinterpret_cast<const char *>(&rest) - static_cast<const char *>(nullptr);
return rest_offset + _getter<Rest, Index-1>::offsetof();
}
};
template <typename IndexedStruct>
struct _getter<IndexedStruct, 0> {
static auto& get(IndexedStruct &inst) { return inst.first; }
static int offsetof() { return 0; }
};
template <typename ...Members>
struct indexed_struct {};
template <typename First, typename ...Rest>
struct indexed_struct<First, Rest...> {
First first;
indexed_struct<Rest...> rest;
template <int Index> auto& get()
{
return _getter<decltype(*this), Index>::get(*this);
}
template <int Index> static int offsetof()
{
return _getter<indexed_struct, Index>::offsetof();
}
};
int main()
{
indexed_struct<int,int,float> my_data { 1, 2, 3.14159 };
std::cout << my_data.get<0>() << " at offset " << decltype(my_data)::offsetof<0>() << std::endl;
std::cout << my_data.get<1>() << " at offset " << decltype(my_data)::offsetof<1>() << std::endl;
std::cout << my_data.get<2>() << " at offset " << decltype(my_data)::offsetof<2>() << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment