digitalmars.D.learn - Understanding isInfinite(Range)
- Andrej Mitrovic <andrej.mitrovich test.com> Sep 03 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Sep 03 2010
- Andrej Mitrovic <andrej.mitrovich test.com> Sep 03 2010
- Peter Alexander <peter.alexander.au gmail.com> Sep 04 2010
- Pelle <pelle.mansson gmail.com> Sep 06 2010
- Andrej Mitrovic <andrej.mitrovich test.com> Sep 06 2010
- Stanislav Blinov <stanislav.blinov gmail.com> Sep 06 2010
- Andrej Mitrovic <andrej.mitrovich test.com> Sep 06 2010
- Andrej Mitrovic <andrej.mitrovich test.com> Sep 06 2010
- Stanislav Blinov <stanislav.blinov gmail.com> Sep 06 2010
- Stanislav Blinov <stanislav.blinov gmail.com> Sep 06 2010
- Andrej Mitrovic <andrej.mitrovich test.com> Sep 06 2010
- Stanislav Blinov <stanislav.blinov gmail.com> Sep 06 2010
- Andrej Mitrovic <andrej.mitrovich test.com> Sep 06 2010
- bearophile < bearophileHUGS lycos.com> Sep 06 2010
- Andrej Mitrovic <andrej.mitrovich test.com> Sep 06 2010
- Andrej Mitrovic <andrej.mitrovich test.com> Sep 06 2010
- Pelle <pelle.mansson gmail.com> Sep 07 2010
- Andrej Mitrovic <andrej.mitrovich test.com> Sep 06 2010
- Stanislav Blinov <stanislav.blinov gmail.com> Sep 06 2010
- Mafi <mafi example.org> Sep 06 2010
- Pelle <pelle.mansson gmail.com> Sep 06 2010
- Andrej Mitrovic <andrej.mitrovich test.com> Sep 06 2010
- bearophile < bearophileHUGS lycos.com> Sep 06 2010
- "Simen kjaeraas" <simen.kjaras gmail.com> Sep 04 2010
- Philippe Sigaud <philippe.sigaud gmail.com> Sep 06 2010
- Philippe Sigaud <philippe.sigaud gmail.com> Sep 06 2010
I was reading about the various range templates in std.range and I found this: http://www.digitalmars.com/d/2.0/phobos/std_range.html#isInfinite Seems simple enough. But I dont understand it's implementation, this from range.d: template isInfinite(Range) { static if (isInputRange!Range && is(char[1 + Range.empty])) enum bool isInfinite = !Range.empty; else enum bool isInfinite = false; } What does char[1 + Range.empty] do? It looks rather cryptic..
Sep 03 2010
On Fri, 03 Sep 2010 11:12:29 -0400, Andrej Mitrovic <andrej.mitrovich test.com> wrote:I was reading about the various range templates in std.range and I found this: http://www.digitalmars.com/d/2.0/phobos/std_range.html#isInfinite Seems simple enough. But I dont understand it's implementation, this from range.d: template isInfinite(Range) { static if (isInputRange!Range && is(char[1 + Range.empty])) enum bool isInfinite = !Range.empty; else enum bool isInfinite = false; } What does char[1 + Range.empty] do? It looks rather cryptic..
char[1+Range.empty] is a type. If Range.empty is a compile-time constant, then this type is valid, otherwise it's not valid (the is expression results to true if the argument is a valid type). If it's valid, then Range.empty never changes. If it never changes and it's always false, then it's infinite. -Steve
Sep 03 2010
Ah, you're right. Whenever I see the square brackets my brain automatically things "we're indexing something". I'll blame that on C. :p Thanks. Steven Schveighoffer Wrote:On Fri, 03 Sep 2010 11:12:29 -0400, Andrej Mitrovic <andrej.mitrovich test.com> wrote:I was reading about the various range templates in std.range and I found this: http://www.digitalmars.com/d/2.0/phobos/std_range.html#isInfinite Seems simple enough. But I dont understand it's implementation, this from range.d: template isInfinite(Range) { static if (isInputRange!Range && is(char[1 + Range.empty])) enum bool isInfinite = !Range.empty; else enum bool isInfinite = false; } What does char[1 + Range.empty] do? It looks rather cryptic..
char[1+Range.empty] is a type. If Range.empty is a compile-time constant, then this type is valid, otherwise it's not valid (the is expression results to true if the argument is a valid type). If it's valid, then Range.empty never changes. If it never changes and it's always false, then it's infinite. -Steve
Sep 03 2010
== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleOn Fri, 03 Sep 2010 11:12:29 -0400, Andrej Mitrovic <andrej.mitrovich test.com> wrote:What does char[1 + Range.empty] do? It looks rather cryptic..
then this type is valid, otherwise it's not valid (the is expression results to true if the argument is a valid type). If it's valid, then Range.empty never changes. If it never changes and it's always false, then it's infinite. -Steve
That's really ugly code :-( Is there a way you could write an isStatic(expr) template? Using something like that would make the code a hell of a lot more readable. At the moment, the code itself does a very poor job of conveying what it's trying to accomplish. These SFINAE-like tricks should be black-boxed as much as possible, or (at the very least) commented so that people know what's going on.
Sep 04 2010
On 09/04/2010 02:11 PM, Simen kjaeraas wrote:Peter Alexander <peter.alexander.au gmail.com> wrote:== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleOn Fri, 03 Sep 2010 11:12:29 -0400, Andrej Mitrovic <andrej.mitrovich test.com> wrote:What does char[1 + Range.empty] do? It looks rather cryptic..
constant, then this type is valid, otherwise it's not valid (the is expression results to true if the argument is a valid type). If it's valid, then Range.empty never changes. If it never changes and it's always false, then it's infinite. -Steve
That's really ugly code :-( Is there a way you could write an isStatic(expr) template? Using something like that would make the code a hell of a lot more readable. At the moment, the code itself does a very poor job of conveying what it's trying to accomplish. These SFINAE-like tricks should be black-boxed as much as possible, or (at the very least) commented so that people know what's going on.
template isStatic( alias T ) { enum isStatic = is( char[1+T] ); } unittest { int n = 3; assert( !isStatic!n ); assert( isStatic!1 ); enum r = 5; assert( isStatic!r ); }
enum s = "Hello"; assert (isStatic!s); Gonna need more work than that.
Sep 06 2010
Apparently I can't post to D.learn from gmail without waiting for a review?
What the..?
Anyway, I've posted this:
On a related note, I always wanted to make a template to replace the
dreaded is(typeof('delegate literal'())); calls.
For example, instead of this:
enum bool isInputRange = is(typeof(
{
R r; // can define a range object
if (r.empty) {} // can test for empty
r.popFront; // can invoke next
auto h = r.front; // can get the front of the range
}()));
We'd have a much cleaner call like so:
enum bool isInputRange = validate!(
{
R r; // can define a range object
if (r.empty) {} // can test for empty
r.popFront; // can invoke next
auto h = r.front; // can get the front of the range
});
But I haven't found a way to do it properly. If I call validate on a
type R range which doesn't feature the empty() method, then no matter
what the definition of validate is the compiler will error out because
it sees the call to r.empty() in the function literal, and 'r' doesn't
have an empty method.
Philippe Sigaud Wrote:
On Mon, Sep 6, 2010 at 18:47, Pelle <pelle.mansson gmail.com> wrote:
On 09/04/2010 02:11 PM, Simen kjaeraas wrote:
Is there a way you could write an isStatic(expr) template? Using
template isStatic( alias T ) {
enum isStatic = is( char[1+T] );
}
unittest {
int n = 3;
assert( !isStatic!n );
assert( isStatic!1 );
enum r = 5;
assert( isStatic!r );
}
enum s = "Hello";
assert (isStatic!s);
Gonna need more work than that.
Why? That's exactly the behavior we want, or so it seems to me.
<div class="gmail_quote">On Mon, Sep 6, 2010 at 18:47, Pelle <span
dir="ltr"><<a href="mailto:pelle.mansson gmail.com">pelle.mansson gmai
.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:
0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left:
1ex;">
<div><div></div><div class="h5">On 09/04/2010 02:11 PM, Simen kjaeraas
wrote:<br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left:
1px solid rgb(204, 204, 204); padding-left: 1ex;"><blockquote
class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid
rgb(204, 204, 204); padding-left: 1ex;">
Is there a way you could write an isStatic(expr) template?
Using<br></blockquote>
<br>
template isStatic( alias T ) {<br>
enum isStatic = is( char[1+T] );<br>
}<br>
<br>
unittest {<br>
int n = 3;<br>
assert( !isStatic!n );<br>
assert( isStatic!1 );<br>
enum r = 5;<br>
assert( isStatic!r );<br>
}<br>
</blockquote>
<br></div></div>
enum s = "Hello";<br>
<br>
assert (isStatic!s);<br>
<br>
Gonna need more work than that.<br>
</blockquote></div><br>Why? That's exactly the behavior we want, or so it
seems to me.<br><br><br>
Sep 06 2010
Andrej Mitrovic wrote:Apparently I can't post to D.learn from gmail without waiting for a review? What the..? Anyway, I've posted this: On a related note, I always wanted to make a template to replace the dreaded is(typeof('delegate literal'())); calls. For example, instead of this: enum bool isInputRange = is(typeof( { R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }())); We'd have a much cleaner call like so: enum bool isInputRange = validate!( { R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }); But I haven't found a way to do it properly. If I call validate on a type R range which doesn't feature the empty() method, then no matter what the definition of validate is the compiler will error out because it sees the call to r.empty() in the function literal, and 'r' doesn't have an empty method.
What about __traits(compiles) ?
Sep 06 2010
Yeah, that could work:
template isInputRange(R)
{
enum bool isInputRange = __traits(compiles,
{
R r; // can define a range object
if (r.empty) {} // can test for empty
r.popFront; // can invoke next
auto h = r.front; // can get the front of the range
});
}
It does look nice. It would look even nicer if __traits gets renamed to meta.
Stanislav Blinov Wrote:
What about __traits(compiles) ?
Sep 06 2010
I'd love to see this used more in Phobos. I don't know if there are any
drawbacks, but this looks and works nicely:
import std.stdio : writeln;
void main()
{
writeln(isInputRange!(N));
}
class N
{
N test;
bool empty()
{
return false;
}
property
void popFront()
{
}
property
N front()
{
return test;
}
}
template isInputRange(R)
{
enum bool isInputRange = __traits(compiles,
{
R r; // can define a range object
if (r.empty) {} // can test for empty
r.popFront; // can invoke next
auto h = r.front; // can get the front of the range
});
}
If you uncomment some of those methods in class N, then you get back false,
which is what you want. Currently isInputRange is defined like so in Phobos:
template isInputRange(R)
{
enum bool isInputRange = is(typeof(
{
R r; // can define a range object
if (r.empty) {} // can test for empty
r.popFront; // can invoke next
auto h = r.front; // can get the front of the range
}()));
}
It's getting close to LISP! :)
Andrej Mitrovic Wrote:
Yeah, that could work:
template isInputRange(R)
{
enum bool isInputRange = __traits(compiles,
{
R r; // can define a range object
if (r.empty) {} // can test for empty
r.popFront; // can invoke next
auto h = r.front; // can get the front of the range
});
}
It does look nice. It would look even nicer if __traits gets renamed to meta.
Stanislav Blinov Wrote:
What about __traits(compiles) ?
Sep 06 2010
Andrej Mitrovic wrote:I'd love to see this used more in Phobos. I don't know if there are any drawbacks, but this looks and works nicely: import std.stdio : writeln; void main() { writeln(isInputRange!(N)); } class N { N test; bool empty() { return false; } property void popFront() { } property N front() { return test; } } template isInputRange(R) { enum bool isInputRange = __traits(compiles, { R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }); } If you uncomment some of those methods in class N, then you get back false, which is what you want. Currently isInputRange is defined like so in Phobos: template isInputRange(R) { enum bool isInputRange = is(typeof( { R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }())); } It's getting close to LISP! :)
If I remember correctly, it has been discussed not long ago that those is(typeof(...))s should really be __traits(compiles). Maybe it's just some code was written before those lovely __traits were introduced?..
Sep 06 2010
Andrej Mitrovic wrote:It does look nice. It would look even nicer if __traits gets renamed to meta.
By the way, there's no stopping writing template isValidCode(alias code) { enum bool isValidCode = __traits(compiles, code); } :)
Sep 06 2010
That still won't work. Observe:
import std.stdio : writeln;
void main()
{
writeln(isInputRange!(N));
}
class N
{
N test;
//~ bool empty() // oops, we"re not an input range anymore
//~ {
//~ return false;
//~ }
property
void popFront()
{
}
property
N front()
{
return test;
}
}
template isInputRange(R)
{
enum bool isInputRange = isValidCode!(
{
R r; // can define a range object
if (r.empty) {} // can test for empty
r.popFront; // can invoke next
auto h = r.front; // can get the front of the range
});
}
template isValidCode(alias code) { enum bool isValidCode = __traits(compiles,
code); }
Instead of returning false, it will give out a compiler error.
Stanislav Blinov Wrote:
Andrej Mitrovic wrote:
It does look nice. It would look even nicer if __traits gets renamed to meta.
By the way, there's no stopping writing
template isValidCode(alias code) { enum bool isValidCode =
__traits(compiles, code); }
:)
Sep 06 2010
Andrej Mitrovic wrote:That still won't work. Observe:
Oops, sorry, I was too quick to conclude.
Sep 06 2010
I'm sorry, but what does q{..} mean?
Philippe Sigaud Wrote:
On Mon, Sep 6, 2010 at 23:31, Andrej Mitrovic <andrej.mitrovich test.com>wrote:
That still won't work. Observe:
template isInputRange(R)
{
enum bool isInputRange = isValidCode!(
{
R r; // can define a range object
if (r.empty) {} // can test for empty
r.popFront; // can invoke next
auto h = r.front; // can get the front of the range
});
}
template isValidCode(alias code) { enum bool isValidCode =
__traits(compiles, code); }
Instead of returning false, it will give out a compiler error.
That's because the part between the curly braces is evaluated before being
passed to the template. And there is no lazy alias.
As Mafi said, you can use a string, it's still the best way to move code
around in D. With q{ ... }, it's palatable.
And no, before you try it, there is no way to pass the {...} to another
template that would stringify it into a q{...} :-)
Maybe, eventually, something like this:
import std.stdio;
template isValidCode(alias code)
{
template For(T)
{
enum bool For = __traits(compiles, code(T.init));
}
}
void main()
{
// use an anonymous templated function:
alias isValidCode!((r)
{
if (r.empty) {} // can test for empty
r.popFront; // can invoke next
auto h = r.front; // c
}
) isInputRange;
// writeln(isInputRange.For!(int[]));
}
Except DMD doesn't like the commented-out line. Whaoh!
Philippe
Sep 06 2010
Andrej Mitrovic:I'm sorry, but what does q{..} mean?
q{} is just a different syntax to write "" or `` It's a controversial feature. q{} isn't recognized by editors as a string, so they colour the syntax it contains normally as code, and not as a string. So it's a bit useful if you want to give a string to a higher order function like map, instead of a delegate, and you want to keep the visual illusion of a delegate: map!q{a * a}([1, 2, 3]) The problem comes straight from its purpose: is that it doesn't look like a string, so its true nature is a bit hidden; and this may cause some troubles. Another possible problem was discussed when the q{} syntax was introduced. It's not a clean syntax, it's a hack from the point of view of parsing/lexing too. It's handy, but it may cause troubles too. I am getting used to it, but it's a untidy hack and it will keep being nothing more than a hack. And sometimes hacks later come back and bite your bum. Bye, bearophile
Sep 06 2010
Heh. I'd rather want text editors to use syntax highlighting on comments as well, but use a different background color. Then I would know it's a comment but it would also make any embedded code in the comment actually readable. bearophile < bearophileHUGS lycos.com> Wrote:Andrej Mitrovic:I'm sorry, but what does q{..} mean?
q{} is just a different syntax to write "" or `` It's a controversial feature. q{} isn't recognized by editors as a string, so they colour the syntax it contains normally as code, and not as a string. So it's a bit useful if you want to give a string to a higher order function like map, instead of a delegate, and you want to keep the visual illusion of a delegate: map!q{a * a}([1, 2, 3]) The problem comes straight from its purpose: is that it doesn't look like a string, so its true nature is a bit hidden; and this may cause some troubles. Another possible problem was discussed when the q{} syntax was introduced. It's not a clean syntax, it's a hack from the point of view of parsing/lexing too. It's handy, but it may cause troubles too. I am getting used to it, but it's a untidy hack and it will keep being nothing more than a hack. And sometimes hacks later come back and bite your bum. Bye, bearophile
Sep 06 2010
I meant string literals. But comments as well. Andrej Mitrovic Wrote:Heh. I'd rather want text editors to use syntax highlighting on comments as well, but use a different background color. Then I would know it's a comment but it would also make any embedded code in the comment actually readable. bearophile < bearophileHUGS lycos.com> Wrote:Andrej Mitrovic:I'm sorry, but what does q{..} mean?
q{} is just a different syntax to write "" or `` It's a controversial feature. q{} isn't recognized by editors as a string, so they colour the syntax it contains normally as code, and not as a string. So it's a bit useful if you want to give a string to a higher order function like map, instead of a delegate, and you want to keep the visual illusion of a delegate: map!q{a * a}([1, 2, 3]) The problem comes straight from its purpose: is that it doesn't look like a string, so its true nature is a bit hidden; and this may cause some troubles. Another possible problem was discussed when the q{} syntax was introduced. It's not a clean syntax, it's a hack from the point of view of parsing/lexing too. It's handy, but it may cause troubles too. I am getting used to it, but it's a untidy hack and it will keep being nothing more than a hack. And sometimes hacks later come back and bite your bum. Bye, bearophile
Sep 06 2010
On 09/07/2010 12:44 AM, bearophile wrote:Andrej Mitrovic:I'm sorry, but what does q{..} mean?
q{} is just a different syntax to write "" or `` It's a controversial feature. q{} isn't recognized by editors as a string, so they colour the syntax it contains normally as code, and not as a string. So it's a bit useful if you want to give a string to a higher order function like map, instead of a delegate, and you want to keep the visual illusion of a delegate: map!q{a * a}([1, 2, 3]) The problem comes straight from its purpose: is that it doesn't look like a string, so its true nature is a bit hidden; and this may cause some troubles. Another possible problem was discussed when the q{} syntax was introduced. It's not a clean syntax, it's a hack from the point of view of parsing/lexing too. It's handy, but it may cause troubles too. I am getting used to it, but it's a untidy hack and it will keep being nothing more than a hack. And sometimes hacks later come back and bite your bum. Bye, bearophile
It's not the same. Try q{\n}. It's lexed like code.
Sep 07 2010
is(typeof( is used a lot in Phobos. There's some ~260 calls like that, a quick search revealed. :p Stanislav Blinov Wrote:If I remember correctly, it has been discussed not long ago that those is(typeof(...))s should really be __traits(compiles). Maybe it's just some code was written before those lovely __traits were introduced?..
Sep 06 2010
Andrej Mitrovic wrote:is(typeof( is used a lot in Phobos. There's some ~260 calls like that, a quick search revealed. :p
Hush! You're spoiling it! It's a part of intergalactic obfuscation plot ;p
Sep 06 2010
Am 06.09.2010 21:24, schrieb Andrej Mitrovic:Apparently I can't post to D.learn from gmail without waiting for a review? What the..? Anyway, I've posted this: On a related note, I always wanted to make a template to replace the dreaded is(typeof('delegate literal'())); calls. For example, instead of this: enum bool isInputRange = is(typeof( { R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }())); We'd have a much cleaner call like so: enum bool isInputRange = validate!( { R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }); But I haven't found a way to do it properly. If I call validate on a type R range which doesn't feature the empty() method, then no matter what the definition of validate is the compiler will error out because it sees the call to r.empty() in the function literal, and 'r' doesn't have an empty method.
You could just let your template get a string. Then validate!q{....} should work. It looks almost exactly the same but has a 'q'. Maybe you could even create an template overload which gets delegate which has always failing static assert with message "you forget the 'q'" but I don't know if template initialization comes before semantic analisys so I'm not sure this will work. Mafi
Sep 06 2010
On 09/06/2010 08:53 PM, Philippe Sigaud wrote:On Mon, Sep 6, 2010 at 18:47, Pelle <pelle.mansson gmail.com <mailto:pelle.mansson gmail.com>> wrote: On 09/04/2010 02:11 PM, Simen kjaeraas wrote: Is there a way you could write an isStatic(expr) template? Using template isStatic( alias T ) { enum isStatic = is( char[1+T] ); } unittest { int n = 3; assert( !isStatic!n ); assert( isStatic!1 ); enum r = 5; assert( isStatic!r ); } enum s = "Hello"; assert (isStatic!s); Gonna need more work than that. Why? That's exactly the behavior we want, or so it seems to me.
Sorry if I was unclear, that assert fails. Due to that you cannot add an integer and a string, not not that the string isn't static. It's an enum, so it definitely is static.
Sep 06 2010
Is this legal?: enum a = "test"; a = "test2"; Because it seems to compile. But that shouldn't work afaik..? I can't reassign other enum types: enum b = 4; b = 5; // error which is expected. Pelle Wrote:On 09/06/2010 08:53 PM, Philippe Sigaud wrote:On Mon, Sep 6, 2010 at 18:47, Pelle <pelle.mansson gmail.com <mailto:pelle.mansson gmail.com>> wrote: On 09/04/2010 02:11 PM, Simen kjaeraas wrote: Is there a way you could write an isStatic(expr) template? Using template isStatic( alias T ) { enum isStatic = is( char[1+T] ); } unittest { int n = 3; assert( !isStatic!n ); assert( isStatic!1 ); enum r = 5; assert( isStatic!r ); } enum s = "Hello"; assert (isStatic!s); Gonna need more work than that. Why? That's exactly the behavior we want, or so it seems to me.
Sorry if I was unclear, that assert fails. Due to that you cannot add an integer and a string, not not that the string isn't static. It's an enum, so it definitely is static.
Sep 06 2010
Andrej Mitrovic:enum a = "test"; a = "test2"; Because it seems to compile. But that shouldn't work afaik..?
I have two open bug reports on this (and a third one was open by Don). Bye, bearophile
Sep 06 2010
Peter Alexander <peter.alexander.au gmail.com> wrote:== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleOn Fri, 03 Sep 2010 11:12:29 -0400, Andrej Mitrovic <andrej.mitrovich test.com> wrote:What does char[1 + Range.empty] do? It looks rather cryptic..
constant, then this type is valid, otherwise it's not valid (the is expression results to true if the argument is a valid type). If it's valid, then Range.empty never changes. If it never changes and it's always false, then it's infinite. -Steve
That's really ugly code :-( Is there a way you could write an isStatic(expr) template? Using something like that would make the code a hell of a lot more readable. At the moment, the code itself does a very poor job of conveying what it's trying to accomplish. These SFINAE-like tricks should be black-boxed as much as possible, or (at the very least) commented so that people know what's going on.
template isStatic( alias T ) { enum isStatic = is( char[1+T] ); } unittest { int n = 3; assert( !isStatic!n ); assert( isStatic!1 ); enum r = 5; assert( isStatic!r ); } -- Simen
Sep 04 2010
--0016e6dab373b4595d048f9bcb22 Content-Type: text/plain; charset=ISO-8859-1 On Mon, Sep 6, 2010 at 18:47, Pelle <pelle.mansson gmail.com> wrote:On 09/04/2010 02:11 PM, Simen kjaeraas wrote:Is there a way you could write an isStatic(expr) template? Using
template isStatic( alias T ) { enum isStatic = is( char[1+T] ); } unittest { int n = 3; assert( !isStatic!n ); assert( isStatic!1 ); enum r = 5; assert( isStatic!r ); }
enum s = "Hello"; assert (isStatic!s); Gonna need more work than that.
Why? That's exactly the behavior we want, or so it seems to me. --0016e6dab373b4595d048f9bcb22 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On Mon, Sep 6, 2010 at 18:47, Pelle <span dir=3D= "ltr"><<a href=3D"mailto:pelle.mansson gmail.com">pelle.mansson gmail.co= m</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi= n: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-le= ft: 1ex;"> <div><div></div><div class=3D"h5">On 09/04/2010 02:11 PM, Simen kjaeraas wr= ote:<br> <blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; borde= r-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><blockquote class= =3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid= rgb(204, 204, 204); padding-left: 1ex;"> Is there a way you could write an isStatic(expr) template? Using<br></block= quote> <br> template isStatic( alias T ) {<br> enum isStatic =3D is( char[1+T] );<br> }<br> <br> unittest {<br> int n =3D 3;<br> assert( !isStatic!n );<br> assert( isStatic!1 );<br> enum r =3D 5;<br> assert( isStatic!r );<br> }<br> </blockquote> <br></div></div> enum s =3D "Hello";<br> <br> assert (isStatic!s);<br> <br> Gonna need more work than that.<br> </blockquote></div><br>Why? That's exactly the behavior we want, or so = it seems to me.<br><br><br> --0016e6dab373b4595d048f9bcb22--
Sep 06 2010
--0016e6d9776fa86220048f9e5e31 Content-Type: text/plain; charset=ISO-8859-1 On Mon, Sep 6, 2010 at 23:31, Andrej Mitrovic <andrej.mitrovich test.com>wrote:That still won't work. Observe:
template isInputRange(R) { enum bool isInputRange = isValidCode!( { R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }); } template isValidCode(alias code) { enum bool isValidCode = __traits(compiles, code); } Instead of returning false, it will give out a compiler error.
That's because the part between the curly braces is evaluated before being passed to the template. And there is no lazy alias. As Mafi said, you can use a string, it's still the best way to move code around in D. With q{ ... }, it's palatable. And no, before you try it, there is no way to pass the {...} to another template that would stringify it into a q{...} :-) Maybe, eventually, something like this: import std.stdio; template isValidCode(alias code) { template For(T) { enum bool For = __traits(compiles, code(T.init)); } } void main() { // use an anonymous templated function: alias isValidCode!((r) { if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // c } ) isInputRange; // writeln(isInputRange.For!(int[])); } Except DMD doesn't like the commented-out line. Whaoh! Philippe --0016e6d9776fa86220048f9e5e31 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On Mon, Sep 6, 2010 at 23:31, Andrej Mitrovic <s= pan dir=3D"ltr"><<a href=3D"mailto:andrej.mitrovich test.com">andrej.mit= rovich test.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" = style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 20= 4); padding-left: 1ex;"> That still won't work. Observe:</blockquote><div>=A0</div><blockquote c= lass=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px s= olid rgb(204, 204, 204); padding-left: 1ex;">template isInputRange(R)<br><d= iv class=3D"im"> {<br> </div> =A0 =A0enum bool isInputRange =3D isValidCode!(<br> <div class=3D"im"> =A0 =A0{<br> =A0 =A0 =A0 =A0R r; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0// can define a range o= bject<br> =A0 =A0 =A0 =A0if (r.empty) {} =A0 =A0 // can test for empty<br> =A0 =A0 =A0 =A0r.popFront; =A0 =A0 =A0 =A0 // can invoke next<br> =A0 =A0 =A0 =A0auto h =3D r.front; =A0 // can get the front of the range<b= r> =A0 =A0});<br> }<br> <br> </div><div class=3D"im">template isValidCode(alias code) { enum bool isVali= dCode =3D __traits(compiles, code); }<br> <br> </div>Instead of returning false, it will give out a compiler error.<br></b= lockquote><div><br>That's because the part between the curly braces is = evaluated before being passed to the template. And there is no lazy alias.<= br> As Mafi said, you can use a string, it's still the best way to move cod= e around in D. With q{ ... }, it's palatable.<br>And no, before you try= it, there is no way to pass the {...} to another template that would strin= gify it into a q{...} :-)<br> <br>Maybe, eventually, something like this:<br><br>import std.stdio;<br><br=<br>template isValidCode(alias code)<br>{<br>=A0=A0=A0 template For(T)<br>=
ode(T.init));<br>=A0=A0=A0 }<br> }<br><br>void main()<br>{<br>=A0=A0 // use an anonymous templated function:= <br>alias isValidCode!((r)<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (r.empty) {}=A0=A0=A0=A0 // can tes= t for empty<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0 r.popFront;=A0=A0=A0=A0=A0=A0=A0=A0 // can invoke nex= t<br> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 auto h =3D r.front;=A0=A0 // c<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 }<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0 ) isInputRange;<br><br>//=A0=A0=A0 writeln(isInput= Range.For!(int[]));<br>}<br><br>Except DMD doesn't like the commented-o= ut line. Whaoh!<br> <br><br><br>Philippe<br><br></div></div> --0016e6d9776fa86220048f9e5e31--
Sep 06 2010









Andrej Mitrovic <andrej.mitrovich test.com> 