Jump to page: 1 2
Thread overview
Make a type tuple from an array
Apr 10, 2015
Marc Schütz
Apr 10, 2015
John Colvin
Apr 10, 2015
Marc Schütz
Apr 10, 2015
John Colvin
Apr 10, 2015
Marc Schütz
Apr 10, 2015
Nordlöw
Apr 11, 2015
John Colvin
Apr 11, 2015
Nordlöw
Apr 11, 2015
Dicebot
Apr 11, 2015
John Colvin
Apr 11, 2015
Artur Skawina
April 10, 2015
Is there a way to turn an array (known at compile time) into a TypeTuple? I want to do a static foreach over it, like this:

    foreach(field; fields) {
        static if(is(mixin("T." ~ field.name))) { ... }
    }

Obviously that won't work, because we don't have a real static foreach yet.

I already worked around it with a string mixin, but I'd like to know whether there's a cleaner way...
April 10, 2015
On Friday, 10 April 2015 at 15:13:54 UTC, Marc Schütz wrote:
> Is there a way to turn an array (known at compile time) into a TypeTuple? I want to do a static foreach over it, like this:
>
>     foreach(field; fields) {
>         static if(is(mixin("T." ~ field.name))) { ... }
>     }
>
> Obviously that won't work, because we don't have a real static foreach yet.
>
> I already worked around it with a string mixin, but I'd like to know whether there's a cleaner way...

For input ranges in general:

import std.range : isInputRange;

template TypeTupleOf(TL...)
    if (TL.length == 1 && isInputRange!(typeof(TL[0])))
{
    import std.typetuple : TT = TypeTuple;
    enum r = TL[0];
    static if (r.empty)
        alias TypeTupleOf = TT!();
    else
    {
        enum f = r.front;
        alias TypeTupleOf = TT!(
            f,
            TypeTupleOf!(
                { auto tmp = r; tmp.popFront(); return tmp; }()
                )
            );
    }
}

unittest
{
    import std.range : iota;
    foreach(i; TypeTupleOf!(iota(10)))
    {
        pragma(msg, i);
    }
}
April 10, 2015
On Friday, 10 April 2015 at 15:36:42 UTC, John Colvin wrote:
> On Friday, 10 April 2015 at 15:13:54 UTC, Marc Schütz wrote:
>> Is there a way to turn an array (known at compile time) into a TypeTuple? I want to do a static foreach over it, like this:
>>
>>    foreach(field; fields) {
>>        static if(is(mixin("T." ~ field.name))) { ... }
>>    }
>>
>> Obviously that won't work, because we don't have a real static foreach yet.
>>
>> I already worked around it with a string mixin, but I'd like to know whether there's a cleaner way...
>
> For input ranges in general:
>
> import std.range : isInputRange;
>
> template TypeTupleOf(TL...)
>     if (TL.length == 1 && isInputRange!(typeof(TL[0])))
> {
>     import std.typetuple : TT = TypeTuple;
>     enum r = TL[0];
>     static if (r.empty)
>         alias TypeTupleOf = TT!();
>     else
>     {
>         enum f = r.front;
>         alias TypeTupleOf = TT!(
>             f,
>             TypeTupleOf!(
>                 { auto tmp = r; tmp.popFront(); return tmp; }()
>                 )
>             );
>     }
> }
>
> unittest
> {
>     import std.range : iota;
>     foreach(i; TypeTupleOf!(iota(10)))
>     {
>         pragma(msg, i);
>     }
> }

Wow, thanks! I had to `import std.array : empty, front, popFront;`, but otherwise it works great.

