www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Aliasing arguments in the template parameter list of an is-expression

reply "Meta" <jared771 gmail.com> writes:
I'd like to have the arguments of the template parameter list of 
an is-expression to be visible outside that is-expression, but I 
can't figure out a way to get an alias to them. Is something like 
this possible?

struct Pair(alias left, alias right) {}

template Left(P)
if (is(P == Pair!(left, right), left, right)
     && is(typeof(left) == int)
     && is(typeof(right) == int))
{
     //...
}

I know that I could put a constraint on the actual Pair type that 
left and right must be ints, but say I was unable to do that for 
some reason or another... Can I access that template parameter 
list outside of the first is-expression somehow?
Mar 18 2014
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/18/2014 09:02 AM, Meta wrote:
 I'd like to have the arguments of the template parameter list of an
 is-expression to be visible outside that is-expression, but I can't
 figure out a way to get an alias to them. Is something like this possible?

 struct Pair(alias left, alias right) {}

 template Left(P)
 if (is(P == Pair!(left, right), left, right)
      && is(typeof(left) == int)
      && is(typeof(right) == int))
Too many typeofs there. left and right are already types: && is(left == int) && is(right == int))
 {
      //...
 }

 I know that I could put a constraint on the actual Pair type that left
 and right must be ints, but say I was unable to do that for some reason
 or another... Can I access that template parameter list outside of the
 first is-expression somehow?
Ali
Mar 18 2014
parent reply "anonymous" <anonymous example.com> writes:
On Tuesday, 18 March 2014 at 17:07:01 UTC, Ali Çehreli wrote:
 On 03/18/2014 09:02 AM, Meta wrote:
[...]
 struct Pair(alias left, alias right) {}

 template Left(P)
 if (is(P == Pair!(left, right), left, right)
     && is(typeof(left) == int)
     && is(typeof(right) == int))
Too many typeofs there. left and right are already types: && is(left == int) && is(right == int))
No, Pair's left and right are alias parameters.
Mar 18 2014
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/18/2014 10:44 AM, anonymous wrote:
 On Tuesday, 18 March 2014 at 17:07:01 UTC, Ali Çehreli wrote:
 On 03/18/2014 09:02 AM, Meta wrote:
[...]
 struct Pair(alias left, alias right) {}

 template Left(P)
 if (is(P == Pair!(left, right), left, right)
     && is(typeof(left) == int)
     && is(typeof(right) == int))
Too many typeofs there. left and right are already types: && is(left == int) && is(right == int))
No, Pair's left and right are alias parameters.
Not in the Pair that I coded before sending that. :p struct Pair(L, R) {} Ali
Mar 18 2014
prev sibling parent reply "anonymous" <anonymous example.com> writes:
On Tuesday, 18 March 2014 at 16:02:26 UTC, Meta wrote:
 I'd like to have the arguments of the template parameter list 
 of an is-expression to be visible outside that is-expression, 
 but I can't figure out a way to get an alias to them. Is 
 something like this possible?

 struct Pair(alias left, alias right) {}

 template Left(P)
 if (is(P == Pair!(left, right), left, right)
     && is(typeof(left) == int)
     && is(typeof(right) == int))
 {
     //...
 }

 I know that I could put a constraint on the actual Pair type 
 that left and right must be ints, but say I was unable to do 
 that for some reason or another... Can I access that template 
 parameter list outside of the first is-expression somehow?
Since left and right are alias parameters, you need "alias" in the is expression, too: --- if (is(P == Pair!(left, right), alias left, alias right) && /* etc */) --- The snippet as given then compiles, but left and right won't be known in the template body. To achieve that, if you can do without the template constraint, just make it a static if in the body: --- template Left(P) { static if (is(P == Pair!(left, right), alias left, alias right) && is(typeof(left) == int) && is(typeof(right) == int)) { alias Left = left; /* or whatever */ } else static assert(false); } --- Otherwise, if you can't do without the template constraint, you have to duplicate the logic.
Mar 18 2014
parent reply "Meta" <jared771 gmail.com> writes:
On Tuesday, 18 March 2014 at 17:38:26 UTC, anonymous wrote:
 On Tuesday, 18 March 2014 at 16:02:26 UTC, Meta wrote:
 I'd like to have the arguments of the template parameter list 
 of an is-expression to be visible outside that is-expression, 
 but I can't figure out a way to get an alias to them. Is 
 something like this possible?

 struct Pair(alias left, alias right) {}

 template Left(P)
 if (is(P == Pair!(left, right), left, right)
    && is(typeof(left) == int)
    && is(typeof(right) == int))
 {
    //...
 }

 I know that I could put a constraint on the actual Pair type 
 that left and right must be ints, but say I was unable to do 
 that for some reason or another... Can I access that template 
 parameter list outside of the first is-expression somehow?
Since left and right are alias parameters, you need "alias" in the is expression, too: --- if (is(P == Pair!(left, right), alias left, alias right) && /* etc */) ---
Yes, my mistake. I also got an error about Pair!(1, 2) being unable to be interpreted at compile time, so I changed left and right to be types. The corrected example code: struct Pair(left, right) {} template Left(P) if (is(P == Pair!(left, right), left, right) && is(left == int) && is(right == int)) { //Error: undefined identifier left alias Left = left; } void main() { alias test = Left!(Pair!(int, int)); } Surprisingly, left and right are actually visible in the subsequent is-expressions that test if they're int. However, they are not available in the body. Is there a way around this?
Mar 18 2014
parent reply "anonymous" <anonymous example.com> writes:
On Tuesday, 18 March 2014 at 18:58:04 UTC, Meta wrote:
 On Tuesday, 18 March 2014 at 17:38:26 UTC, anonymous wrote:
[...]
 Since left and right are alias parameters, you need "alias" in
 the is expression, too:
 ---
 if (is(P == Pair!(left, right), alias left, alias right)
     && /* etc */)
 ---
Yes, my mistake. I also got an error about Pair!(1, 2) being unable to be interpreted at compile time, so I changed left and right to be types. The corrected example code: struct Pair(left, right) {} template Left(P) if (is(P == Pair!(left, right), left, right) && is(left == int) && is(right == int)) { //Error: undefined identifier left alias Left = left; } void main() { alias test = Left!(Pair!(int, int)); } Surprisingly, left and right are actually visible in the subsequent is-expressions that test if they're int. However, they are not available in the body. Is there a way around this?
See the rest of my message.
Mar 18 2014
parent "Meta" <jared771 gmail.com> writes:
On Tuesday, 18 March 2014 at 19:18:23 UTC, anonymous wrote:
 See the rest of my message.
Right, I was afraid this was the case.
Mar 18 2014