I would like to store the initialization values for elements in a tuple inside a separate tuple, so that I can use the same values as a preset for other tuples of the respective
For anyone interested in a solution, I came up with a way to control the initialization order and retain the constness of elements
:
#include
template
struct construct
{
template
static constexpr const std::tuple
drop_head_impl( const std::index_sequence ns,
const std::tuple tup )
{
return std::tuple( std::get( tup )... );
}
template
static constexpr const std::tuple
drop_head( const std::tuple tup )
{
return drop_head_impl( std::make_index_sequence(), tup );
}
template
static constexpr const std::tuple
func_impl( const std::tuple initer )
{
return std::tuple( { std::get<0>( initer ) } );
}
template
static constexpr const std::tuple
func_impl( const std::tuple initer )
{
std::tuple head( { std::get<0>( initer ) } );
return std::tuple_cat( head, func_impl( drop_head(initer) ) );
}
static constexpr const std::tuple
func( const std::tuple initer )
{
return func_impl( initer );
}
};
// Elements are the end points of a Widget hierarchy
struct Element
{
using initer_t = int;
Element( const initer_t pIniter )
:data{ pIniter }
{
printf( "Creating %i\n", data );
}
const initer_t data;
};
// A Widget class stores any number of Elements and/or other Widget instances
template
struct Widget
{
using initer_t = std::tuple;
Widget( const initer_t pIniter )
:elements( construct::func( pIniter ) )
{}
const std::tuple elements;
};
int main()
{
using Button = Widget;
using ButtonList = Widget
The construct
structure takes the tuple of initer_t
s (initer), constructs a tuple containing the first element of Elems...
using the first element of initer, then drops the first element of initer and passes the remaining tuple to itself, which causes a tuple with the next element of Elems...
to be constructed using the next element in initer. This recursion is stopped by an overload of func_impl
for a tuple with one element which simply constructs that element from its initer_t
in a tuple and returns it. This single-element tuple gets concatenated to the tuple with the previous element, the result gets returned to the higher level and is concatenated to the single-element tuple there and so on.