diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 8a3790142cf..27dfc5fc1d9 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -109f0f2e11aaaddd2b158117928e10c3c4688870 +b43203a134fb5e259ffc1711cc061c6e869b56f6 The first line of this file holds the git revision number of the last merge done from the dlang/druntime repository. diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index 38bd0ae1f6b..d7588dccbed 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -661,12 +661,12 @@ class TypeInfo_AssociativeArray : TypeInfo override bool equals(in void* p1, in void* p2) @trusted const { - return !!_aaEqual(this, *cast(const void**) p1, *cast(const void**) p2); + return !!_aaEqual(this, *cast(const AA*) p1, *cast(const AA*) p2); } override hash_t getHash(scope const void* p) nothrow @trusted const { - return _aaGetHash(cast(void*)p, this); + return _aaGetHash(cast(AA*)p, this); } // BUG: need to add the rest of the functions @@ -1862,30 +1862,31 @@ extern (C) { // from druntime/src/rt/aaA.d - // size_t _aaLen(in void* p) pure nothrow @nogc; - private void* _aaGetY(void** paa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey) pure nothrow; - private void* _aaGetX(void** paa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey, out bool found) pure nothrow; - // inout(void)* _aaGetRvalueX(inout void* p, in TypeInfo keyti, in size_t valuesize, in void* pkey); - inout(void)[] _aaValues(inout void* p, in size_t keysize, in size_t valuesize, const TypeInfo tiValArray) pure nothrow; - inout(void)[] _aaKeys(inout void* p, in size_t keysize, const TypeInfo tiKeyArray) pure nothrow; - void* _aaRehash(void** pp, in TypeInfo keyti) pure nothrow; - void _aaClear(void* p) pure nothrow; + private struct AA { void* impl; } + // size_t _aaLen(in AA aa) pure nothrow @nogc; + private void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti, in size_t valsz, in void* pkey) pure nothrow; + private void* _aaGetX(AA* paa, const TypeInfo_AssociativeArray ti, in size_t valsz, in void* pkey, out bool found) pure nothrow; + // inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz, in void* pkey); + inout(void[]) _aaValues(inout AA aa, in size_t keysz, in size_t valsz, const TypeInfo tiValueArray) pure nothrow; + inout(void[]) _aaKeys(inout AA aa, in size_t keysz, const TypeInfo tiKeyArray) pure nothrow; + void* _aaRehash(AA* paa, in TypeInfo keyti) pure nothrow; + void _aaClear(AA aa) pure nothrow; // alias _dg_t = extern(D) int delegate(void*); - // int _aaApply(void* aa, size_t keysize, _dg_t dg); + // int _aaApply(AA aa, size_t keysize, _dg_t dg); // alias _dg2_t = extern(D) int delegate(void*, void*); - // int _aaApply2(void* aa, size_t keysize, _dg2_t dg); + // int _aaApply2(AA aa, size_t keysize, _dg2_t dg); - private struct AARange { void* impl; size_t idx; } - AARange _aaRange(void* aa) pure nothrow @nogc @safe; + private struct AARange { AA impl; size_t idx; } + AARange _aaRange(AA aa) pure nothrow @nogc @safe; bool _aaRangeEmpty(AARange r) pure nothrow @nogc @safe; void* _aaRangeFrontKey(AARange r) pure nothrow @nogc @safe; void* _aaRangeFrontValue(AARange r) pure nothrow @nogc @safe; void _aaRangePopFront(ref AARange r) pure nothrow @nogc @safe; - int _aaEqual(in TypeInfo tiRaw, in void* e1, in void* e2); - hash_t _aaGetHash(in void* aa, in TypeInfo tiRaw) nothrow; + int _aaEqual(in TypeInfo tiRaw, in AA aa1, in AA aa2); + hash_t _aaGetHash(in AA* aa, in TypeInfo tiRaw) nothrow; /* _d_assocarrayliteralTX marked as pure, because aaLiteral can be called from pure code. @@ -1910,13 +1911,13 @@ alias AssociativeArray(Key, Value) = Value[Key]; */ void clear(T : Value[Key], Value, Key)(T aa) { - _aaClear(*cast(void **) &aa); + _aaClear(*cast(AA *) &aa); } /* ditto */ void clear(T : Value[Key], Value, Key)(T* aa) { - _aaClear(*cast(void **) aa); + _aaClear(*cast(AA *) aa); } /*********************************** @@ -1929,28 +1930,28 @@ void clear(T : Value[Key], Value, Key)(T* aa) */ T rehash(T : Value[Key], Value, Key)(T aa) { - _aaRehash(cast(void**)&aa, typeid(Value[Key])); + _aaRehash(cast(AA*)&aa, typeid(Value[Key])); return aa; } /* ditto */ T rehash(T : Value[Key], Value, Key)(T* aa) { - _aaRehash(cast(void**)aa, typeid(Value[Key])); + _aaRehash(cast(AA*)aa, typeid(Value[Key])); return *aa; } /* ditto */ T rehash(T : shared Value[Key], Value, Key)(T aa) { - _aaRehash(cast(void**)&aa, typeid(Value[Key])); + _aaRehash(cast(AA*)&aa, typeid(Value[Key])); return aa; } /* ditto */ T rehash(T : shared Value[Key], Value, Key)(T* aa) { - _aaRehash(cast(void**)aa, typeid(Value[Key])); + _aaRehash(cast(AA*)aa, typeid(Value[Key])); return *aa; } @@ -1977,7 +1978,7 @@ V[K] dup(T : V[K], K, V)(T aa) { import core.stdc.string : memcpy; - void* pv = _aaGetY(cast(void**)&result, typeid(V[K]), V.sizeof, &k); + void* pv = _aaGetY(cast(AA*)&result, typeid(V[K]), V.sizeof, &k); memcpy(pv, &v, V.sizeof); return *cast(V*)pv; } @@ -2010,7 +2011,7 @@ private AARange _aaToRange(T: V[K], K, V)(ref T aa) pure nothrow @nogc @safe alias realAA = aa; else const(V[K]) realAA = aa; - return _aaRange(() @trusted { return cast(void*)realAA; } ()); + return _aaRange(() @trusted { return *cast(AA*)&realAA; } ()); } /*********************************** @@ -2146,7 +2147,12 @@ auto byKeyValue(T : V[K], K, V)(T* aa) pure nothrow @nogc */ Key[] keys(T : Value[Key], Value, Key)(T aa) @property { - auto a = cast(void[])_aaKeys(cast(inout(void)*)aa, Key.sizeof, typeid(Key[])); + // ensure we are dealing with a genuine AA. + static if (is(const(Value[Key]) == const(T))) + alias realAA = aa; + else + const(Value[Key]) realAA = aa; + auto a = cast(void[])_aaKeys(*cast(inout(AA)*)&realAA, Key.sizeof, typeid(Key[])); auto res = *cast(Key[]*)&a; _doPostblit(res); return res; @@ -2158,6 +2164,19 @@ Key[] keys(T : Value[Key], Value, Key)(T *aa) @property return (*aa).keys; } +@system unittest +{ + static struct S + { + string str; + void[][string] dict; + alias dict this; + } + + auto s = S("a"); + assert(s.keys.length == 0); +} + /*********************************** * Returns a dynamic array, the elements of which are the values in the * associative array. @@ -2168,7 +2187,12 @@ Key[] keys(T : Value[Key], Value, Key)(T *aa) @property */ Value[] values(T : Value[Key], Value, Key)(T aa) @property { - auto a = cast(void[])_aaValues(cast(inout(void)*)aa, Key.sizeof, Value.sizeof, typeid(Value[])); + // ensure we are dealing with a genuine AA. + static if (is(const(Value[Key]) == const(T))) + alias realAA = aa; + else + const(Value[Key]) realAA = aa; + auto a = cast(void[])_aaValues(*cast(inout(AA)*)&realAA, Key.sizeof, Value.sizeof, typeid(Value[])); auto res = *cast(Value[]*)&a; _doPostblit(res); return res; @@ -2180,6 +2204,19 @@ Value[] values(T : Value[Key], Value, Key)(T *aa) @property return (*aa).values; } +@system unittest +{ + static struct S + { + string str; + void[][string] dict; + alias dict this; + } + + auto s = S("a"); + assert(s.values.length == 0); +} + /*********************************** * Looks up key; if it exists returns corresponding value else evaluates and * returns defaultValue. @@ -2220,12 +2257,12 @@ ref V require(K, V)(ref V[K] aa, K key, lazy V value = V.init) { auto p = () @trusted { - return cast(V*) _aaGetX(cast(void**) &aa, typeid(V[K]), V.sizeof, &key, found); + return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found); } (); } else { - auto p = cast(V*) _aaGetX(cast(void**) &aa, typeid(V[K]), V.sizeof, &key, found); + auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found); } return found ? *p : (*p = value); } @@ -2276,12 +2313,12 @@ if (isCreateOperation!(C, V) && isUpdateOperation!(U, V)) { auto p = () @trusted { - return cast(V*) _aaGetX(cast(void**) &aa, typeid(V[K]), V.sizeof, &key, found); + return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found); } (); } else { - auto p = cast(V*) _aaGetX(cast(void**) &aa, typeid(V[K]), V.sizeof, &key, found); + auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found); } if (!found) *p = create(); @@ -3879,3 +3916,30 @@ unittest scope arr = [S(&p)]; auto a = arr.dup; // dup does escape } + +// compiler frontend lowers dynamic array comparison to this +bool __ArrayEq(T1, T2)(T1[] a, T2[] b) +{ + if (a.length != b.length) + return false; + foreach (size_t i; 0 .. a.length) + { + if (a[i] != b[i]) + return false; + } + return true; +} + +// compiler frontend lowers struct array postblitting to this +void __ArrayPostblit(T)(T[] a) +{ + foreach (ref T e; a) + e.__xpostblit(); +} + +// compiler frontend lowers dynamic array deconstruction to this +void __ArrayDtor(T)(T[] a) +{ + foreach_reverse (ref T e; a) + e.__xdtor(); +}