Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
May 11, 2015 Run-time Indexing of a Compile-Time Tuple | ||||
---|---|---|---|---|
| ||||
The pattern final switch (_index) { import std.range: empty, front; foreach (i, R; Rs) { case i: assert(!source[i].empty); return source[i].front; } } occurring in roundRobin() and now also in my merge at https://github.com/nordlow/justd/blob/master/range_ex.d#L604 is nor pretty nor concise. Is there a better way of indexing a compile time tuple with a run-time index? It may have to work together with CommonType somehow as is shown in my implementation of merge(). |
May 11, 2015 Re: Run-time Indexing of a Compile-Time Tuple | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Monday, 11 May 2015 at 22:46:00 UTC, Per Nordlöw wrote:
> The pattern
>
> final switch (_index)
> {
> import std.range: empty, front;
> foreach (i, R; Rs)
> {
> case i:
> assert(!source[i].empty);
> return source[i].front;
> }
> }
>
> occurring in roundRobin() and now also in my merge at
>
> https://github.com/nordlow/justd/blob/master/range_ex.d#L604
>
> is nor pretty nor concise.
>
> Is there a better way of indexing a compile time tuple with a run-time index?
>
> It may have to work together with CommonType somehow as is shown in my implementation of merge().
Would this work?
auto x = std.typecons.tuple(Rs)[_index]
|
May 12, 2015 Re: Run-time Indexing of a Compile-Time Tuple | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Monday, 11 May 2015 at 22:46:00 UTC, Per Nordlöw wrote:
> The pattern
>
> final switch (_index)
> {
> import std.range: empty, front;
> foreach (i, R; Rs)
> {
> case i:
> assert(!source[i].empty);
> return source[i].front;
> }
> }
>
> occurring in roundRobin() and now also in my merge at
>
> https://github.com/nordlow/justd/blob/master/range_ex.d#L604
>
> is nor pretty nor concise.
>
> Is there a better way of indexing a compile time tuple with a run-time index?
>
> It may have to work together with CommonType somehow as is shown in my implementation of merge().
I wrote that code in roundRobin to replace a nightmare string mixin. I can't see any way of getting around it, as there is no meaningful CommonType for a tuple of arbitrary ranges. The body of each case statement needs to know the index at compile-time.
If the tuple genuinely did have a CommonType, then it would be easy to make a little free function (or member of std.typecons.tuple) to get this sort of result:
import std.typecons, std.traits;
CommonType!(T.Types) rtIdx(T)(T t, uint i)
if(is(T : Tuple!A, A...))
in
{
assert(i < t.length);
}
body
{
final switch(i)
{
foreach(ctI, m; t)
{
case ctI:
return t[ctI];
}
}
assert(0);
}
unittest
{
uint i = 2;
Tuple!(int, long, byte) myTuple;
myTuple[2] = 42;
auto a = myTuple.rtIdx(i);
static assert(is(typeof(a) == long));
assert(a == 42);
}
You could probably extend this to take expression tuples as well or whatever the hell we call compiler tuples that contain runtime values these days.
Alternatively, you could make rtIndex return a struct that defines opIndex, so you could write
auto a = myTuple.rtIdx[i];
opSlice would be doable as well, to round it out.
|
May 12, 2015 Re: Run-time Indexing of a Compile-Time Tuple | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Tuesday, 12 May 2015 at 09:26:07 UTC, John Colvin wrote:
> On Monday, 11 May 2015 at 22:46:00 UTC, Per Nordlöw wrote:
>> The pattern
>>
>> final switch (_index)
>> {
>> import std.range: empty, front;
>> foreach (i, R; Rs)
>> {
>> case i:
>> assert(!source[i].empty);
>> return source[i].front;
>> }
>> }
>>
>> occurring in roundRobin() and now also in my merge at
>>
>> https://github.com/nordlow/justd/blob/master/range_ex.d#L604
>>
>> is nor pretty nor concise.
>>
>> Is there a better way of indexing a compile time tuple with a run-time index?
>>
>> It may have to work together with CommonType somehow as is shown in my implementation of merge().
>
> I wrote that code in roundRobin to replace a nightmare string mixin. I can't see any way of getting around it, as there is no meaningful CommonType for a tuple of arbitrary ranges. The body of each case statement needs to know the index at compile-time.
Correction: there are ways around it, but none of them are
improvements.
|
May 12, 2015 Re: Run-time Indexing of a Compile-Time Tuple | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Parrill | On Monday, 11 May 2015 at 23:12:17 UTC, Alex Parrill wrote:
> Would this work?
>
> auto x = std.typecons.tuple(Rs)[_index]
Nope. _index must be know at compile-time.
|
May 12, 2015 Re: Run-time Indexing of a Compile-Time Tuple | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Monday, 11 May 2015 at 22:46:00 UTC, Per Nordlöw wrote: > The pattern > > final switch (_index) > { > import std.range: empty, front; > foreach (i, R; Rs) > { > case i: > assert(!source[i].empty); > return source[i].front; > } > } > > occurring in roundRobin() and now also in my merge at > > https://github.com/nordlow/justd/blob/master/range_ex.d#L604 > > is nor pretty nor concise. > > Is there a better way of indexing a compile time tuple with a run-time index? > > It may have to work together with CommonType somehow as is shown in my implementation of merge(). A little hacky, but how about casting it to a static array? http://dpaste.dzfl.pl/d0059e6e6c09 |
May 13, 2015 Re: Run-time Indexing of a Compile-Time Tuple | ||||
---|---|---|---|---|
| ||||
Posted in reply to Idan Arye | On Tuesday, 12 May 2015 at 13:30:22 UTC, Idan Arye wrote: > A little hacky, but how about casting it to a static array? > > http://dpaste.dzfl.pl/d0059e6e6c09 This PR[1] achieves this without making a copy. [1] https://github.com/D-Programming-Language/phobos/pull/3198 |
Copyright © 1999-2021 by the D Language Foundation