diff --git a/internal/object.d b/internal/object.d index 120a83040..6701033f7 100644 --- a/internal/object.d +++ b/internal/object.d @@ -324,6 +324,16 @@ class TypeInfo class TypeInfo_Typedef : TypeInfo { char[] toString() { return name; } + + int opEquals(Object o) + { TypeInfo_Typedef c; + + return this is o || + ((c = cast(TypeInfo_Typedef)o) !is null && + this.name == c.name && + this.base == c.base); + } + hash_t getHash(void *p) { return base.getHash(p); } int equals(void *p1, void *p2) { return base.equals(p1, p2); } int compare(void *p1, void *p2) { return base.compare(p1, p2); } @@ -342,6 +352,14 @@ class TypeInfo_Pointer : TypeInfo { char[] toString() { return next.toString() ~ "*"; } + int opEquals(Object o) + { TypeInfo_Pointer c; + + return this is o || + ((c = cast(TypeInfo_Pointer)o) !is null && + this.next == c.next); + } + hash_t getHash(void *p) { return cast(uint)*cast(void* *)p; @@ -376,6 +394,14 @@ class TypeInfo_Array : TypeInfo { char[] toString() { return next.toString() ~ "[]"; } + int opEquals(Object o) + { TypeInfo_Array c; + + return this is o || + ((c = cast(TypeInfo_Array)o) !is null && + this.next == c.next); + } + hash_t getHash(void *p) { size_t sz = next.tsize(); hash_t hash = 0; @@ -440,6 +466,15 @@ class TypeInfo_StaticArray : TypeInfo return next.toString() ~ "[" ~ std.string.toString(len) ~ "]"; } + int opEquals(Object o) + { TypeInfo_StaticArray c; + + return this is o || + ((c = cast(TypeInfo_StaticArray)o) !is null && + this.len == c.len && + this.next == c.next); + } + hash_t getHash(void *p) { size_t sz = next.tsize(); hash_t hash = 0; @@ -510,6 +545,15 @@ class TypeInfo_AssociativeArray : TypeInfo return next.toString() ~ "[" ~ key.toString() ~ "]"; } + int opEquals(Object o) + { TypeInfo_AssociativeArray c; + + return this is o || + ((c = cast(TypeInfo_AssociativeArray)o) !is null && + this.key == c.key && + this.next == c.next); + } + // BUG: need to add the rest of the functions size_t tsize() @@ -528,6 +572,14 @@ class TypeInfo_Function : TypeInfo return next.toString() ~ "()"; } + int opEquals(Object o) + { TypeInfo_Function c; + + return this is o || + ((c = cast(TypeInfo_Function)o) !is null && + this.next == c.next); + } + // BUG: need to add the rest of the functions size_t tsize() @@ -545,6 +597,14 @@ class TypeInfo_Delegate : TypeInfo return next.toString() ~ " delegate()"; } + int opEquals(Object o) + { TypeInfo_Delegate c; + + return this is o || + ((c = cast(TypeInfo_Delegate)o) !is null && + this.next == c.next); + } + // BUG: need to add the rest of the functions size_t tsize() @@ -559,6 +619,14 @@ class TypeInfo_Class : TypeInfo { char[] toString() { return info.name; } + int opEquals(Object o) + { TypeInfo_Class c; + + return this is o || + ((c = cast(TypeInfo_Class)o) !is null && + this.info.name == c.classinfo.name); + } + hash_t getHash(void *p) { Object o = *cast(Object*)p; @@ -607,6 +675,14 @@ class TypeInfo_Interface : TypeInfo { char[] toString() { return info.name; } + int opEquals(Object o) + { TypeInfo_Interface c; + + return this is o || + ((c = cast(TypeInfo_Interface)o) !is null && + this.info.name == c.classinfo.name); + } + hash_t getHash(void *p) { Interface* pi = **cast(Interface ***)*cast(void**)p; @@ -660,6 +736,15 @@ class TypeInfo_Struct : TypeInfo { char[] toString() { return name; } + int opEquals(Object o) + { TypeInfo_Struct s; + + return this is o || + ((s = cast(TypeInfo_Struct)o) !is null && + this.name == s.name && + this.xsize == s.xsize); + } + hash_t getHash(void *p) { hash_t h; @@ -751,6 +836,24 @@ class TypeInfo_Tuple : TypeInfo return s; } + int opEquals(Object o) + { + if (this is o) + return 1; + + auto t = cast(TypeInfo_Tuple)o; + if (t && elements.length == t.elements.length) + { + for (size_t i = 0; i < elements.length; i++) + { + if (elements[i] != t.elements[i]) + return 0; + } + return 1; + } + return 0; + } + hash_t getHash(void *p) { assert(0); diff --git a/std.ddoc b/std.ddoc index 79f28df5b..a8ba23388 100644 --- a/std.ddoc +++ b/std.ddoc @@ -144,6 +144,8 @@ NAVIGATION_PHOBOS= $(LI std.string) $(LI std.system) $(LI std.thread) + $(LI std.traits) + $(LI std.typetuple) $(LI std.uni) $(LI std.uri) $(LI std.utf) diff --git a/std/demangle.d b/std/demangle.d index 81f8682de..b936238cf 100644 --- a/std/demangle.d +++ b/std/demangle.d @@ -1,11 +1,19 @@ + +// Written in the D programming language. + +/* + * Placed into the Public Domain. + */ + /**** * Demangle D mangled names. * Macros: * WIKI = Phobos/StdDemangle */ -/* Author: +/* Authors: * Walter Bright, Digital Mars, www.digitalmars.com + * Thomas Kuehne */ module std.demangle; @@ -234,6 +242,11 @@ char[] demangle(char[] name) char c = name[ni]; if (c == 'Z') break; + if (c == 'X') + { + args ~= " ..."; + break; + } if (args.length) args ~= ", "; switch (c) @@ -248,6 +261,11 @@ char[] demangle(char[] name) ni++; goto default; + case 'L': + args ~= "lazy "; + ni++; + goto default; + default: args ~= parseType(); continue; @@ -472,6 +490,9 @@ unittest [ "_D4test58__T9factorialVde67666666666666860140VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, char[5] \"hello\"c, void* null).factorial" ], [ "_D4test101__T9factorialVde67666666666666860140Vrc9a999999999999d9014000000000000000c00040VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, cdouble 6.8+3i, char[5] \"hello\"c, void* null).factorial" ], [ "_D4test34__T3barVG3uw3_616263VG3wd3_646566Z1xi", "int test.bar!(wchar[3] \"abc\"w, dchar[3] \"def\"d).x" ], + [ "_D8demangle4testFLC6ObjectLDFLiZiZi", "int demangle.test(lazy class Object, lazy int delegate(lazy int))"], + [ "_D8demangle4testFAiXi", "int demangle.test(int[] ...)"], + [ "_D8demangle4testFLAiXi", "int demangle.test(lazy int[] ...)"] ]; foreach (char[][2] name; table) @@ -481,3 +502,5 @@ unittest assert(r == name[1]); } } + + diff --git a/std/format.d b/std/format.d index d95a0080a..7c0507c4c 100644 --- a/std/format.d +++ b/std/format.d @@ -696,7 +696,10 @@ void doFormat(void delegate(dchar) putc, TypeInfo[] arguments, va_list argptr) case Mangle.Tclass: vobject = va_arg!(Object)(argptr); - s = vobject.toString(); + if (vobject is null) + s = "null"; + else + s = vobject.toString(); goto Lputstr; case Mangle.Tpointer: @@ -1363,5 +1366,9 @@ unittest assert(r == "f"); r = std.string.format("%X", 15); assert(r == "F"); + + Object c = null; + r = std.string.format(c); + assert(r == "null"); } diff --git a/std/socket.d b/std/socket.d index 51e4c368a..43fc829dc 100644 --- a/std/socket.d +++ b/std/socket.d @@ -1593,47 +1593,3 @@ class Socket +/ } - -/// TcpSocket is a shortcut class for a TCP Socket. -class TcpSocket: Socket -{ - /// Constructs a blocking TCP Socket. - this(AddressFamily family) - { - super(family, SocketType.STREAM, ProtocolType.TCP); - } - - /// Constructs a blocking TCP Socket. - this() - { - this(cast(AddressFamily)AddressFamily.INET); - } - - - //shortcut - /// Constructs a blocking TCP Socket and connects to an InternetAddress. - this(Address connectTo) - { - this(connectTo.addressFamily()); - connect(connectTo); - } -} - - -/// UdpSocket is a shortcut class for a UDP Socket. -class UdpSocket: Socket -{ - /// Constructs a blocking UDP Socket. - this(AddressFamily family) - { - super(family, SocketType.DGRAM, ProtocolType.UDP); - } - - - /// Constructs a blocking UDP Socket. - this() - { - this(cast(AddressFamily)AddressFamily.INET); - } -} - diff --git a/std/stdio.d b/std/stdio.d index 2a524f569..28fb2d03c 100644 --- a/std/stdio.d +++ b/std/stdio.d @@ -1,4 +1,6 @@ +// Written in the D programming language. + /* Written by Walter Bright * www.digitalmars.com * Placed in the Public Domain. diff --git a/std/traits.d b/std/traits.d index 891fee2db..04f123309 100644 --- a/std/traits.d +++ b/std/traits.d @@ -85,3 +85,43 @@ template FieldTypeTuple(S) else static assert(0, "argument is not struct or class"); } + + +/*** + * Get a TypeTuple of the base class and base interfaces of + * this class or interface. + * Example: + * --- + * import std.traits, std.typetuple, std.stdio; + * interface I { } + * class A { } + * class B : A, I { } + * + * void main() + * { + * alias BaseTypeTuple!(B) TL; + * writefln(typeid(TL)); // prints: (A,I) + * } + * --- + */ + +template BaseTypeTuple(A) +{ + static if (is(A P == super)) + alias P BaseTypeTuple; + else + static assert(0, "argument is not a class or interface"); +} + +unittest +{ + interface I { } + class A { } + class B : A, I { } + + alias BaseTypeTuple!(B) TL; + assert(TL.length == 2); + assert(is (TL[0] == A)); + assert(is (TL[1] == I)); +} + diff --git a/std/uni.d b/std/uni.d index 900f761e3..5b7edab35 100644 --- a/std/uni.d +++ b/std/uni.d @@ -1,3 +1,6 @@ + +// Written in the D programming language. + /* * Placed into the Public Domain. * Digital Mars, www.digitalmars.com @@ -52,7 +55,7 @@ dchar toUniLower(dchar c) { c += 32; } - if (c >= 0x00C0) + else if (c >= 0x00C0) { if ((c >= 0x00C0 && c <= 0x00D6) || (c >= 0x00D8 && c<=0x00DE)) { @@ -118,7 +121,7 @@ dchar toUniUpper(dchar c) { c -= 32; } - if (c >= 0x00E0) + else if (c >= 0x00E0) { if ((c >= 0x00E0 && c <= 0x00F6) || (c >= 0x00F8 && c <= 0x00FE)) {