This should be in Phobos!
April 10, 2015
On Friday, 10 April 2015 at 17:53:31 UTC, Marc Schütz wrote:
> On Friday, 10 April 2015 at 15:36:42 UTC, John Colvin wrote:
>> On Friday, 10 April 2015 at 15:13:54 UTC, Marc Schütz wrote:
>>> Is there a way to turn an array (known at compile time) into a TypeTuple? I want to do a static foreach over it, like this:
>>>
>>>   foreach(field; fields) {
>>>       static if(is(mixin("T." ~ field.name))) { ... }
>>>   }
>>>
>>> Obviously that won't work, because we don't have a real static foreach yet.
>>>
>>> I already worked around it with a string mixin, but I'd like to know whether there's a cleaner way...
>>
>> For input ranges in general:
>>
>> import std.range : isInputRange;
>>
>> template TypeTupleOf(TL...)
>>    if (TL.length == 1 && isInputRange!(typeof(TL[0])))
>> {
>>    import std.typetuple : TT = TypeTuple;
>>    enum r = TL[0];
>>    static if (r.empty)
>>        alias TypeTupleOf = TT!();
>>    else
>>    {
>>        enum f = r.front;
>>        alias TypeTupleOf = TT!(
>>            f,
>>            TypeTupleOf!(
>>                { auto tmp = r; tmp.popFront(); return tmp; }()
>>                )
>>            );
>>    }
>> }
>>
>> unittest
>> {
>>    import std.range : iota;
>>    foreach(i; TypeTupleOf!(iota(10)))
>>    {
>>        pragma(msg, i);
>>    }
>> }
>
> Wow, thanks! I had to `import std.array : empty, front, popFront;`, but otherwise it works great.

Haha, yeah... I forgot where they were, they aren't documented in
std.array (grrrr), so I just left it for someone else to find :p

> This should be in Phobos!

Yup. I've mentioned it here:
https://github.com/D-Programming-Language/phobos/pull/3128  but
it's a bit of a complicated situation as a bunch of names are
likely to change.
April 10, 2015
On Friday, 10 April 2015 at 18:25:14 UTC, John Colvin wrote:
>> This should be in Phobos!
>
> Yup. I've mentioned it here:
> https://github.com/D-Programming-Language/phobos/pull/3128  but
> it's a bit of a complicated situation as a bunch of names are
> likely to change.

I had seen the PR, but didn't mentally connect it with std.typetuple. Now I see it's intended as a replacement for it.

Good that it won't get lost.
April 10, 2015
On Friday, 10 April 2015 at 15:36:42 UTC, John Colvin wrote:
>     if (TL.length == 1 && isInputRange!(typeof(TL[0])))

Why not use isStaticArray instead of isInputRange here?
April 11, 2015
On Friday, 10 April 2015 at 22:55:23 UTC, Nordlöw wrote:
> On Friday, 10 April 2015 at 15:36:42 UTC, John Colvin wrote:
>>    if (TL.length == 1 && isInputRange!(typeof(TL[0])))
>
> Why not use isStaticArray instead of isInputRange here?

Because that would be completely different. Static arrays aren't even input ranges...
April 11, 2015
On Saturday, 11 April 2015 at 07:18:26 UTC, John Colvin wrote:
>> Why not use isStaticArray instead of isInputRange here?
>
> Because that would be completely different. Static arrays aren't even input ranges...

Ahh, my mistake.

Could somebody explain when this feature is needed?
April 11, 2015
On Saturday, 11 April 2015 at 09:05:19 UTC, Nordlöw wrote:
> On Saturday, 11 April 2015 at 07:18:26 UTC, John Colvin wrote:
>>> Why not use isStaticArray instead of isInputRange here?
>>
>> Because that would be completely different. Static arrays aren't even input ranges...
>
> Ahh, my mistake.
>
> Could somebody explain when this feature is needed?

Code generation. Doing string mixin for each element of the array (won't work with plain foreach over array as it does runtime iteration)
April 11, 2015
On Saturday, 11 April 2015 at 09:23:11 UTC, Dicebot wrote:
> On Saturday, 11 April 2015 at 09:05:19 UTC, Nordlöw wrote:
>> On Saturday, 11 April 2015 at 07:18:26 UTC, John Colvin wrote:
>>>> Why not use isStaticArray instead of isInputRange here?
>>>
>>> Because that would be completely different. Static arrays aren't even input ranges...
>>
>> Ahh, my mistake.
>>
>> Could somebody explain when this feature is needed?
>
> Code generation. Doing string mixin for each element of the array (won't work with plain foreach over array as it does runtime iteration)

Generating case statements is a nice example use that doesn't (necessarily) involve string mixins.
« First   ‹ Prev
1 2