Thread overview
Conditional compilation on availability?
Jul 08, 2006
Fredrik Olsson
Jul 08, 2006
Kirk McDonald
Jul 09, 2006
Bruno Medeiros
Jul 09, 2006
Fredrik Olsson
Jul 09, 2006
Tom S
Jul 08, 2006
Tom S
July 08, 2006
Might be an easy one, or a missing feature :).

But how do I do a conditional compilation on the availability of a function, variable, type or whatever?

For example:

class foo(T) {
 T[] bar;
  static if ("predicate for toString(T) exists") {
    char[] allBarsConcatinatedAsString() {
      char[] r = ""
      foreach (v; bar) {
	r ~= toString(v);
      }
    }
  }
}

What would I type instead of "predicate for toString(T) exists"?

// Fredrik
July 08, 2006
Fredrik Olsson wrote:
> Might be an easy one, or a missing feature :).
> 
> But how do I do a conditional compilation on the availability of a function, variable, type or whatever?
> 
> For example:
> 
> class foo(T) {
>  T[] bar;
>   static if ("predicate for toString(T) exists") {
>     char[] allBarsConcatinatedAsString() {
>       char[] r = ""
>       foreach (v; bar) {
>     r ~= toString(v);
>       }
>     }
>   }
> }
> 
> What would I type instead of "predicate for toString(T) exists"?
> 
> // Fredrik

class foo(T) {
    static if (is(typeof(toString(T.init)))) {
        // ...
    }
}

The IsExpression tests whether a given type is valid. typeof gets the type of a given expression. Thus, you can use one inside the other to test whether a given expression exists. Additionally, the expression inside of typeof is not actually executed, so it's safe to "call" the function like this.

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://dsource.org/projects/pyd/wiki
July 08, 2006
Fredrik Olsson wrote:
> Might be an easy one, or a missing feature :).
> 
> But how do I do a conditional compilation on the availability of a function, variable, type or whatever?
> 
> For example:
> 
> class foo(T) {
>  T[] bar;
>   static if ("predicate for toString(T) exists") {
>     char[] allBarsConcatinatedAsString() {
>       char[] r = ""
>       foreach (v; bar) {
>     r ~= toString(v);
>       }
>     }
>   }
> }
> 
> What would I type instead of "predicate for toString(T) exists"?
> 
> // Fredrik

The following seems to do the trick:



import std.string;


class foo(T) {
 T[] bar;
  static if (is(typeof(.toString(bar[0])))) {
    char[] allBarsConcatinatedAsString() {
      char[] r = "";
      foreach (v; bar) {
		  r ~= .toString(v);
      }
	  return r;
    }
  }
}



void main() {
	auto a = new foo!(int);
	a.allBarsConcatinatedAsString();

	struct Blah {}
	auto b = new foo!(Blah);
	//b.allBarsConcatinatedAsString();
}



-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
July 09, 2006
Kirk McDonald wrote:
> Fredrik Olsson wrote:
>> Might be an easy one, or a missing feature :).
>>
>> But how do I do a conditional compilation on the availability of a function, variable, type or whatever?
>>
>> For example:
>>
>> class foo(T) {
>>  T[] bar;
>>   static if ("predicate for toString(T) exists") {
>>     char[] allBarsConcatinatedAsString() {
>>       char[] r = ""
>>       foreach (v; bar) {
>>     r ~= toString(v);
>>       }
>>     }
>>   }
>> }
>>
>> What would I type instead of "predicate for toString(T) exists"?
>>
>> // Fredrik
> 
> class foo(T) {
>     static if (is(typeof(toString(T.init)))) {
>         // ...
>     }
> }
> 
> The IsExpression tests whether a given type is valid. typeof gets the type of a given expression. Thus, you can use one inside the other to test whether a given expression exists. Additionally, the expression inside of typeof is not actually executed, so it's safe to "call" the function like this.
> 

Note that that doesn't work if T is a static array, since
typeof(T) != typeof(T.init) but instead typeof(T.init) == typeof(*T) (which is viewed by some of us as a nasty inconsistency).
Best to do as in Tom's example.


-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
July 09, 2006
Bruno Medeiros skrev:
> Kirk McDonald wrote:
> 
>> Fredrik Olsson wrote:
>>
>>> Might be an easy one, or a missing feature :).
>>>
>>> But how do I do a conditional compilation on the availability of a function, variable, type or whatever?
>>>
>>> For example:
>>>
>>> class foo(T) {
>>>  T[] bar;
>>>   static if ("predicate for toString(T) exists") {
>>>     char[] allBarsConcatinatedAsString() {
>>>       char[] r = ""
>>>       foreach (v; bar) {
>>>     r ~= toString(v);
>>>       }
>>>     }
>>>   }
>>> }
>>>
>>> What would I type instead of "predicate for toString(T) exists"?
>>>
>>> // Fredrik
>>
>>
>> class foo(T) {
>>     static if (is(typeof(toString(T.init)))) {
>>         // ...
>>     }
>> }
>>
>> The IsExpression tests whether a given type is valid. typeof gets the type of a given expression. Thus, you can use one inside the other to test whether a given expression exists. Additionally, the expression inside of typeof is not actually executed, so it's safe to "call" the function like this.
>>
> 
> Note that that doesn't work if T is a static array, since
> typeof(T) != typeof(T.init) but instead typeof(T.init) == typeof(*T) (which is viewed by some of us as a nasty inconsistency).
> Best to do as in Tom's example.
> 
> 

Thanks Kirk, Tom and Bruno. I got it too work.

But for a more general case perhaps:
static if(expression) should yield false if expression is false, _or_ if the expression can not be resolved. So that for example these could work:
static if (toString(int)) { /* jupp std.strings probably imported */ }
static if (T.nan) { /* Would seem we have a float */ }
etc.

But that is just wishes.

// Fredrik
July 09, 2006
Fredrik Olsson wrote:
> But for a more general case perhaps:
> static if(expression) should yield false if expression is false, _or_ if the expression can not be resolved. So that for example these could work:
> static if (toString(int)) { /* jupp std.strings probably imported */ }
> static if (T.nan) { /* Would seem we have a float */ }
> etc.
> 
> But that is just wishes.

I'd be against it. At first it looks like a cool idea, until you think about modifying existing code. Say, you statically check some condition in your code, e.g. 'static if (foo.bar > 10)'. Then after a few committee meetings, it's decided that 'bar' should be renamed to 'baz'. So you get to work to change all 'bar' occurrences to 'baz'. But if you miss one... then 'static if (foo.bar > 10)' would always be false. An error should be triggered in that case IMO.

You can still do these tests by using the 'static if (is(typeof()))' combo.


-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/