I am attempting to convert between two types of std::tuples but I'm having trouble getting the implementation right. I want it to map if the type is the same, but it needs to allow duplicate types to get mapped in the original order.
The basic logic is:
while has pair<input, output>
if type(input) == type(output)
then do map, next input, next output
else
next input
assert(all outputs mapped)
With an example mapping being:
My "best" attempt at a solution looks like this:
template <auto> struct value {};
template <auto... Vals> struct value_sequence {};
template <class... Vals> struct placeholder {};
template <auto... As, auto... Bs>
constexpr value_sequence<As..., Bs...> operator+(value_sequence<As...>, value_sequence<Bs...>)
{
return {};
}
template <size_t Idx, size_t... Idxs, size_t OtherIdx, size_t... OtherIdxs, class T, class... Ts, class OtherT, class... OtherTs>
constexpr auto mapper(const std::index_sequence<Idx, Idxs...>&, const std::index_sequence<OtherIdx, OtherIdxs...>&, const placeholder<T, Ts...>&,
const placeholder<OtherT, OtherTs...>&)
{
if constexpr (sizeof...(OtherIdxs) == 0)
{
static_assert(std::is_same_v<T, OtherT>);
return value_sequence<Idx>{};
}
else if constexpr (std::is_same_v<T, OtherT>)
{
return value_sequence<Idx>{} +
mapper(std::index_sequence<Idxs...>{}, std::index_sequence<OtherIdxs...>{}, placeholder<Ts...>{}, placeholder<OtherTs...>{});
}
else
{
return mapper(std::index_sequence<Idx, Idxs...>{}, std::index_sequence<OtherIdxs...>{}, placeholder<T, Ts...>{}, placeholder<OtherTs...>{});
}
}
Called with:
mapper(std::make_index_sequence<sizeof...(Ts)>{}, std::make_index_sequence<sizeof...(OtherTs)>{},
placeholder<Ts...>{}, placeholder<OtherTs...>{})
Which gives the compiler error error C2672: 'mapper': no matching overloaded function found
pointing to the else if
case of the function mapper
I'm working in c++17, and it looks like all the bits I need are there, I just can't assemble them the right way.
Any help would be really appreciated!