Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 16, 2016 Sequence separation | ||||
---|---|---|---|---|
| ||||
alias x = AliasSeq!(a, b, AliasSeq!(c, d)); results in a flat sequence. I would like to be able to keep them separate so I can have sub sequences. x.length == 4; |
August 16, 2016 Re: Sequence separation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Engine Machine | On Tuesday, 16 August 2016 at 19:17:27 UTC, Engine Machine wrote:
> alias x = AliasSeq!(a, b, AliasSeq!(c, d));
>
> results in a flat sequence. I would like to be able to keep them separate so I can have sub sequences.
wrap them in a struct.
|
August 17, 2016 Re: Sequence separation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Tuesday, 16 August 2016 at 23:18:28 UTC, Adam D. Ruppe wrote:
> On Tuesday, 16 August 2016 at 19:17:27 UTC, Engine Machine wrote:
>> alias x = AliasSeq!(a, b, AliasSeq!(c, d));
>>
>> results in a flat sequence. I would like to be able to keep them separate so I can have sub sequences.
>
> wrap them in a struct.
You mean something like:
struct MySequence(Args...)
{
enum length = Args.length;
alias args = Args;
}
alias x = MySequence!(a, b, MySequence!(c, d));
static assert(x.length == 3)
static assert(x.args[2].length == 2);
|
August 17, 2016 Re: Sequence separation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lodovico Giaretta | On Wednesday, 17 August 2016 at 08:37:32 UTC, Lodovico Giaretta wrote:
> On Tuesday, 16 August 2016 at 23:18:28 UTC, Adam D. Ruppe wrote:
>> On Tuesday, 16 August 2016 at 19:17:27 UTC, Engine Machine wrote:
>>> alias x = AliasSeq!(a, b, AliasSeq!(c, d));
>>>
>>> results in a flat sequence. I would like to be able to keep them separate so I can have sub sequences.
>>
>> wrap them in a struct.
>
> You mean something like:
>
> struct MySequence(Args...)
> {
> enum length = Args.length;
> alias args = Args;
> }
>
> alias x = MySequence!(a, b, MySequence!(c, d));
>
> static assert(x.length == 3)
> static assert(x.args[2].length == 2);
Thanks, basically works.
How can I test, though, if a argument uses a MySequence? I can't do if (Args[0] == MySequence) because MySequence is templated. While I could test for a length, that doesn't work because some types have a length. I could add another enum to MySequence, but again, not safe.
I could do some string tests, but that doesn't work.
in your exmaple,
if (x.args[2] == MySequence) ??
I simply need to differentiate between a parameter/arg being a MySequence and not.
|
August 17, 2016 Re: Sequence separation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Engine Machine | On 08/17/2016 08:38 PM, Engine Machine wrote: > On Wednesday, 17 August 2016 at 08:37:32 UTC, Lodovico Giaretta wrote: [...] >> You mean something like: >> >> struct MySequence(Args...) >> { >> enum length = Args.length; >> alias args = Args; >> } >> >> alias x = MySequence!(a, b, MySequence!(c, d)); >> >> static assert(x.length == 3) >> static assert(x.args[2].length == 2); > > Thanks, basically works. > > How can I test, though, if a argument uses a MySequence? I can't do if > (Args[0] == MySequence) because MySequence is templated. While I could > test for a length, that doesn't work because some types have a length. I > could add another enum to MySequence, but again, not safe. > > I could do some string tests, but that doesn't work. > > in your exmaple, > > if (x.args[2] == MySequence) ?? > > I simply need to differentiate between a parameter/arg being a > MySequence and not. With MySequence being a type, you can do this: ---- static if (is(x.args[2] == MySequence!Args, Args ...)) { ... } ---- Aside from this check, there is probably not much use for MySequence being a type. So I'm be tempted to find a way to do the check with a raw template MySequence. As you said, another enum alone doesn't cut it. The faker can just add the same enum. But a private enum of a private type might do it: ---- template MySequence(Args ...) { /* ... length and args ... */ private enum id = Id(); } private struct Id {} enum isMySequence(alias seq) = is(typeof(seq.id) == Id); ---- Other modules can't use the Id type directly, because it's private. And they can't use typeof(MySequence!foo.id), because the id member is private, too. However, I wouldn't be surprised if this can be circumvented too. |
August 17, 2016 Re: Sequence separation | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On Wednesday, 17 August 2016 at 19:15:48 UTC, ag0aep6g wrote:
> On 08/17/2016 08:38 PM, Engine Machine wrote:
>> On Wednesday, 17 August 2016 at 08:37:32 UTC, Lodovico Giaretta wrote:
> [...]
>>> You mean something like:
>>>
>>> struct MySequence(Args...)
>>> {
>>> enum length = Args.length;
>>> alias args = Args;
>>> }
>>>
>>> alias x = MySequence!(a, b, MySequence!(c, d));
>>>
>>> static assert(x.length == 3)
>>> static assert(x.args[2].length == 2);
>>
>> Thanks, basically works.
>>
>> How can I test, though, if a argument uses a MySequence? I can't do if
>> (Args[0] == MySequence) because MySequence is templated. While I could
>> test for a length, that doesn't work because some types have a length. I
>> could add another enum to MySequence, but again, not safe.
>>
>> I could do some string tests, but that doesn't work.
>>
>> in your exmaple,
>>
>> if (x.args[2] == MySequence) ??
>>
>> I simply need to differentiate between a parameter/arg being a
>> MySequence and not.
>
> With MySequence being a type, you can do this:
>
> ----
> static if (is(x.args[2] == MySequence!Args, Args ...))
> {
> ...
> }
> ----
>
> Aside from this check, there is probably not much use for MySequence being a type. So I'm be tempted to find a way to do the check with a raw template MySequence.
import std.traits: TemplateOf;
static if (__traits(isSame, TemplateOf!(x.args[2]), MySequence))
{
...
}
std.traits.TemplateOf extracts the symbol representing the uninstantiated template.
__traits(isSame, symbol1, symbol2) evaluates at compile time to true if and only if the two symbols represent the same thing (be it a type, an uninstantiated template, an instantiated one or whatever else).
|
August 17, 2016 Re: Sequence separation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Engine Machine | On Wednesday, 17 August 2016 at 18:38:48 UTC, Engine Machine wrote:
> On Wednesday, 17 August 2016 at 08:37:32 UTC, Lodovico Giaretta wrote:
>> On Tuesday, 16 August 2016 at 23:18:28 UTC, Adam D. Ruppe wrote:
>>> [...]
>>
>> You mean something like:
>>
>> struct MySequence(Args...)
>> {
>> enum length = Args.length;
>> alias args = Args;
>> }
>>
>> alias x = MySequence!(a, b, MySequence!(c, d));
>>
>> static assert(x.length == 3)
>> static assert(x.args[2].length == 2);
>
> Thanks, basically works.
>
> How can I test, though, if a argument uses a MySequence? I can't do if (Args[0] == MySequence) because MySequence is templated. While I could test for a length, that doesn't work because some types have a length. I could add another enum to MySequence, but again, not safe.
>
> I could do some string tests, but that doesn't work.
>
> in your exmaple,
>
> if (x.args[2] == MySequence) ??
>
> I simply need to differentiate between a parameter/arg being a MySequence and not.
I guess I'll go with something like
static if ((a.Args[2]).stringof[0..11] == "MySequence!")
Doesn't feel entirely safe but probably will work without issue.
Maybe there is a better way?
|
August 17, 2016 Re: Sequence separation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lodovico Giaretta | On Wednesday, 17 August 2016 at 19:21:57 UTC, Lodovico Giaretta wrote: > On Wednesday, 17 August 2016 at 19:15:48 UTC, ag0aep6g wrote: >> [...] > > import std.traits: TemplateOf; > static if (__traits(isSame, TemplateOf!(x.args[2]), MySequence)) > { > ... > } > > std.traits.TemplateOf extracts the symbol representing the uninstantiated template. > > __traits(isSame, symbol1, symbol2) evaluates at compile time to true if and only if the two symbols represent the same thing (be it a type, an uninstantiated template, an instantiated one or whatever else). Thanks! To note, it error's if there is no match ;/ |
August 17, 2016 Re: Sequence separation | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On Wednesday, 17 August 2016 at 19:15:48 UTC, ag0aep6g wrote: > On 08/17/2016 08:38 PM, Engine Machine wrote: >> [...] > [...] >> [...] > > With MySequence being a type, you can do this: > > ---- > static if (is(x.args[2] == MySequence!Args, Args ...)) > { > ... > } > ---- > It works! Nifty that you can do that with is. > Aside from this check, there is probably not much use for MySequence being a type. So I'm be tempted to find a way to do the check with a raw template MySequence. > > As you said, another enum alone doesn't cut it. The faker can just add the same enum. > > But a private enum of a private type might do it: > > ---- > template MySequence(Args ...) > { > /* ... length and args ... */ > private enum id = Id(); > } > > private struct Id {} > > enum isMySequence(alias seq) = is(typeof(seq.id) == Id); > ---- > > Other modules can't use the Id type directly, because it's private. And they can't use typeof(MySequence!foo.id), because the id member is private, too. > > However, I wouldn't be surprised if this can be circumvented too. Well, the is does work and that probably is the best solution. I don't mind the extra type at this point. Of course, a library solution for this type of stuff would be nice. I'd rather not have to even use a type but rather use arrays: [a,b,[c,d]]. |
August 17, 2016 Re: Sequence separation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lodovico Giaretta | On 08/17/2016 09:21 PM, Lodovico Giaretta wrote:
> import std.traits: TemplateOf;
> static if (__traits(isSame, TemplateOf!(x.args[2]), MySequence))
> {
> ...
> }
>
> std.traits.TemplateOf extracts the symbol representing the
> uninstantiated template.
>
> __traits(isSame, symbol1, symbol2) evaluates at compile time to true if
> and only if the two symbols represent the same thing (be it a type, an
> uninstantiated template, an instantiated one or whatever else).
Look at that! Much better.
TemplateOf is implemented with a template specialization, which can handle other things than types, unlike `is(...)`.
Using that directly, without going to std.traits, isMySequence could be done like this:
----
enum isMySequence(alias thing : MySequence!args, args ...) = true;
enum isMySequence(alias thing) = false;
----
That's just me toying around with the language, of course. The isSame+TemplateOf version is perfectly fine.
|
Copyright © 1999-2021 by the D Language Foundation