JPGygax68
12/27/2015 - 1:48 PM

Proof-of-concept for something similar to tuple, but based on struct composition instead of struct inheritance.

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;
}