digitalmars.D.learn - Testing for template argument being result of takeExactly
- Jonathan M Davis (34/34) Sep 22 2012 I'm trying to test whether a template argument is the type returned by
- bearophile (9/12) Sep 22 2012 I have done some tries, but I have failed, I am sorry :-)
- Jonathan M Davis (9/20) Sep 22 2012 The power that it provides is useful if not outright necessary, but it c...
- Timon Gehr (13/47) Sep 23 2012 import std.range, std.traits;
- Andrei Alexandrescu (5/10) Sep 23 2012 That's the nicest. Regarding availability of "_input", I meant to make
- Timon Gehr (10/21) Sep 23 2012 Well, I noticed it is not entirely correct as takeExactly special cases
- Jonathan M Davis (8/11) Sep 23 2012 Thanks. That does the trick quite cleanly, though you'd think that it wo...
- monarch_dodra (30/59) Sep 23 2012 Interesting. Thanks.
- monarch_dodra (8/9) Sep 23 2012 I think I forgot this test, when R is already a type returned by
- monarch_dodra (11/21) Sep 23 2012 Er, sorry for triple post, no edit button.
- Jonathan M Davis (13/21) Sep 24 2012 It may work, but again, it's relying on how takeExactly works. It's test...
- monarch_dodra (20/49) Sep 24 2012 Good points.
- Jonathan M Davis (11/24) Sep 24 2012 That was one trick that I was not aware of. I didn't think that one is
- monarch_dodra (23/54) Sep 24 2012 Well, it does work...
- Jonathan M Davis (6/32) Sep 24 2012 @disable this; is pretty broken, so I wouldn't really trust it at this p...
- Timon Gehr (6/24) Sep 24 2012 I don't think this does what you think it does. The 'is(R r)' declares r...
- monarch_dodra (11/20) Sep 24 2012 Technically, no: That was my first try, and as mentioned in the
- Timon Gehr (7/24) Sep 26 2012 I assume you messed up the parentheses.
- monarch_dodra (10/41) Sep 26 2012 Yes sorry. I miss read that.
- Timon Gehr (3/42) Sep 26 2012 It is special syntax, not an == operator. is-expressions suppress errors
- Andrei Alexandrescu (3/7) Sep 26 2012 Neither should work. The expression should be takeExactly(S.init, 1).
- Timon Gehr (3/11) Sep 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8220
- monarch_dodra (20/23) Sep 23 2012 I *kind of* see what you are doing with U, V, W, but what's wrong
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (12/34) Sep 23 2012 The goal is to "test whether a template argument is the type returned by...
- monarch_dodra (18/61) Sep 23 2012 That did seem fishy to me too actually, but it does compile.
- Timon Gehr (3/8) Sep 23 2012 See discussion here:
I'm trying to test whether a template argument is the type returned by takeExactly, and I haven't been able to sort out the template voodoo required yet. It would be a lot easier if I had a variable to work with, but I just have the type, and the fancy is expression required to pull it off is fancy enough that I haven't been able to sort it out yet. At present, I have this: import std.range; import std.stdio; template Hello(R) if(is(R r == U, V, V w, U = typeof(takeExactly(w, 1)))) { alias R Hello; } void main() { auto str = "hello"; auto t = takeExactly(str, 3); writeln(t); Hello!(typeof(t)) h = t; writeln(h); } I need Hello to instatiate if R is the type returned by takeExactly and fail to instantiate otherwise. At present, the code gives these compilation errors: q.d(15): Error: template instance Hello!(Result) Hello!(Result) does not match template declaration Hello(R) if (is(R r == U,V,V w,U = typeof(takeExactly(w,1)))) q.d(15): Error: Hello!(Result) is used as a type q.d(16): Error: template std.stdio.writeln does not match any function template declaration q.d(16): Error: template std.stdio.writeln(T...) cannot deduce template function from argument types !()(_error_) So, clearly I don't have the is expression right, and this is seriously pushing the edge of my knowledge of is expressions. So, any help would be appreciated. Thanks. - Jonathan M Davis
Sep 22 2012
Jonathan M Davis:So, clearly I don't have the is expression right, and this is seriously pushing the edge of my knowledge of is expressions. So, any help would be appreciated. Thanks.I have done some tries, but I have failed, I am sorry :-) The is() syntax is a part of D good to burn on a campfire. But takeExactly returns a Result struct defined inside it, so it even possible for the is() syntax to work on this inner (hidden?) type? Generally the idea of defining structs inside looks nice, but seems a source for troubles. Bye, bearophile
Sep 22 2012
On Sunday, September 23, 2012 02:57:36 bearophile wrote:Jonathan M Davis:The power that it provides is useful if not outright necessary, but it could definitely use some improvements in the usability camp once you go beyond the basics. But I don't even know how you'd go about designing it so that it was more user friendly.So, clearly I don't have the is expression right, and this is seriously pushing the edge of my knowledge of is expressions. So, any help would be appreciated. Thanks.I have done some tries, but I have failed, I am sorry :-) The is() syntax is a part of D good to burn on a campfire.But takeExactly returns a Result struct defined inside it, so it even possible for the is() syntax to work on this inner (hidden?) type? Generally the idea of defining structs inside looks nice, but seems a source for troubles.Yeah. Increasingly, it looks like Voldemort types are a bad idea as nice as they are in principle. But we have yet to reach the point where it's clear that we need to ditch them. We may yet get there though. - Jonathan M Davis
Sep 22 2012
On 09/23/2012 01:54 AM, Jonathan M Davis wrote:I'm trying to test whether a template argument is the type returned by takeExactly, and I haven't been able to sort out the template voodoo required yet. It would be a lot easier if I had a variable to work with, but I just have the type, and the fancy is expression required to pull it off is fancy enough that I haven't been able to sort it out yet. At present, I have this: import std.range; import std.stdio; template Hello(R) if(is(R r == U, V, V w, U = typeof(takeExactly(w, 1)))) { alias R Hello; } void main() { auto str = "hello"; auto t = takeExactly(str, 3); writeln(t); Hello!(typeof(t)) h = t; writeln(h); } I need Hello to instatiate if R is the type returned by takeExactly and fail to instantiate otherwise. At present, the code gives these compilation errors: q.d(15): Error: template instance Hello!(Result) Hello!(Result) does not match template declaration Hello(R) if (is(R r == U,V,V w,U = typeof(takeExactly(w,1)))) q.d(15): Error: Hello!(Result) is used as a type q.d(16): Error: template std.stdio.writeln does not match any function template declaration q.d(16): Error: template std.stdio.writeln(T...) cannot deduce template function from argument types !()(_error_) So, clearly I don't have the is expression right, and this is seriously pushing the edge of my knowledge of is expressions. So, any help would be appreciated. Thanks. - Jonathan M Davisimport std.range, std.traits; import std.stdio; template Hello(R) if(is(typeof(R._input.takeExactly(2)) == R)){ alias R Hello; } void main(){ auto str = "hello"; auto t = takeExactly(str, 3); writeln(t); Hello!(typeof(t)) h = t; writeln(h); }
Sep 23 2012
On 9/23/12 8:47 AM, Timon Gehr wrote:import std.range, std.traits; import std.stdio; template Hello(R) if(is(typeof(R._input.takeExactly(2)) == R)){ alias R Hello; }That's the nicest. Regarding availability of "_input", I meant to make it available systematically as "input" for ranges where the notion makes sense. Andrei
Sep 23 2012
On 09/23/2012 03:48 PM, Andrei Alexandrescu wrote:On 9/23/12 8:47 AM, Timon Gehr wrote:Well, I noticed it is not entirely correct as takeExactly special cases sliceable inputs. Therefore, the guard also passes for ranges that have a sliceable member called _input of the same range type. The correct guard therefore would be: if(hasSlicing!R || is(typeof(R._input.takeExactly(2)) == R)) or if(!hasSlicing!R && is(typeof(R._input.takeExactly(2)) == R)) depending on what the goal is.import std.range, std.traits; import std.stdio; template Hello(R) if(is(typeof(R._input.takeExactly(2)) == R)){ alias R Hello; }That's the nicest.Regarding availability of "_input", I meant to make it available systematically as "input" for ranges where the notion makes sense. AndreiThis seems to be reasonable.
Sep 23 2012
On Sunday, September 23, 2012 14:47:27 Timon Gehr wrote:template Hello(R) if(is(typeof(R._input.takeExactly(2)) == R)){ alias R Hello; }Thanks. That does the trick quite cleanly, though you'd think that it would be possible to test whether a template argument is the result of takeExactly without caring or knowing about the guts of takeExactly. So, this isn't a general purpose solution at all, when I think that there should be one. Still, I don't need a general purpose one for what I'm doing, so this should work just fine. - Jonathan M Davis
Sep 23 2012
On Sunday, 23 September 2012 at 21:52:23 UTC, Timon Gehr wrote:On 09/23/2012 10:57 PM, Ali Çehreli wrote:Interesting. Thanks. On Sunday, 23 September 2012 at 21:53:20 UTC, Jonathan M Davis wrote:... Also, I think your code should have passed a range like R.init to takeExactly, not R, which is a type: takeExactly(R.init, 1) I don't know why your code compiles.See discussion here: http://d.puremagic.com/issues/show_bug.cgi?id=8220On Sunday, September 23, 2012 14:47:27 Timon Gehr wrote:What is wrong with my proposed solution? ---- import std.range; template Hello(R) if ( is(typeof(takeExactly(R.init, 1))) && is(R == typeof(takeExactly(R.init, 1))) ) { alias R Hello; } struct R { enum empty = false; property int front(); void popFront(); } struct S{} void main( ) { Hello!(int[]) a; //OK Hello!R b; //Fails second Check: R == typeof(...) Hello!S c; //Fails first check: is(typeof(takeExactly(...))) } ---- Forgive me again if there is something wrong with it, but this time, I think it is correct...?template Hello(R) if(is(typeof(R._input.takeExactly(2)) == R)){ alias R Hello; }Thanks. That does the trick quite cleanly, though you'd think that it would be possible to test whether a template argument is the result of takeExactly without caring or knowing about the guts of takeExactly. So, this isn't a general purpose solution at all, when I think that there should be one. Still, I don't need a general purpose one for what I'm doing, so this should work just fine. - Jonathan M Davis
Sep 23 2012
On Monday, 24 September 2012 at 06:20:57 UTC, monarch_dodra wrote:What is wrong with my proposed solution?I think I forgot this test, when R is already a type returned by takeExactly: void main( ) { alias typeof(takeExactly(R.init, 5)) G; Hello!G g; } Which also works.
Sep 23 2012
On Monday, 24 September 2012 at 06:29:25 UTC, monarch_dodra wrote:On Monday, 24 September 2012 at 06:20:57 UTC, monarch_dodra wrote:Er, sorry for triple post, no edit button. This is R: struct R { enum empty = false; property int front(); void popFront(); } I meant when "Hello' R is already the result of a Take exactly", sorry for the confusion.What is wrong with my proposed solution?I think I forgot this test, when R is already a type returned by takeExactly: void main( ) { alias typeof(takeExactly(R.init, 5)) G; Hello!G g; } Which also works.
Sep 23 2012
On Monday, September 24, 2012 08:21:46 monarch_dodra wrote:template Hello(R) if ( is(typeof(takeExactly(R.init, 1))) && is(R == typeof(takeExactly(R.init, 1))) ) { alias R Hello; }What is wrong with my proposed solution?It may work, but again, it's relying on how takeExactly works. It's testing that you can call takeExactly on R.init and then that R is the same type as that result, which means that it's relies on the fact that takeExactly returns itself if you call takeExactly on it. It also relies on init, which can be risky, given the fact that it can be disabled. So, between your prosposal and the other that Philippe and Timon gave, theirs seems better. But unfortunately, none of the proposals work generically. Ideally, there would be a way to generically test that a type is the type returned by particular function, and I would _think_ that that's possible, but the way that I would expect to work doesn't. Regardless, thanks for your help. - Jonathan M Davis
Sep 24 2012
On Monday, 24 September 2012 at 07:07:16 UTC, Jonathan M Davis wrote:On Monday, September 24, 2012 08:21:46 monarch_dodra wrote:Good points. Regarding the ".init" issue, I hadn't thought of that, but it can be worked around pretty easily with an is(R r): -------- template Hello(R) if ( is(R r) && is(typeof(takeExactly(r, 1))) && is(R == typeof(takeExactly(r, 1))) ) { alias R Hello; } -------- After that, I guess it is indeed one implementation detail vs the other. IMO, it really depends on whether or not you'd want "int[]" to be considered the return type of a takeExactly :/ Maybe it is, maybe it ain't.template Hello(R) if ( is(typeof(takeExactly(R.init, 1))) && is(R == typeof(takeExactly(R.init, 1))) ) { alias R Hello; }What is wrong with my proposed solution?It may work, but again, it's relying on how takeExactly works. It's testing that you can call takeExactly on R.init and then that R is the same type as that result, which means that it's relies on the fact that takeExactly returns itself if you call takeExactly on it. It also relies on init, which can be risky, given the fact that it can be disabled. So, between your prosposal and the other that Philippe and Timon gave, theirs seems better. But unfortunately, none of the proposals work generically. Ideally, there would be a way to generically test that a type is the type returned by particular function, and I would _think_ that that's possible, but the way that I would expect to work doesn't. Regardless, thanks for your help. - Jonathan M Davis
Sep 24 2012
On Monday, September 24, 2012 09:41:26 monarch_dodra wrote:Regarding the ".init" issue, I hadn't thought of that, but it can be worked around pretty easily with an is(R r): -------- template Hello(R) if ( is(R r) && is(typeof(takeExactly(r, 1))) && is(R == typeof(takeExactly(r, 1))) ) { alias R Hello; } --------That was one trick that I was not aware of. I didn't think that one is expression could have an effect on a later one in the surrounding expression. Cool. Though I would point out that that probably doesn't avoid the init problem, because R r uses R.init (unless is expressions treat it differently, which they may). The normal way to avoid that is to do R r = void; but I don't think that that would work in that is expression. Sometimes disabling init is useful, but it can definitely be problematic. It may ultimately have been a mistake to allow it. I don't know. - Jonathan M Davis
Sep 24 2012
On Monday, 24 September 2012 at 07:51:23 UTC, Jonathan M Davis wrote:On Monday, September 24, 2012 09:41:26 monarch_dodra wrote:Well, it does work... struct S { disable this(); } void foo(T)(T i) if ( is(T t)) {} void main() { //S s; //Fail S s = void; foo(s); //Works } I think it makes sense that it works, because "is" doesn't actually validate a compile time syntax, rather it is just declaring that "t can be used as an instance of T", but it is not actually declaring *the variable* "t" itself... Not sure I'm explaining myself. Or I think that's how it works. I've been on a wrong streak lately :/Regarding the ".init" issue, I hadn't thought of that, but it can be worked around pretty easily with an is(R r): -------- template Hello(R) if ( is(R r) && is(typeof(takeExactly(r, 1))) && is(R == typeof(takeExactly(r, 1))) ) { alias R Hello; } --------That was one trick that I was not aware of. I didn't think that one is expression could have an effect on a later one in the surrounding expression. Cool. Though I would point out that that probably doesn't avoid the init problem, because R r uses R.init (unless is expressions treat it differently, which they may). The normal way to avoid that is to do R r = void; but I don't think that that would work in that is expression. Sometimes disabling init is useful, but it can definitely be problematic. It may ultimately have been a mistake to allow it. I don't know. - Jonathan M Davis
Sep 24 2012
On Monday, September 24, 2012 10:02:54 monarch_dodra wrote:Well, it does work... struct S { disable this(); } void foo(T)(T i) if ( is(T t)) {} void main() { //S s; //Fail S s = void; foo(s); //Works } I think it makes sense that it works, because "is" doesn't actually validate a compile time syntax, rather it is just declaring that "t can be used as an instance of T", but it is not actually declaring *the variable* "t" itself... Not sure I'm explaining myself. Or I think that's how it works. I've been on a wrong streak lately :/disable this; is pretty broken, so I wouldn't really trust it at this point. http://d.puremagic.com/issues/show_bug.cgi?id=7021 But it wouldn't surprise if is expressions are supposed to act differently. is expressions are arguably too fancy for their own good (well, our good anyway). - Jonathan M Davis
Sep 24 2012
On 09/24/2012 09:41 AM, monarch_dodra wrote:... Regarding the ".init" issue, I hadn't thought of that, but it can be worked around pretty easily with an is(R r): -------- template Hello(R) if ( is(R r) && is(typeof(takeExactly(r, 1))) && is(R == typeof(takeExactly(r, 1))) ) { alias R Hello; } -------- After that, I guess it is indeed one implementation detail vs the other.I don't think this does what you think it does. The 'is(R r)' declares r to be an alias for R. So 'r' is a type in that code snippet. Also, is(typeof(takeExactly(R, 1))) && is(R == typeof(takeExactly(R, 1))) can be written in a more compact way as is(typeof(takeExactly(R, 1)) == R)IMO, it really depends on whether or not you'd want "int[]" to be considered the return type of a takeExactly :/ Maybe it is, maybe it ain't.
Sep 24 2012
On Monday, 24 September 2012 at 22:13:51 UTC, Timon Gehr wrote:On 09/24/2012 09:41 AM, monarch_dodra wrote:Darn :([SNIP]I don't think this does what you think it does. The 'is(R r)' declares r to be an alias for R. So 'r' is a type in that code snippet.Also, is(typeof(takeExactly(R, 1))) && is(R == typeof(takeExactly(R, 1))) can be written in a more compact way as is(typeof(takeExactly(R, 1)) == R)Technically, no: That was my first try, and as mentioned in the first reply, this returns true when the types of takeExactly and R are equal comparable, but does not make sure they are the actually the same types. "is(R == typeof(takeExactly(R, 1)))" Makes sure they are the exact same type, and "is(typeof(takeExactly(R, 1)))" is a short-circuit, to prevent the second test from error'ing if takeExactly!R is not legal.
Sep 24 2012
On 09/25/2012 08:41 AM, monarch_dodra wrote:On Monday, 24 September 2012 at 22:13:51 UTC, Timon Gehr wrote:I assume you messed up the parentheses. is(typeof(takeExactly(R, 1) == R)) // test for equal-comparable is(typeof(takeExactly(R, 1)) == R) // test for type identity alias float flt; static assert(is(typeof(1==flt))); static assert(!is(typeof(1)==flt));On 09/24/2012 09:41 AM, monarch_dodra wrote:Darn :([SNIP]I don't think this does what you think it does. The 'is(R r)' declares r to be an alias for R. So 'r' is a type in that code snippet.Also, is(typeof(takeExactly(R, 1))) && is(R == typeof(takeExactly(R, 1))) can be written in a more compact way as is(typeof(takeExactly(R, 1)) == R)Technically, no: That was my first try, and as mentioned in the first reply, this returns true when the types of takeExactly and R are equal comparable, but does not make sure they are the actually the same types. ...
Sep 26 2012
On Wednesday, 26 September 2012 at 13:19:13 UTC, Timon Gehr wrote:On 09/25/2012 08:41 AM, monarch_dodra wrote:Yes sorry. I miss read that. Kind of weird though, could you explain why: struct S{}; is(typeof(takeExactly(S, 1)) == S) //false is(S == typeof(takeExactly(S, 1))) //Error: template std.range.takeExactly does not match any function template declaration I was under the understanding that == was a commutative operation. Not the case in an is block?On Monday, 24 September 2012 at 22:13:51 UTC, Timon Gehr wrote:I assume you messed up the parentheses. is(typeof(takeExactly(R, 1) == R)) // test for equal-comparable is(typeof(takeExactly(R, 1)) == R) // test for type identity alias float flt; static assert(is(typeof(1==flt))); static assert(!is(typeof(1)==flt));On 09/24/2012 09:41 AM, monarch_dodra wrote:Darn :([SNIP]I don't think this does what you think it does. The 'is(R r)' declares r to be an alias for R. So 'r' is a type in that code snippet.Also, is(typeof(takeExactly(R, 1))) && is(R == typeof(takeExactly(R, 1))) can be written in a more compact way as is(typeof(takeExactly(R, 1)) == R)Technically, no: That was my first try, and as mentioned in the first reply, this returns true when the types of takeExactly and R are equal comparable, but does not make sure they are the actually the same types. ...
Sep 26 2012
On 09/26/2012 03:50 PM, monarch_dodra wrote:On Wednesday, 26 September 2012 at 13:19:13 UTC, Timon Gehr wrote:It is special syntax, not an == operator. is-expressions suppress errors in the first argument only.On 09/25/2012 08:41 AM, monarch_dodra wrote:Yes sorry. I miss read that. Kind of weird though, could you explain why: struct S{}; is(typeof(takeExactly(S, 1)) == S) //false is(S == typeof(takeExactly(S, 1))) //Error: template std.range.takeExactly does not match any function template declaration I was under the understanding that == was a commutative operation. Not the case in an is block?On Monday, 24 September 2012 at 22:13:51 UTC, Timon Gehr wrote:I assume you messed up the parentheses. is(typeof(takeExactly(R, 1) == R)) // test for equal-comparable is(typeof(takeExactly(R, 1)) == R) // test for type identity alias float flt; static assert(is(typeof(1==flt))); static assert(!is(typeof(1)==flt));On 09/24/2012 09:41 AM, monarch_dodra wrote:Darn :([SNIP]I don't think this does what you think it does. The 'is(R r)' declares r to be an alias for R. So 'r' is a type in that code snippet.Also, is(typeof(takeExactly(R, 1))) && is(R == typeof(takeExactly(R, 1))) can be written in a more compact way as is(typeof(takeExactly(R, 1)) == R)Technically, no: That was my first try, and as mentioned in the first reply, this returns true when the types of takeExactly and R are equal comparable, but does not make sure they are the actually the same types. ...
Sep 26 2012
On 9/26/12 9:50 AM, monarch_dodra wrote:struct S{}; is(typeof(takeExactly(S, 1)) == S) //false is(S == typeof(takeExactly(S, 1))) //Error: template std.range.takeExactly does not match any function template declarationNeither should work. The expression should be takeExactly(S.init, 1). Andrei
Sep 26 2012
On 09/26/2012 05:08 PM, Andrei Alexandrescu wrote:On 9/26/12 9:50 AM, monarch_dodra wrote:http://d.puremagic.com/issues/show_bug.cgi?id=8220 https://github.com/D-Programming-Language/dmd/pull/1007struct S{}; is(typeof(takeExactly(S, 1)) == S) //false is(S == typeof(takeExactly(S, 1))) //Error: template std.range.takeExactly does not match any function template declarationNeither should work. The expression should be takeExactly(S.init, 1). Andrei
Sep 26 2012
On Saturday, 22 September 2012 at 23:53:28 UTC, Jonathan M Davis wrote:I'm trying to test... [SNIP] - Jonathan M DavisI *kind of* see what you are doing with U, V, W, but what's wrong with just doing: ---- import std.range; template Hello(R) if(is(typeof(R == typeof(takeExactly(R, 1))))) { alias R Hello; } struct S; void main( ) { Hello!(int[]) a; //OK Hello!S b; //FAIL } ---- ? It seems to work for me..., but I'm not 100% sure there isn't something illegal/unsafe in there.
Sep 23 2012
On 09/23/2012 12:02 PM, monarch_dodra wrote:On Saturday, 22 September 2012 at 23:53:28 UTC, Jonathan M Davis wrote:The goal is to "test whether a template argument is the type returned by takeExactly." Your solution (I think) is looking at a container and determining whether the type of that container can be compared to the return type of takeExactly(). (Note that typeof(X == Y) is used for checking whether that expression itself is valid.) Also, I think your code should have passed a range like R.init to takeExactly, not R, which is a type: takeExactly(R.init, 1) I don't know why your code compiles. AliI'm trying to test... [SNIP] - Jonathan M DavisI *kind of* see what you are doing with U, V, W, but what's wrong with just doing: ---- import std.range; template Hello(R) if(is(typeof(R == typeof(takeExactly(R, 1))))) { alias R Hello; } struct S; void main( ) { Hello!(int[]) a; //OK Hello!S b; //FAIL } ---- ? It seems to work for me..., but I'm not 100% sure there isn't something illegal/unsafe in there.
Sep 23 2012
On Sunday, 23 September 2012 at 20:56:42 UTC, Ali Çehreli wrote:On 09/23/2012 12:02 PM, monarch_dodra wrote:Good point. My bad then.On Saturday, 22 September 2012 at 23:53:28 UTC, Jonathan MDavis wrote:wrong withI'm trying to test... [SNIP] - Jonathan M DavisI *kind of* see what you are doing with U, V, W, but what'sjust doing: ---- import std.range; template Hello(R) if(is(typeof(R == typeof(takeExactly(R, 1))))) { alias R Hello; } struct S; void main( ) { Hello!(int[]) a; //OK Hello!S b; //FAIL } ---- ? It seems to work for me..., but I'm not 100% sure there isn'tsomethingillegal/unsafe in there.The goal is to "test whether a template argument is the type returned by takeExactly." Your solution (I think) is looking at a container and determining whether the type of that container can be compared to the return type of takeExactly(). (Note that typeof(X == Y) is used for checking whether that expression itself is valid.)Also, I think your code should have passed a range like R.init to takeExactly, not R, which is a type: takeExactly(R.init, 1) I don't know why your code compiles.That did seem fishy to me too actually, but it does compile.AliIn that case, what about: -------- import std.range; template Hello(R) if(is(typeof(takeExactly(R.init, 1))) && is(R == typeof(takeExactly(R.init, 1)))) { alias R Hello; } struct S{}; void main( ) { Hello!(int[]) a; //OK Hello!S b; //FAIL (again) } -------
Sep 23 2012
On 09/23/2012 10:57 PM, Ali Çehreli wrote:... Also, I think your code should have passed a range like R.init to takeExactly, not R, which is a type: takeExactly(R.init, 1) I don't know why your code compiles.See discussion here: http://d.puremagic.com/issues/show_bug.cgi?id=8220
Sep 23 2012