# HG changeset patch # User Frank Benoit # Date 1233673690 -3600 # Node ID a4d38d47ddc41abb42eb9b054e689090c4c583a0 # Parent 6d35b9960800b00551b0c357c37112b13cda5fdf HashMap support for null values and keys diff -r 6d35b9960800 -r a4d38d47ddc4 dwtx/dwtxhelper/Collection.d --- 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 ); } }