digitalmars.D.learn - Compiler complaining about code that can't be reached, builtin types
- Sean Grimes (43/43) Jun 25 2015 I have a method, containsValue() in a class similar to
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (37/49) Jun 25 2015 That is a run-time conditional. There is no guarantee for the compiler
- Sean Grimes (4/33) Jun 25 2015 Ali,
I have a method, containsValue() in a class similar to java.util.HashMap. The class is a template class, instantiated with 2 parameters, K key, V value. bool containsValue(V value){ // dlang associative array, .values returns dynamic array of values in the aa auto values = this.internal_arr.values; /* * isBuiltIn() checks against all the builtin types in D * returns true if value instantiated as int, double, immutable(char)[] etc... * returns false iff value is a user defined object */ if(!isBuiltIn(value)){ foreach(val; values){ if(val.equals(value)) return true; } } // isBuiltin() false, assume builtin type, use "==" for comparison else{ foreach(val; values){ if(val == value) return true; } } return false; } The problem I'm having is using a D builtin type for the value parameter. The compiler tells me "no property 'equals' for type 'string'" in the containsValue() method. Well that's well and good, but I already know that which is why I check if the class has been instantiated with a builtin type or a user defined type. My question: Is there any way around the compiler complaining about this? The code doesn't allow (as best I can tell) the .equals() method to be called when "value" is a builtin type, so why does the compiler still complain? As a side note, I couldn't get std.traits.isBuiltinType(T) to work, so the function isBuiltIn() is not just calling std.traits.isBuiltinType(T), it's checking the typeid(value) against D builtin typeids.
Jun 25 2015
On 06/25/2015 11:26 AM, Sean Grimes wrote:/* * isBuiltIn() checks against all the builtin types in D * returns true if value instantiated as int, double, immutable(char)[] etc... * returns false iff value is a user defined object */ if(!isBuiltIn(value)){ foreach(val; values){ if(val.equals(value)) return true; } }That is a run-time conditional. There is no guarantee for the compiler that isBuiltIn() will return 'true' for every 'value'. For example, it can return 'false' for 42 but 'true' for 43. To enable or disable code sections you can use 'static if'. However, isBuiltIn must be evaluable at compile time as well. Since isBuiltIn works with values (not types) in your case, you can't pass it to 'static if': static if (!isBuiltIn(value)) { // <-- compilation error You want isBuiltIn to be a template which works on a type (V in your case). Here is a short example which treats 'int' and 'double' as built-in only: import std.typetuple; bool isBuiltIn(T)() { foreach (T2; TypeTuple!(int, double/*, ... */)) { if (is (T2 == T)) { return true; } } return false; } struct S(V) { void foo(V v) { static if (!isBuiltIn!V) { /* Assumes that non-built-ins support bar(). */ v.bar(); } } } void main() { auto s = S!int(); s.foo(42); } Ali
Jun 25 2015
On Thursday, 25 June 2015 at 18:43:31 UTC, Ali Çehreli wrote:On 06/25/2015 11:26 AM, Sean Grimes wrote: Here is a short example which treats 'int' and 'double' as built-in only: import std.typetuple; bool isBuiltIn(T)() { foreach (T2; TypeTuple!(int, double/*, ... */)) { if (is (T2 == T)) { return true; } } return false; } struct S(V) { void foo(V v) { static if (!isBuiltIn!V) { /* Assumes that non-built-ins support bar(). */ v.bar(); } } } void main() { auto s = S!int(); s.foo(42); } AliAli, Thanks that works for me. - Sean
Jun 25 2015