Thread overview
Re: The is expression
Apr 02, 2011
Caligo
Apr 02, 2011
spir
Apr 02, 2011
enuhtac
Apr 02, 2011
enuhtac
Apr 03, 2011
Philippe Sigaud
Apr 05, 2011
enuhtac
Apr 10, 2011
David Nadlinger
Apr 05, 2011
Philippe Sigaud
April 02, 2011
On Fri, Apr 1, 2011 at 5:14 PM, enuhtac <enuhtac_lists@gmx.de> wrote:
> Hello,
>
> the "is" expression is a great feature of D - but its use is not very
> intuitive, at least for me.
> I'm trying to write a template that figures out if the template
> parameter is of a given type.
> This is the type I would like to check for:
>
> struct A( T, string s )
> { ... };
>
> One possibility to accomplish this check is explicit template specialization:
>
> template isA( T )
> {
>    enum bool isA = false;
> };
>
> template isA( T : A!( U, s ), U, string s )
> {
>    enum bool isA = true;
> };
>
> This more or less the C++ approach. But in D this could also be done with static if and the "is" expression. As I understand "is" it should be done like this:
>
> template isA( T )
> {
>    static if( is( T U == A!( U, s ), string s ) )
>        enum bool isA = true;
>    else
>        enum bool isA = false;
> };
>
> But this does not work. So what am I doing wrong?
>
> Regards,
> enuhtac
>
>

I'm new too, but I think it should be like this:

template isA( T ){

  enum bool isA = is(T : A)
}

if the name of enum is same as the template then you could use it as such:

if( isA( T ) ){ }

instead of

if( isA( T ).isA ){ }

Also note that : allows implicit conversion, while == requires the types to be exactly the same.
April 02, 2011
On 04/02/2011 12:14 AM, enuhtac wrote:
> template isA( T )
> {
>      static if( is( T U == A!( U, s ), string s ) )
>          enum bool isA = true;
>      else
>          enum bool isA = false;
> };

What does ", string s" do here inside the is expression?

Denis
-- 
_________________
vita es estrany
spir.wikidot.com

April 02, 2011
Am 02.04.2011 11:24, schrieb spir:
> On 04/02/2011 12:14 AM, enuhtac wrote:
>> template isA( T )
>> {
>>      static if( is( T U == A!( U, s ), string s ) )
>>          enum bool isA = true;
>>      else
>>          enum bool isA = false;
>> };
>
> What does ", string s" do here inside the is expression?
>
> Denis
A takes two template parameters: a type "T" and a value "string s". So I need to specify both parameters in the is expression. In the D manual you find something similar:

static if (is(int[10] W : W[V], int V))


April 02, 2011
Am 02.04.2011 04:00, schrieb Caligo:
> On Fri, Apr 1, 2011 at 5:14 PM, enuhtac <enuhtac_lists@gmx.de> wrote:
>> Hello,
>>
>> the "is" expression is a great feature of D - but its use is not very
>> intuitive, at least for me.
>> I'm trying to write a template that figures out if the template
>> parameter is of a given type.
>> This is the type I would like to check for:
>>
>> struct A( T, string s )
>> { ... };
>>
>> One possibility to accomplish this check is explicit template specialization:
>>
>> template isA( T )
>> {
>>    enum bool isA = false;
>> };
>>
>> template isA( T : A!( U, s ), U, string s )
>> {
>>    enum bool isA = true;
>> };
>>
>> This more or less the C++ approach. But in D this could also be done with static if and the "is" expression. As I understand "is" it should be done like this:
>>
>> template isA( T )
>> {
>>    static if( is( T U == A!( U, s ), string s ) )
>>        enum bool isA = true;
>>    else
>>        enum bool isA = false;
>> };
>>
>> But this does not work. So what am I doing wrong?
>>
>> Regards,
>> enuhtac
>>
>>
> I'm new too, but I think it should be like this:
>
> template isA( T ){
>
>   enum bool isA = is(T : A)
> }
>
> if the name of enum is same as the template then you could use it as such:
>
> if( isA( T ) ){ }
>
> instead of
>
> if( isA( T ).isA ){ }
>
> Also note that : allows implicit conversion, while == requires the types to be exactly the same.
Your right. In your example it is possible to circumvent the "static if"
construct. I was not aware of this, so thanks for the hint.
But in my case this does not work as I'm using the following "is" form:

*is (* /Type/ /Identifier/ *==* /TypeSpecialization/ *,*
/TemplateParameterList/ *)

*Obviously "is" forms that include an "Identifier" can only be used in
"static if" constructs. Actually I could do without the "Identifier" but
I need the "TemplateParameterList". But there is no "is" form where you
get a "TemplateParameterList" without an "Identifier".
Actually that would be nice as this would look like the explicit
specialization:

