C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Accessing a tuple element of index not known until runtime

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Sun, 12 Nov 2023 01:16:13 +0100
niedz., 12 lis 2023 o 00:35 Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> napisaƂ(a):
>
> If we have a tuple as follows:
>
> tuple<int,char,long> mytuple;
>
> Then we can access its elements as follows:
>
> get<0>(mytuple)
> get<1>(mytuple)
> get<2>(mytuple)
>
> The index must be a compile-time constant in order for it to be a
> template parameter to the template function "get". I've seen people
> write if-else ladders and switch statements:
>
> void SetNull(unsigned const index, tuple<int,char,long> &t)
> {
> switch ( index )
> {
> case 0: get<0>(t) = {}; break;
> case 1: get<1>(t) = {}; break;
> case 2: get<2>(t) = {}; break;
> default: unreachable();
> }
> }
>
> I think a lot of people would agree that the best way to allow runtime
> access of tuple elements would be to use the 'visit' function. Have
> there been any other proposals to simplify runtime access of tuple
> elements?
>
> My own version of 'visit' can be used as follows to set a tuple element to null:
>
> visit( index, mytuple, [](auto &x)
> {
> x = {};
> });
>
> Here's the code behind it:
>
> template<std::size_t I, typename ElemType, typename V>
> void visit_detail2(std::size_t const index, ElemType &&e, V &&v)
> {
> if ( I != index ) return;
> std::forward<V>(v)( std::forward<ElemType>(e) );
> }
>
> template<typename T, typename V, std::size_t... I>
> void visit_detail1(std::size_t const index, T &&t, V &&v,
> std::index_sequence<I...>)
> {
> (..., visit_detail2<I>(index,std::get<I>(std::forward<T>(t)),std::forward<V>(v)));
> }
>
> template<typename T, typename V>
> void visit(std::size_t const index, T &&t, V &&v)
> {
> visit_detail1(index, std::forward<T>(t), std::forward<V>(v),
> std::make_index_sequence< std::tuple_size_v<typename
> std::decay_t<T> > >());
> }

Similar problems exist for `std::variant` if you want to
init it dynamically (like deserialization).
This could be a generic function that converts run time `int`
into `std::integral_constant<int, I>` from a given range.
Something like:
```
to_static<0, 20>(i, [&]<int I>(){ get<I>(v) = {}; });
```


> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2023-11-12 00:16:25