Re: Sequence separation

2016-08-21 Thread Alexandru Ermicioi via Digitalmars-d-learn
On Wednesday, 17 August 2016 at 19:38:22 UTC, Engine Machine 
wrote:
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]].


Maybe you can use Tuple from std.typecons, instead of custom 
structs, that group the arguments.


Ex:

alias seqWithSubSeq = AliasSeq!(a, b, Tuple!(c, d))

http://dlang.org/phobos/std_typecons.html#.Tuple


Re: Sequence separation

2016-08-17 Thread ag0aep6g via Digitalmars-d-learn

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.


Re: Sequence separation

2016-08-17 Thread Engine Machine via Digitalmars-d-learn

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]].



Re: Sequence separation

2016-08-17 Thread Engine Machine via Digitalmars-d-learn
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 ;/


Re: Sequence separation

2016-08-17 Thread Engine Machine via Digitalmars-d-learn
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?


Re: Sequence separation

2016-08-17 Thread Lodovico Giaretta via Digitalmars-d-learn

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).


Re: Sequence separation

2016-08-17 Thread ag0aep6g via Digitalmars-d-learn

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.


Re: Sequence separation

2016-08-17 Thread Engine Machine via Digitalmars-d-learn
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.






Re: Sequence separation

2016-08-17 Thread Lodovico Giaretta via Digitalmars-d-learn

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);


Re: Sequence separation

2016-08-16 Thread Adam D. Ruppe via Digitalmars-d-learn

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.