## digitalmars.D.learn - Understanding isInfinite(Range)

Andrej Mitrovic <andrej.mitrovich test.com> writes:
```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
"Steven Schveighoffer" <schveiguy yahoo.com> writes:
```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
Andrej Mitrovic <andrej.mitrovich test.com> writes:
```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
Peter Alexander <peter.alexander.au gmail.com> writes:
```== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s article
On 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
Pelle <pelle.mansson gmail.com> writes:
```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 article
On 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
Andrej Mitrovic <andrej.mitrovich test.com> writes:
```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

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">&lt;<a href="mailto:pelle.mansson gmail.com">pelle.mansson gmai
.com</a>&gt;</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

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 = &quot;Hello&quot;;<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
Stanislav Blinov <stanislav.blinov gmail.com> writes:
```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

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.

```
Sep 06 2010
Andrej Mitrovic <andrej.mitrovich test.com> writes:
```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:

```
Sep 06 2010
Andrej Mitrovic <andrej.mitrovich test.com> writes:
```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:

```
Sep 06 2010
Stanislav Blinov <stanislav.blinov gmail.com> writes:
```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
Stanislav Blinov <stanislav.blinov gmail.com> writes:
```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 <andrej.mitrovich test.com> writes:
```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
Stanislav Blinov <stanislav.blinov gmail.com> writes:
```Andrej Mitrovic wrote:
That still won't work. Observe:

Oops, sorry, I was too quick to conclude.
```
Sep 06 2010
Andrej Mitrovic <andrej.mitrovich test.com> writes:
```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
bearophile < bearophileHUGS lycos.com> writes:
```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
Andrej Mitrovic <andrej.mitrovich test.com> writes:
```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
Andrej Mitrovic <andrej.mitrovich test.com> writes:
```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
Pelle <pelle.mansson gmail.com> writes:
```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
Andrej Mitrovic <andrej.mitrovich test.com> writes:
```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
Stanislav Blinov <stanislav.blinov gmail.com> writes:
```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
Mafi <mafi example.org> writes:
```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

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
Pelle <pelle.mansson gmail.com> writes:
```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 <andrej.mitrovich test.com> writes:
```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
bearophile < bearophileHUGS lycos.com> writes:
```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
"Simen kjaeraas" <simen.kjaras gmail.com> writes:
```Peter Alexander <peter.alexander.au gmail.com> wrote:

== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s article
On 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
Philippe Sigaud <philippe.sigaud gmail.com> writes:
```--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">&lt;<a href=3D"mailto:pelle.mansson gmail.com">pelle.mansson gmail.co=
m</a>&gt;</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=

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 &quot;Hello&quot;;<br>
<br>
assert (isStatic!s);<br>
<br>
Gonna need more work than that.<br>
</blockquote></div><br>Why? That&#39;s exactly the behavior we want, or so =
it seems to me.<br><br><br>

--0016e6dab373b4595d048f9bcb22--
```
Sep 06 2010
Philippe Sigaud <philippe.sigaud gmail.com> writes:
```--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">&lt;<a href=3D"mailto:andrej.mitrovich test.com">andrej.mit=
rovich test.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" =
style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 20=
That still won&#39;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&#39;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&#39;s still the best way to move cod=
e around in D. With q{ ... }, it&#39;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&#39;t like the commented-o=
ut line. Whaoh!<br>
<br><br><br>Philippe<br><br></div></div>

--0016e6d9776fa86220048f9e5e31--
```
Sep 06 2010