www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - A couple of questions

reply Sam Hu <samhudotsamhu gmail.com> writes:
Hello,

For the given example below,

E1:
template Chain(R...) if (allSatisfy!(isInputRange, R))
{
    static if (R.length > 1)
        alias ChainImpl!(R) Chain;
    else
        alias R[0] Chain;
}
Q1: What's *if* statement doing right after the template definite?I can guess
what the purpose is but I can not find the answer from the spec.

E2:
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
    }()));
}

Q2:What's the logic inside the enum...{} blocks?
Q3:The *typeof* expression here. is it an anonymous function/delegate which
return a bool value?If not,how come there is a () pairs appeared right after
the enum{}blocks?If yes,shouldn't the () pairs appear before the last *)* ?

It would be grateful if anybody can help.

Regards,
Sam
May 12 2009
parent reply BCS <none anon.com> writes:
Hello Sam,

 Hello,
 
 For the given example below,
 
 E1:
 template Chain(R...) if (allSatisfy!(isInputRange, R))
 {
 static if (R.length > 1)
 alias ChainImpl!(R) Chain;
 else
 alias R[0] Chain;
 }
 Q1: What's *if* statement doing right after the template definite?I
 can guess what the purpose is but I can not find the answer from the
 spec.
 
 E2:
 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
 }()));
 }
 Q2:What's the logic inside the enum...{} blocks?
That is an odd construct and not an enum block, breaking it into pieces: enum bool isInputRange = SomeBoolExp; SomeBoolExp: // true if SomeExp is a valid expression is(typeof(SomeExp)) SomeExp: // a function call SomeFnExp() SomeFnExp: // a delegate literal { 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 }
 Q3:The *typeof* expression here. is it an anonymous function/delegate
 which return a bool value?If not,how come there is a () pairs appeared
 right after the enum{}blocks?If yes,shouldn't the () pairs appear
 before the last *)* ?
 It would be grateful if anybody can help.
see above
 
 Regards,
 Sam
May 12 2009
parent reply Sam Hu <samhudotsamhu gmail.com> writes:
Thanks.The construct is clear now.

Still leaves Q1,that is ,the *if* expression after the template definition,I
want to learn more about the usage,where can I find more information?

and one more question here:
Q4.In the delegate somFnExp:front(),popFront,empty() are all not
defined??Anyway it is not an interface ,so why it is allowed?

Thanks for help.
Sam
May 13 2009
next sibling parent John C <johnch_atms hotmail.com> writes:
Sam Hu Wrote:

 Thanks.The construct is clear now.
 
 Still leaves Q1,that is ,the *if* expression after the template definition,I
want to learn more about the usage,where can I find more information?
It is in the spec: http://www.digitalmars.com/d/2.0/template.html#Constraint
May 13 2009
prev sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
Sam Huwrote:

 Q4.In the delegate somFnExp:front(),popFront,empty() are all not  
 defined??Anyway it is not an interface ,so why it is allowed?
Basically, is(typeof(X)) is D magic. One could interpret it as 'is X a valid type', or perhaps more correctly as 'does X compile'. So if SomeFnExp does something it is not allowed to (e.g. call popFront on something that has no popFront), it will return false. If I were to write this code without is(typeof()) around it: R r; if (r.empty) {} r.popFront; auto h = r.front; It might seem a strange piece of code, but there is nothing inherently wrong with it. empty, popFront and front are expected members of R, and will give a compilation error if R does not follow the interface (note: not as in a D interface, but as in exposing the correct functions to the outside world). -- Simen
May 13 2009
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Simen Kjaeraas wrote:
 Sam Huwrote:
 
 Q4.In the delegate somFnExp:front(),popFront,empty() are all not 
 defined??Anyway it is not an interface ,so why it is allowed?
Basically, is(typeof(X)) is D magic. One could interpret it as 'is X a valid type', or perhaps more correctly as 'does X compile'. So if SomeFnExp does something it is not allowed to (e.g. call popFront on something that has no popFront), it will return false. If I were to write this code without is(typeof()) around it: R r; if (r.empty) {} r.popFront; auto h = r.front; It might seem a strange piece of code, but there is nothing inherently wrong with it. empty, popFront and front are expected members of R, and will give a compilation error if R does not follow the interface (note: not as in a D interface, but as in exposing the correct functions to the outside world). -- Simen
IOW, is(typeof({ XXXXXX }()) Evaluates to a boolean meaning "does a function containing XXXXXX compile". Its purpose here is to find out if r has "empty", "popFront" and "front". This is placed inside a template that has one member that is the name of the template, so it ends up that: isInputRange!(R) just becomes a boolean that's true if R has "empty", "popFront", and "front", and false if it doesn't. ... C++ template hacks are worse. Really. Usually.
May 13 2009
parent Sam Hu <samhudotsamhu gmail.com> writes:
Hi All,

Thank you so much! It really helps!

Regards,
Sam
May 13 2009