Thread overview | |||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 03, 2010 Understanding isInfinite(Range) | ||||
---|---|---|---|---|
| ||||
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.. |
September 03, 2010 Re: Understanding isInfinite(Range) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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
|
September 03, 2010 Re: Understanding isInfinite(Range) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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
|
September 04, 2010 Re: Understanding isInfinite(Range) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | == 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..
> 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
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.
|
September 04, 2010 Re: Understanding isInfinite(Range) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | 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.. >> 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 > > 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 |
September 06, 2010 Re: Understanding isInfinite(Range) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | 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..
>>> 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
>>
>> 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.
|
September 06, 2010 Re: Understanding isInfinite(Range) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pelle Attachments:
| 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.
|
September 06, 2010 Re: Understanding isInfinite(Range) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | 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@gmail.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>
>
|
September 06, 2010 Re: Understanding isInfinite(Range) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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) ?
|
September 06, 2010 Re: Understanding isInfinite(Range) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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
|
Copyright © 1999-2021 by the D Language Foundation