www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Compiler complaining about code that can't be reached, builtin types

reply "Sean Grimes" <spg63 cs.drexel.edu> writes:
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
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
parent "Sean Grimes" <spg63 cs.drexel.edu> writes:
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);
 }

 Ali
Ali, Thanks that works for me. - Sean
Jun 25 2015