Thread overview | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 22, 2012 Testing for template argument being result of takeExactly | ||||
---|---|---|---|---|
| ||||
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 |
September 23, 2012 Re: Testing for template argument being result of takeExactly | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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
|
September 23, 2012 Re: Testing for template argument being result of takeExactly | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Sunday, September 23, 2012 02:57:36 bearophile wrote: > 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. 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. > 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 |
September 23, 2012 Re: Testing for template argument being result of takeExactly | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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 Davis > import 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); } |
September 23, 2012 Re: Testing for template argument being result of takeExactly | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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
|
September 23, 2012 Re: Testing for template argument being result of takeExactly | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 09/23/2012 03:48 PM, Andrei Alexandrescu wrote: > 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. 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. > Regarding availability of "_input", I meant to make > it available systematically as "input" for ranges where the notion makes > sense. > > Andrei This seems to be reasonable. |
September 23, 2012 Re: Testing for template argument being result of takeExactly | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Saturday, 22 September 2012 at 23:53:28 UTC, Jonathan M Davis wrote:
> I'm trying to test...
> [SNIP]
> - Jonathan M Davis
I *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.
|
September 23, 2012 Re: Testing for template argument being result of takeExactly | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 09/23/2012 12:02 PM, monarch_dodra wrote: > On Saturday, 22 September 2012 at 23:53:28 UTC, Jonathan M Davis wrote: >> I'm trying to test... >> [SNIP] >> - Jonathan M Davis > > I *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. 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. Ali |
September 23, 2012 Re: Testing for template argument being result of takeExactly | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Sunday, 23 September 2012 at 20:56:42 UTC, Ali Çehreli wrote: > On 09/23/2012 12:02 PM, monarch_dodra wrote: > > On Saturday, 22 September 2012 at 23:53:28 UTC, Jonathan M > Davis wrote: > >> I'm trying to test... > >> [SNIP] > >> - Jonathan M Davis > > > > I *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. > > 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.) Good point. My bad then. > 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. > Ali In 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) } ------- |
September 23, 2012 Re: Testing for template argument being result of takeExactly | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 |
Copyright © 1999-2021 by the D Language Foundation