changeset 195:a4d38d47ddc4

HashMap support for null values and keys
author Frank Benoit <benoit@tionex.de>
date Tue, 03 Feb 2009 16:08:10 +0100
parents 6d35b9960800
children 66bceed20048
files dwtx/dwtxhelper/Collection.d
diffstat 1 files changed, 78 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/dwtx/dwtxhelper/Collection.d	Sun Feb 01 19:41:13 2009 +0100
+++ b/dwtx/dwtxhelper/Collection.d	Tue Feb 03 16:08:10 2009 +0100
@@ -200,56 +200,70 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-    class MapEntry : Map.Entry {
-        Map map;
-        Object key;
-        private this( Map map, Object key){
-            this.map = map;
-            this.key = key;
-        }
-        public override int opEquals(Object o){
-            if( auto other = cast(MapEntry)o){
+class MapEntry : Map.Entry {
+    Map map;
+    Object key;
+    private this( Map map, Object key){
+        this.map = map;
+        this.key = key;
+    }
+    public override int opEquals(Object o){
+        if( auto other = cast(MapEntry)o){
 
-                if(( getKey() is null ? other.getKey() is null : getKey() == other.getKey() )  &&
-                   ( getValue() is null ? other.getValue() is null : getValue() == other.getValue() )){
-                    return true;
-                }
-                return false;
+            if(( getKey() is null ? other.getKey() is null : getKey() == other.getKey() )  &&
+               ( getValue() is null ? other.getValue() is null : getValue() == other.getValue() )){
+                return true;
             }
             return false;
         }
-        public Object getKey(){
-            return key;
-        }
-        public Object getValue(){
-            return map.get(key);
-        }
-        public override hash_t toHash(){
-            return ( getKey()   is null ? 0 : getKey().toHash()   ) ^
-                   ( getValue() is null ? 0 : getValue().toHash() );
-        }
-        public Object     setValue(Object value){
-            return map.put( key, value );
-        }
-
+        return false;
+    }
+    public Object getKey(){
+        return key;
+    }
+    public Object getValue(){
+        return map.get(key);
+    }
+    public override hash_t toHash(){
+        return ( getKey()   is null ? 0 : getKey().toHash()   ) ^
+               ( getValue() is null ? 0 : getValue().toHash() );
+    }
+    public Object     setValue(Object value){
+        return map.put( key, value );
     }
 
+}
+
+private struct ObjRef {
+    Object obj;
+    static ObjRef opCall( Object obj ){
+        ObjRef res;
+        res.obj = obj;
+        return res;
+    }
+    public hash_t toHash(){
+        return obj is null ? 0 : obj.toHash();
+    }
+    public int opEquals( ObjRef other ){
+        return obj is null ? other.obj is null : obj.opEquals( other.obj );
+    }
+    public int opEquals( Object other ){
+        return obj is null ? other is null : obj.opEquals( other );
+    }
+}
+
 class HashMap : Map {
-    //FIXME "NULL" is used to work around tango ticket 1468.
-    static Object NULL;
     // The HashMap  class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.
-    alias tango.util.container.HashMap.HashMap!(Object,Object) MapType;
+    alias tango.util.container.HashMap.HashMap!(ObjRef,ObjRef) MapType;
     private MapType map;
 
     public this(){
-        if( NULL is null ) NULL  = new Object();
         map = new MapType();
     }
     public this(int initialCapacity){
         this();
     }
     public this(int initialCapacity, float loadFactor){
-        if( NULL is null ) NULL  = new Object();
         map = new MapType(loadFactor);
     }
     public this(Map m){
@@ -260,20 +274,21 @@
         map.clear();
     }
     public bool containsKey(Object key){
-        Object v;
-        return map.get(key, v );
+        ObjRef v;
+        ObjRef keyr = ObjRef(key);
+        return map.get(keyr, v );
     }
     public bool containsKey(String key){
         return containsKey(stringcast(key));
     }
     public bool containsValue(Object value){
-        Object v = (value is null) ? NULL : value;
-        return map.contains(v);
+        ObjRef valuer = ObjRef(value);
+        return map.contains(valuer);
     }
     public Set  entrySet(){
         HashSet res = new HashSet();
         foreach( k, v; map ){
-            res.add( new MapEntry(this,k));
+            res.add( new MapEntry(this,k.obj));
         }
         return res;
     }
@@ -283,7 +298,7 @@
                 return false;
             }
             foreach( k, v; map ){
-                Object vo = other.get(k);
+                auto vo = other.get(k.obj);
                 if( v != vo ){
                     return false;
                 }
@@ -293,9 +308,9 @@
         return false;
     }
     public Object get(Object key){
-        if( auto v = key in map ){
-            if( *v is NULL ) return null;
-            return *v;
+        ObjRef keyr = ObjRef(key);
+        if( auto v = keyr in map ){
+            return (*v).obj;
         }
         return null;
     }
@@ -311,17 +326,18 @@
     public Set    keySet(){
         HashSet res = new HashSet();
         foreach( k, v; map ){
-            res.add(k);
+            res.add(k.obj);
         }
         return res;
     }
     public Object put(Object key, Object value){
-        Object v = (value is null) ? NULL : value;
+        ObjRef valuer = ObjRef(value);
+        ObjRef keyr = ObjRef(key);
         Object res = null;
-        if( auto vold = key in map ){
-            res = *vold;
+        if( auto vold = keyr in map ){
+            res = (*vold).obj;
         }
-        map[ key ] = v;
+        map[ keyr ] = valuer;
         return res;
     }
     public Object put(String key, Object value){
@@ -335,18 +351,17 @@
     }
     public void   putAll(Map t){
         foreach( k, v; t ){
-            Object vi = (v is null) ? NULL : v;
-            map[k] = vi;
+            map[ObjRef(k)] = ObjRef(v);
         }
     }
     public Object remove(Object key){
-        if( auto v = key in map ){
-            Object res = *v;
-            map.remove(key);
-            if( res is NULL ) return null;
+        ObjRef keyr = ObjRef(key);
+        if( auto v = keyr in map ){
+            Object res = (*v).obj;
+            map.remove(keyr);
             return res;
         }
-        map.remove(key);
+        map.remove(keyr);
         return null;
     }
     public Object remove(String key){
@@ -358,16 +373,22 @@
     public Collection values(){
         ArrayList res = new ArrayList( size() );
         foreach( k, v; map ){
-            res.add( v );
+            res.add( v.obj );
         }
         return res;
     }
 
     public int opApply (int delegate(ref Object value) dg){
-        return map.opApply( dg );
+        int ldg( ref ObjRef or ){
+            return dg( or.obj );
+        }
+        return map.opApply( &ldg );
     }
     public int opApply (int delegate(ref Object key, ref Object value) dg){
-        return map.opApply( dg );
+        int ldg( ref ObjRef key, ref ObjRef value ){
+            return dg( key.obj, value.obj );
+        }
+        return map.opApply( &ldg );
     }
 
 }