template isA( T )
{
   static if( is( T == A!( U, s ), U, string s ) )
       enum bool isA = true;
   else
       enum bool isA = false;
};

Or with your simplification:

template isA( T )
{
   enum bool isA = is( T == A!( U, s ), U, string s );
};


But this is not possible as the "Identifier" is missing.

So still I do not know what I'm doing wrong in my original code.


April 03, 2011
On Sat, Apr 2, 2011 at 13:05, enuhtac <enuhtac_lists@gmx.de> wrote:
> This is the type I would like to check for:
>
> struct A( T, string s )
> { ... };

Hi,

the trick is to use a function do the work for you. Let's define isAnA:

void isAnA(T, string s)( A!(T,s) a) { }

isAnA can only be called (compiled) with your A.

A!(int, "abc") a;
A!(double, "") b;

isAnA(a); // OK
isAnA(b); // OK
isAnA(123); // does not compile.

So you can nest it in a template and check at compile-time if it compiles:

template isMyA(Type)
{
    static if (__traits(compiles,
                        {
                            void isAnA(T, string s)(A!(T,s) a) {}
                            isAnA(Type.init); // create a value of
type Type, see if isAnA accepts it.
                        }))
        enum bool isMyA = true;
    else
        enum bool isMyA = false;
}

Note that this is strictly tailored to A's with (T, string s) as arguments. You can relax the constraints by adapting the test function.

For a more generic way to test for this, you can have a look there:

http://svn.dsource.org/projects/dranges/trunk/dranges/docs/templates.html
      ("isInstanceOf" and "Template ParametersTypeTuple")
http://svn.dsource.org/projects/dranges/trunk/dranges/docs/typepattern.html
     (look for "isA")


Philippe
April 05, 2011
Am 03.04.2011 16:11, schrieb Philippe Sigaud:
> On Sat, Apr 2, 2011 at 13:05, enuhtac <enuhtac_lists@gmx.de> wrote:
>> This is the type I would like to check for:
>>
>> struct A( T, string s )
>> { ... };
> Hi,
>
> the trick is to use a function do the work for you. Let's define isAnA:
>
> void isAnA(T, string s)( A!(T,s) a) { }
>
> isAnA can only be called (compiled) with your A.
>
> A!(int, "abc") a;
> A!(double, "") b;
>
> isAnA(a); // OK
> isAnA(b); // OK
> isAnA(123); // does not compile.
>
> So you can nest it in a template and check at compile-time if it compiles:
>
> template isMyA(Type)
> {
>     static if (__traits(compiles,
>                         {
>                             void isAnA(T, string s)(A!(T,s) a) {}
>                             isAnA(Type.init); // create a value of
> type Type, see if isAnA accepts it.
>                         }))
>         enum bool isMyA = true;
>     else
>         enum bool isMyA = false;
> }
>
> Note that this is strictly tailored to A's with (T, string s) as arguments. You can relax the constraints by adapting the test function.
>
> For a more generic way to test for this, you can have a look there:
>
> http://svn.dsource.org/projects/dranges/trunk/dranges/docs/templates.html
>       ("isInstanceOf" and "Template ParametersTypeTuple")
> http://svn.dsource.org/projects/dranges/trunk/dranges/docs/typepattern.html
>      (look for "isA")
>
>
> Philippe

Hi Philippe,

thanks for your answer. If it is that complicated if I prefer explicit specialization, I think. But I do not quite understand that it is not possible to achieve this with a simple "is" expression (without a function like "isAnA" and using "__traits") as the D language reference includes a very similiar example based on arrays:


  static if (is(int[10] W : W[V], int V))

what is the essential difference to:

    static if( is( A!(int, "xxx") T == A!(T, s), string s ) )

?

enuhtac
April 05, 2011
> thanks for your answer. If it is that complicated if I prefer explicit specialization, I think. But I do not quite understand that it is not possible to achieve this with a simple "is" expression (without a function like "isAnA" and using "__traits") as the D language reference includes a very similiar example based on arrays:
>
>
>  static if (is(int[10] W : W[V], int V))
>
> what is the essential difference to:
>
>    static if( is( A!(int, "xxx") T == A!(T, s), string s ) )

I don't know. Maybe the compiler knows about arrays and associated arrays, whereas it isn't smart enough to extract the correct information from a templated type? The is() expression was not developed from first principles: it grew 'organically' as a hodge-podge of tricks and needs.
April 10, 2011
On 4/5/11 12:21 PM, enuhtac wrote:
> […]
>    static if (is(int[10] W : W[V], int V))
>
> what is the essential difference to:
>
>      static if( is( A!(int, "xxx") T == A!(T, s), string s ) )

This is probably merely a bug, I just stumbled across something similar: http://d.puremagic.com/issues/show_bug.cgi?id=5830

David