diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-09-23 12:27:26 +0200 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-09-23 13:01:16 +0200 |
commit | d6679fa2d65316e80a267c94c17ad9e23f433f77 (patch) | |
tree | eca9ecef18b21760629c54620785c18bc4452bbd /libphobos | |
parent | 59d27cc55a0588ed7b03bef804662cb844e8a24d (diff) | |
download | gcc-d6679fa2d65316e80a267c94c17ad9e23f433f77.zip gcc-d6679fa2d65316e80a267c94c17ad9e23f433f77.tar.gz gcc-d6679fa2d65316e80a267c94c17ad9e23f433f77.tar.bz2 |
d: Merge upstream dmd, druntime 4574d1728d, phobos d7e79f024.
D front-end changes:
- Import dmd v2.105.0.
- Catch clause must take only `const' or mutable exceptions.
- Creating a `scope' class instance with a non-scope constructor
is now `@system' only with `-fpreview=dip1000'.
- Global `const' variables can no longer be initialized from a
non-shared static constructor
D runtime changes:
- Import druntime v2.105.0.
Phobos changes:
- Import phobos v2.105.0.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 4574d1728d.
* dmd/VERSION: Bump version to v2.105.0.
* d-diagnostic.cc (verror): Remove.
(verrorSupplemental): Remove.
(vwarning): Remove.
(vwarningSupplemental): Remove.
(vdeprecation): Remove.
(vdeprecationSupplemental): Remove.
(vmessage): Remove.
(vtip): Remove.
(verrorReport): New function.
(verrorReportSupplemental): New function.
* d-lang.cc (d_parse_file): Update for new front-end interface.
* decl.cc (d_mangle_decl): Update for new front-end interface.
* intrinsics.cc (maybe_set_intrinsic): Update for new front-end
interface.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 4574d1728d.
* src/MERGE: Merge upstream phobos d7e79f024.
Diffstat (limited to 'libphobos')
34 files changed, 695 insertions, 371 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index a02a8cb..dc26778 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -26f049fb26e755096dea3f1474decea7c0fef187 +4574d1728d1f7e52ff40e6733b8c39889d128349 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d index f08e1f8..f113159 100644 --- a/libphobos/libdruntime/core/demangle.d +++ b/libphobos/libdruntime/core/demangle.d @@ -127,7 +127,7 @@ pure @safe: void putComma(size_t n) { - pragma(inline, false); + version (DigitalMars) pragma(inline, false); if (n) put(", "); } @@ -2861,7 +2861,7 @@ private class OverflowException : Exception /// Ditto private noreturn error(string msg = "Invalid symbol") @trusted pure { - pragma(inline, false); // tame dmd inliner + version (DigitalMars) pragma(inline, false); // tame dmd inliner //throw new ParseException( msg ); debug(info) printf( "error: %.*s\n", cast(int) msg.length, msg.ptr ); @@ -2872,7 +2872,7 @@ private noreturn error(string msg = "Invalid symbol") @trusted pure /// Ditto private noreturn overflow(string msg = "Buffer overflow") @trusted pure { - pragma(inline, false); // tame dmd inliner + version (DigitalMars) pragma(inline, false); // tame dmd inliner //throw new OverflowException( msg ); debug(info) printf( "overflow: %.*s\n", cast(int) msg.length, msg.ptr ); @@ -2927,7 +2927,7 @@ private struct Buffer // move val to the end of the dst buffer char[] shift(scope const(char)[] val) return scope { - pragma(inline, false); // tame dmd inliner + version (DigitalMars) pragma(inline, false); // tame dmd inliner if (val.length) { @@ -2949,7 +2949,7 @@ private struct Buffer // remove val from dst buffer void remove(scope const(char)[] val) scope { - pragma(inline, false); // tame dmd inliner + version (DigitalMars) pragma(inline, false); // tame dmd inliner if ( val.length ) { @@ -2965,7 +2965,7 @@ private struct Buffer char[] append(scope const(char)[] val) return scope { - pragma(inline, false); // tame dmd inliner + version (DigitalMars) pragma(inline, false); // tame dmd inliner if (val.length) { diff --git a/libphobos/libdruntime/core/internal/array/appending.d b/libphobos/libdruntime/core/internal/array/appending.d index b609167..bb24813 100644 --- a/libphobos/libdruntime/core/internal/array/appending.d +++ b/libphobos/libdruntime/core/internal/array/appending.d @@ -35,7 +35,7 @@ template _d_arrayappendcTXImpl(Tarr : T[], T) ref Tarr _d_arrayappendcTX(return ref scope Tarr px, size_t n) @trusted pure nothrow { // needed for CTFE: https://github.com/dlang/druntime/pull/3870#issuecomment-1178800718 - pragma(inline, false); + version (DigitalMars) pragma(inline, false); version (D_TypeInfo) { auto ti = typeid(Tarr); @@ -70,7 +70,7 @@ template _d_arrayappendcTXImpl(Tarr : T[], T) /// Implementation of `_d_arrayappendT` ref Tarr _d_arrayappendT(Tarr : T[], T)(return ref scope Tarr x, scope Tarr y) @trusted { - pragma(inline, false); + version (DigitalMars) pragma(inline, false); import core.stdc.string : memcpy; import core.internal.traits : hasElaborateCopyConstructor, Unqual; diff --git a/libphobos/libdruntime/core/internal/array/capacity.d b/libphobos/libdruntime/core/internal/array/capacity.d index 254e950..10ce2c6 100644 --- a/libphobos/libdruntime/core/internal/array/capacity.d +++ b/libphobos/libdruntime/core/internal/array/capacity.d @@ -36,7 +36,7 @@ template _d_arraysetlengthTImpl(Tarr : T[], T) */ size_t _d_arraysetlengthT(return scope ref Tarr arr, size_t newlength) @trusted pure nothrow { - pragma(inline, false); + version (DigitalMars) pragma(inline, false); version (D_TypeInfo) { auto ti = typeid(Tarr); diff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d index ae71f51..2508359 100644 --- a/libphobos/libdruntime/core/internal/array/construction.d +++ b/libphobos/libdruntime/core/internal/array/construction.d @@ -36,7 +36,7 @@ import core.internal.traits : Unqual; */ Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from, char* makeWeaklyPure = null) @trusted { - pragma(inline, false); + version (DigitalMars) pragma(inline, false); import core.internal.traits : hasElaborateCopyConstructor; import core.lifetime : copyEmplace; import core.stdc.string : memcpy; @@ -200,7 +200,7 @@ Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from, char* ma */ void _d_arraysetctor(Tarr : T[], T)(scope Tarr p, scope ref T value) @trusted { - pragma(inline, false); + version (DigitalMars) pragma(inline, false); import core.lifetime : copyEmplace; size_t i; diff --git a/libphobos/libdruntime/core/memory.d b/libphobos/libdruntime/core/memory.d index 96c2af4..4f44b604 100644 --- a/libphobos/libdruntime/core/memory.d +++ b/libphobos/libdruntime/core/memory.d @@ -270,7 +270,7 @@ extern(C): * reentrant, and must be called once for every call to disable before * automatic collections are enabled. */ - pragma(mangle, "gc_enable") static void enable() nothrow pure; + pragma(mangle, "gc_enable") static void enable() @safe nothrow pure; /** @@ -280,7 +280,7 @@ extern(C): * such as during an out of memory condition. This function is reentrant, * but enable must be called once for each call to disable. */ - pragma(mangle, "gc_disable") static void disable() nothrow pure; + pragma(mangle, "gc_disable") static void disable() @safe nothrow pure; /** @@ -290,14 +290,14 @@ extern(C): * and then to reclaim free space. This action may need to suspend all * running threads for at least part of the collection process. */ - pragma(mangle, "gc_collect") static void collect() nothrow pure; + pragma(mangle, "gc_collect") static void collect() @safe nothrow pure; /** * Indicates that the managed memory space be minimized by returning free * physical memory to the operating system. The amount of free memory * returned depends on the allocator design and on program behavior. */ - pragma(mangle, "gc_minimize") static void minimize() nothrow pure; + pragma(mangle, "gc_minimize") static void minimize() @safe nothrow pure; extern(D): diff --git a/libphobos/libdruntime/core/sys/windows/basetsd.d b/libphobos/libdruntime/core/sys/windows/basetsd.d index 3c5c35f..e70dbdc 100644 --- a/libphobos/libdruntime/core/sys/windows/basetsd.d +++ b/libphobos/libdruntime/core/sys/windows/basetsd.d @@ -10,39 +10,10 @@ module core.sys.windows.basetsd; version (Windows): -/* This template is used in these modules to declare constant pointer types, - * in order to support both D 1.x and 2.x. - * Since removed - now supporting only D2 - */ -/*template CPtr(T) { - version (D_Version2) { - // must use mixin so that it doesn't cause a syntax error under D1 - mixin("alias const(T)* CPtr;"); - } else { - alias T* CPtr; - } -}*/ - -/* [CyberShadow VP 2011.12.22] typedef is now deprecated in D2. - */ -template TypeDef(T) { - version (D_Version2) { - alias T TypeDef; - } else { - // must use mixin so that it doesn't cause a deprecation error under D2 - mixin("typedef T TypeDef;"); - } -} - // [SnakE 2009-02-23] Moved HANDLE definition here from winnt.d to avoid // 'forwatd template reference' to CPtr from winnt.d caused by a circular // import. - -alias TypeDef!(void*) HANDLE; -/+struct HANDLE { -const(void)* h; - alias h this; -}+/ +alias HANDLE = void*; package template DECLARE_HANDLE(string name, base = HANDLE) { mixin ("alias " ~ base.stringof ~ " " ~ name ~ ";"); diff --git a/libphobos/libdruntime/core/sys/windows/mmsystem.d b/libphobos/libdruntime/core/sys/windows/mmsystem.d index 7e7c34b..29c066e 100644 --- a/libphobos/libdruntime/core/sys/windows/mmsystem.d +++ b/libphobos/libdruntime/core/sys/windows/mmsystem.d @@ -1049,7 +1049,7 @@ struct MMTIME { } alias MMTIME* PMMTIME, LPMMTIME; -alias TypeDef!(HANDLE) HDRVR; +alias HANDLE HDRVR; struct DRVCONFIGINFO { align(1): @@ -1083,9 +1083,9 @@ alias MIDICALLBACK* LPMIDICALLBACK; +/ -alias TypeDef!(HANDLE) HWAVE; -alias TypeDef!(HANDLE) HWAVEIN; -alias TypeDef!(HANDLE) HWAVEOUT; +alias HANDLE HWAVE; +alias HANDLE HWAVEIN; +alias HANDLE HWAVEOUT; alias HWAVEIN* LPHWAVEIN; alias HWAVEOUT* LPHWAVEOUT; @@ -1175,10 +1175,10 @@ struct WAVEFORMATEX { alias WAVEFORMATEX* PWAVEFORMATEX, LPWAVEFORMATEX; alias const(WAVEFORMATEX)* LPCWAVEFORMATEX; -alias TypeDef!(HANDLE) HMIDI; -alias TypeDef!(HANDLE) HMIDIIN; -alias TypeDef!(HANDLE) HMIDIOUT; -alias TypeDef!(HANDLE) HMIDISTRM; +alias HANDLE HMIDI; +alias HANDLE HMIDIIN; +alias HANDLE HMIDIOUT; +alias HANDLE HMIDISTRM; alias HMIDI* LPHMIDI; alias HMIDIIN* LPHMIDIIN; @@ -1295,10 +1295,10 @@ struct AUXCAPSW { } alias AUXCAPSW* PAUXCAPSW, LPAUXCAPSW; -alias TypeDef!(HANDLE) HMIXEROBJ; +alias HANDLE HMIXEROBJ; alias HMIXEROBJ* LPHMIXEROBJ; -alias TypeDef!(HANDLE) HMIXER; +alias HANDLE HMIXER; alias HMIXER* LPHMIXER; struct MIXERCAPSA { @@ -1595,7 +1595,7 @@ alias JOYINFOEX* PJOYINFOEX, LPJOYINFOEX; alias DWORD FOURCC; alias char* HPSTR; -alias TypeDef!(HANDLE) HMMIO; +alias HANDLE HMMIO; alias LRESULT function (LPSTR, UINT, LPARAM, LPARAM) LPMMIOPROC; diff --git a/libphobos/libdruntime/core/sys/windows/ole.d b/libphobos/libdruntime/core/sys/windows/ole.d index c29ec50..a844124 100644 --- a/libphobos/libdruntime/core/sys/windows/ole.d +++ b/libphobos/libdruntime/core/sys/windows/ole.d @@ -257,7 +257,7 @@ struct OLESERVERVTBL { OLESTATUS function(LPOLESERVER) Release; OLESTATUS function(LPOLESERVER, HGLOBAL) Execute; } -alias TypeDef!(OLESERVERVTBL*) LPOLESERVERVTBL; +alias OLESERVERVTBL* LPOLESERVERVTBL; struct OLESERVER { LPOLESERVERVTBL lpvtbl; diff --git a/libphobos/libdruntime/core/sys/windows/ras.d b/libphobos/libdruntime/core/sys/windows/ras.d index cb69686..4561799 100644 --- a/libphobos/libdruntime/core/sys/windows/ras.d +++ b/libphobos/libdruntime/core/sys/windows/ras.d @@ -223,7 +223,7 @@ enum RASPROJECTION { } alias RASPROJECTION* LPRASPROJECTION; -alias TypeDef!(HANDLE) HRASCONN; +alias HANDLE HRASCONN; alias HRASCONN* LPHRASCONN; struct RASCONNW { diff --git a/libphobos/libdruntime/core/sys/windows/rpcdcep.d b/libphobos/libdruntime/core/sys/windows/rpcdcep.d index cebe981..71b82be 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcdcep.d +++ b/libphobos/libdruntime/core/sys/windows/rpcdcep.d @@ -97,7 +97,7 @@ const(void)* InterpreterInfo; } alias RPC_CLIENT_INTERFACE* PRPC_CLIENT_INTERFACE; -alias TypeDef!(void*) I_RPC_MUTEX; +alias void* I_RPC_MUTEX; struct RPC_TRANSFER_SYNTAX { GUID Uuid; diff --git a/libphobos/libdruntime/core/sys/windows/rpcndr.d b/libphobos/libdruntime/core/sys/windows/rpcndr.d index 127d88b..f5744ec 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcndr.d +++ b/libphobos/libdruntime/core/sys/windows/rpcndr.d @@ -387,7 +387,7 @@ enum PROXY_PHASE { PROXY_UNMARSHAL } -alias TypeDef!(void *) RPC_SS_THREAD_HANDLE; +alias void * RPC_SS_THREAD_HANDLE; extern (Windows) { alias void function (void*) NDR_RUNDOWN; diff --git a/libphobos/libdruntime/core/sys/windows/sqltypes.d b/libphobos/libdruntime/core/sys/windows/sqltypes.d index 28d5f5d..e86834f 100644 --- a/libphobos/libdruntime/core/sys/windows/sqltypes.d +++ b/libphobos/libdruntime/core/sys/windows/sqltypes.d @@ -32,7 +32,7 @@ alias UDWORD SQLUINTEGER; // #endif //static if (ODBCVER >= 0x0300) { -alias TypeDef!(HANDLE) SQLHANDLE; +alias HANDLE SQLHANDLE; alias SQLHANDLE SQLHENV, SQLHDBC, SQLHSTMT, SQLHDESC; /* } else { diff --git a/libphobos/libdruntime/core/sys/windows/vfw.d b/libphobos/libdruntime/core/sys/windows/vfw.d index ebe0ed0..e8ca74e 100644 --- a/libphobos/libdruntime/core/sys/windows/vfw.d +++ b/libphobos/libdruntime/core/sys/windows/vfw.d @@ -38,7 +38,7 @@ DWORD MKFOURCC(char ch0, char ch1, char ch2, char ch3) { enum ICVERSION = 0x0104; -alias TypeDef!(HANDLE) HIC; +alias HANDLE HIC; enum BI_1632 = 0x32333631; @@ -1045,7 +1045,7 @@ DECLARE_INTERFACE_(IAVIStream, IUnknown) #endif }; -alias TypeDef!(IAVIStream FAR*) PAVISTREAM; +alias IAVIStream FAR* PAVISTREAM; #undef INTERFACE #define INTERFACE IAVIStreaming @@ -1063,7 +1063,7 @@ DECLARE_INTERFACE_(IAVIStreaming, IUnknown) STDMETHOD(End) (THIS) PURE; }; -alias TypeDef!(IAVIStreaming FAR*) PAVISTREAMING; +alias IAVIStreaming FAR* PAVISTREAMING; #undef INTERFACE @@ -1091,7 +1091,7 @@ DECLARE_INTERFACE_(IAVIEditStream, IUnknown) LONG cbInfo) PURE; }; -alias TypeDef!(IAVIEditStream FAR*) PAVIEDITSTREAM; +alias IAVIEditStream FAR* PAVIEDITSTREAM; #undef INTERFACE #define INTERFACE IAVIPersistFile @@ -1101,7 +1101,7 @@ DECLARE_INTERFACE_(IAVIPersistFile, IPersistFile) STDMETHOD(Reserved1)(THIS) PURE; }; -alias TypeDef!(IAVIPersistFile FAR*) PAVIPERSISTFILE; +alias IAVIPersistFile FAR* PAVIPERSISTFILE; #undef INTERFACE #define INTERFACE IAVIFile @@ -1138,7 +1138,7 @@ DECLARE_INTERFACE_(IAVIFile, IUnknown) }; #undef PAVIFILE -alias TypeDef!(IAVIFile FAR*) PAVIFILE; +alias IAVIFile FAR* PAVIFILE; #undef INTERFACE #define INTERFACE IGetFrame @@ -1159,7 +1159,7 @@ DECLARE_INTERFACE_(IGetFrame, IUnknown) }; #undef PGETFRAME -alias TypeDef!(IGetFrame FAR*) PGETFRAME; +alias IGetFrame FAR* PGETFRAME; #define DEFINE_AVIGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46) @@ -1825,7 +1825,7 @@ enum { MCI_MODE_OPEN, } -alias TypeDef!(HANDLE) HVIDEO; +alias HANDLE HVIDEO; alias HVIDEO* LPHVIDEO; // Error Return Values diff --git a/libphobos/libdruntime/core/sys/windows/winbase.d b/libphobos/libdruntime/core/sys/windows/winbase.d index bbb6e9a..2e32ba2 100644 --- a/libphobos/libdruntime/core/sys/windows/winbase.d +++ b/libphobos/libdruntime/core/sys/windows/winbase.d @@ -408,7 +408,7 @@ enum : DWORD { STD_ERROR_HANDLE = 0xFFFFFFF4 } -enum HANDLE INVALID_HANDLE_VALUE = cast(HANDLE) (-1); +@trusted enum HANDLE INVALID_HANDLE_VALUE = cast(HANDLE) (-1); enum : DWORD { GET_TAPE_MEDIA_INFORMATION = 0, diff --git a/libphobos/libdruntime/core/sys/windows/wingdi.d b/libphobos/libdruntime/core/sys/windows/wingdi.d index 5a4eeaa..c7b0c8b 100644 --- a/libphobos/libdruntime/core/sys/windows/wingdi.d +++ b/libphobos/libdruntime/core/sys/windows/wingdi.d @@ -2425,11 +2425,11 @@ struct EMRARC { POINTL ptlEnd; } alias EMRARC* PEMRARC; -alias TypeDef!(EMRARC) EMRARCTO; +alias EMRARC EMRARCTO; alias EMRARCTO* PEMRARCTO; -alias TypeDef!(EMRARC) EMRCHORD; +alias EMRARC EMRCHORD; alias EMRCHORD* PEMRCHORD; -alias TypeDef!(EMRARC) EMRPIE; +alias EMRARC EMRPIE; alias EMRPIE* PEMRPIE; struct XFORM { @@ -2467,7 +2467,7 @@ struct LOGBRUSH { COLORREF lbColor; ULONG_PTR lbHatch; } -alias TypeDef!(LOGBRUSH) PATTERN; +alias LOGBRUSH PATTERN; alias LOGBRUSH* PLOGBRUSH, NPLOGBRUSH, LPLOGBRUSH; alias PATTERN* PPATTERN, NPPATTERN, LPPATTERN; @@ -2559,9 +2559,9 @@ struct EMRSETCOLORSPACE { DWORD ihCS; } alias EMRSETCOLORSPACE* PEMRSETCOLORSPACE; -alias TypeDef!(EMRSETCOLORSPACE) EMRSELECTCOLORSPACE; +alias EMRSETCOLORSPACE EMRSELECTCOLORSPACE; alias EMRSELECTCOLORSPACE* PEMRSELECTCOLORSPACE; -alias TypeDef!(EMRSETCOLORSPACE) EMRDELETECOLORSPACE; +alias EMRSETCOLORSPACE EMRDELETECOLORSPACE; alias EMRDELETECOLORSPACE* PEMRDELETECOLORSPACE; static if (_WIN32_WINNT >= 0x500) { @@ -2573,7 +2573,7 @@ static if (_WIN32_WINNT >= 0x500) { BYTE[1] EscData; } alias EMREXTESCAPE* PEMREXTESCAPE; - alias TypeDef!(EMREXTESCAPE) EMRDRAWESCAPE; + alias EMREXTESCAPE EMRDRAWESCAPE; alias EMRDRAWESCAPE* PEMRDRAWESCAPE; struct EMRNAMEDESCAPE { @@ -2593,9 +2593,9 @@ static if (_WIN32_WINNT >= 0x500) { BYTE[1] Data; } alias EMRSETICMPROFILE* PEMRSETICMPROFILE; - alias TypeDef!(EMRSETICMPROFILE) EMRSETICMPROFILEA; + alias EMRSETICMPROFILE EMRSETICMPROFILEA; alias EMRSETICMPROFILEA* PEMRSETICMPROFILEA; - alias TypeDef!(EMRSETICMPROFILE) EMRSETICMPROFILEW; + alias EMRSETICMPROFILE EMRSETICMPROFILEW; alias EMRSETICMPROFILEW* PEMRSETICMPROFILEW; struct EMRCREATECOLORSPACEW { @@ -2739,7 +2739,7 @@ struct EMRELLIPSE { } alias EMRELLIPSE* PEMRELLIPSE; -alias TypeDef!(EMRELLIPSE) EMRRECTANGLE; +alias EMRELLIPSE EMRRECTANGLE; alias EMRRECTANGLE* PEMRRECTANGLE; struct EMREOF { @@ -2755,7 +2755,7 @@ struct EMREXCLUDECLIPRECT { RECTL rclClip; } alias EMREXCLUDECLIPRECT* PEMREXCLUDECLIPRECT; -alias TypeDef!(EMREXCLUDECLIPRECT) EMRINTERSECTCLIPRECT; +alias EMREXCLUDECLIPRECT EMRINTERSECTCLIPRECT; alias EMRINTERSECTCLIPRECT* PEMRINTERSECTCLIPRECT; struct EMREXTCREATEFONTINDIRECTW { @@ -2833,7 +2833,7 @@ struct EMREXTTEXTOUTA { EMRTEXT emrtext; } alias EMREXTTEXTOUTA* PEMREXTTEXTOUTA; -alias TypeDef!(EMREXTTEXTOUTA) EMREXTTEXTOUTW; +alias EMREXTTEXTOUTA EMREXTTEXTOUTW; alias EMREXTTEXTOUTW* PEMREXTTEXTOUTW; struct EMRFILLPATH { @@ -2842,10 +2842,10 @@ struct EMRFILLPATH { } alias EMRFILLPATH* PEMRFILLPATH; -alias TypeDef!(EMRFILLPATH) EMRSTROKEANDFILLPATH; +alias EMRFILLPATH EMRSTROKEANDFILLPATH; alias EMRSTROKEANDFILLPATH* PEMRSTROKEANDFILLPATH; -alias TypeDef!(EMRFILLPATH) EMRSTROKEPATH; +alias EMRFILLPATH EMRSTROKEPATH; alias EMRSTROKEPATH* PEMRSTROKEPATH; struct EMRFILLRGN { @@ -2889,7 +2889,7 @@ struct EMRINVERTRGN { BYTE[1] RgnData; } alias EMRINVERTRGN* PEMRINVERTRGN; -alias TypeDef!(EMRINVERTRGN) EMRPAINTRGN; +alias EMRINVERTRGN EMRPAINTRGN; alias EMRPAINTRGN* PEMRPAINTRGN; struct EMRLINETO { @@ -2897,7 +2897,7 @@ struct EMRLINETO { POINTL ptl; } alias EMRLINETO* PEMRLINETO; -alias TypeDef!(EMRLINETO) EMRMOVETOEX; +alias EMRLINETO EMRMOVETOEX; alias EMRMOVETOEX* PEMRMOVETOEX; struct EMRMASKBLT { @@ -2990,13 +2990,13 @@ struct EMRPOLYLINE { POINTL[1] aptl; } alias EMRPOLYLINE* PEMRPOLYLINE; -alias TypeDef!(EMRPOLYLINE) EMRPOLYBEZIER; +alias EMRPOLYLINE EMRPOLYBEZIER; alias EMRPOLYBEZIER* PEMRPOLYBEZIER; -alias TypeDef!(EMRPOLYLINE) EMRPOLYGON; +alias EMRPOLYLINE EMRPOLYGON; alias EMRPOLYGON* PEMRPOLYGON; -alias TypeDef!(EMRPOLYLINE) EMRPOLYBEZIERTO; +alias EMRPOLYLINE EMRPOLYBEZIERTO; alias EMRPOLYBEZIERTO* PEMRPOLYBEZIERTO; -alias TypeDef!(EMRPOLYLINE) EMRPOLYLINETO; +alias EMRPOLYLINE EMRPOLYLINETO; alias EMRPOLYLINETO* PEMRPOLYLINETO; struct EMRPOLYLINE16 { @@ -3006,13 +3006,13 @@ struct EMRPOLYLINE16 { POINTS[1] apts; } alias EMRPOLYLINE16* PEMRPOLYLINE16; -alias TypeDef!(EMRPOLYLINE16) EMRPOLYBEZIER16; +alias EMRPOLYLINE16 EMRPOLYBEZIER16; alias EMRPOLYBEZIER16* PEMRPOLYBEZIER16; -alias TypeDef!(EMRPOLYLINE16) EMRPOLYGON16; +alias EMRPOLYLINE16 EMRPOLYGON16; alias EMRPOLYGON16* PEMRPOLYGON16; -alias TypeDef!(EMRPOLYLINE16) EMRPOLYBEZIERTO16; +alias EMRPOLYLINE16 EMRPOLYBEZIERTO16; alias EMRPOLYBEZIERTO16* PEMRPOLYBEZIERTO16; -alias TypeDef!(EMRPOLYLINE16) EMRPOLYLINETO16; +alias EMRPOLYLINE16 EMRPOLYLINETO16; alias EMRPOLYLINETO16* PEMRPOLYLINETO16; struct EMRPOLYPOLYLINE { @@ -3024,7 +3024,7 @@ struct EMRPOLYPOLYLINE { POINTL[1] aptl; } alias EMRPOLYPOLYLINE* PEMRPOLYPOLYLINE; -alias TypeDef!(EMRPOLYPOLYLINE) EMRPOLYPOLYGON; +alias EMRPOLYPOLYLINE EMRPOLYPOLYGON; alias EMRPOLYPOLYGON* PEMRPOLYPOLYGON; struct EMRPOLYPOLYLINE16 { @@ -3036,7 +3036,7 @@ struct EMRPOLYPOLYLINE16 { POINTS[1] apts; } alias EMRPOLYPOLYLINE16* PEMRPOLYPOLYLINE16; -alias TypeDef!(EMRPOLYPOLYLINE16) EMRPOLYPOLYGON16; +alias EMRPOLYPOLYLINE16 EMRPOLYPOLYGON16; alias EMRPOLYPOLYGON16* PEMRPOLYPOLYGON16; struct EMRPOLYTEXTOUTA { @@ -3049,7 +3049,7 @@ struct EMRPOLYTEXTOUTA { EMRTEXT[1] aemrtext; } alias EMRPOLYTEXTOUTA* PEMRPOLYTEXTOUTA; -alias TypeDef!(EMRPOLYTEXTOUTA) EMRPOLYTEXTOUTW; +alias EMRPOLYTEXTOUTA EMRPOLYTEXTOUTW; alias EMRPOLYTEXTOUTW* PEMRPOLYTEXTOUTW; struct EMRRESIZEPALETTE { @@ -3080,7 +3080,7 @@ struct EMRSCALEVIEWPORTEXTEX { LONG yDenom; } alias EMRSCALEVIEWPORTEXTEX* PEMRSCALEVIEWPORTEXTEX; -alias TypeDef!(EMRSCALEVIEWPORTEXTEX) EMRSCALEWINDOWEXTEX; +alias EMRSCALEVIEWPORTEXTEX EMRSCALEWINDOWEXTEX; alias EMRSCALEWINDOWEXTEX* PEMRSCALEWINDOWEXTEX; struct EMRSELECTOBJECT { @@ -3088,7 +3088,7 @@ struct EMRSELECTOBJECT { DWORD ihObject; } alias EMRSELECTOBJECT* PEMRSELECTOBJECT; -alias TypeDef!(EMRSELECTOBJECT) EMRDELETEOBJECT; +alias EMRSELECTOBJECT EMRDELETEOBJECT; alias EMRDELETEOBJECT* PEMRDELETEOBJECT; struct EMRSELECTPALETTE { @@ -3108,7 +3108,7 @@ struct EMRSETTEXTCOLOR { COLORREF crColor; } alias EMRSETTEXTCOLOR* PEMRSETTEXTCOLOR; -alias TypeDef!(EMRSETTEXTCOLOR) EMRSETBKCOLOR; +alias EMRSETTEXTCOLOR EMRSETBKCOLOR; alias EMRSETBKCOLOR* PEMRSETBKCOLOR; struct EMRSETCOLORADJUSTMENT { @@ -3169,7 +3169,7 @@ struct EMRSETVIEWPORTEXTEX { SIZEL szlExtent; } alias EMRSETVIEWPORTEXTEX* PEMRSETVIEWPORTEXTEX; -alias TypeDef!(EMRSETVIEWPORTEXTEX) EMRSETWINDOWEXTEX; +alias EMRSETVIEWPORTEXTEX EMRSETWINDOWEXTEX; alias EMRSETWINDOWEXTEX* PEMRSETWINDOWEXTEX; struct EMRSETVIEWPORTORGEX { @@ -3177,9 +3177,9 @@ struct EMRSETVIEWPORTORGEX { POINTL ptlOrigin; } alias EMRSETVIEWPORTORGEX* PEMRSETVIEWPORTORGEX; -alias TypeDef!(EMRSETVIEWPORTORGEX) EMRSETWINDOWORGEX; +alias EMRSETVIEWPORTORGEX EMRSETWINDOWORGEX; alias EMRSETWINDOWORGEX* PEMRSETWINDOWORGEX; -alias TypeDef!(EMRSETVIEWPORTORGEX) EMRSETBRUSHORGEX; +alias EMRSETVIEWPORTORGEX EMRSETBRUSHORGEX; alias EMRSETBRUSHORGEX* PEMRSETBRUSHORGEX; struct EMRSETWORLDTRANSFORM { @@ -3234,21 +3234,21 @@ struct EMRABORTPATH { EMR emr; } alias EMRABORTPATH* PEMRABORTPATH; -alias TypeDef!(EMRABORTPATH) EMRBEGINPATH; +alias EMRABORTPATH EMRBEGINPATH; alias EMRBEGINPATH* PEMRBEGINPATH; -alias TypeDef!(EMRABORTPATH) EMRENDPATH; +alias EMRABORTPATH EMRENDPATH; alias EMRENDPATH* PEMRENDPATH; -alias TypeDef!(EMRABORTPATH) EMRCLOSEFIGURE; +alias EMRABORTPATH EMRCLOSEFIGURE; alias EMRCLOSEFIGURE* PEMRCLOSEFIGURE; -alias TypeDef!(EMRABORTPATH) EMRFLATTENPATH; +alias EMRABORTPATH EMRFLATTENPATH; alias EMRFLATTENPATH* PEMRFLATTENPATH; -alias TypeDef!(EMRABORTPATH) EMRWIDENPATH; +alias EMRABORTPATH EMRWIDENPATH; alias EMRWIDENPATH* PEMRWIDENPATH; -alias TypeDef!(EMRABORTPATH) EMRSETMETARGN; +alias EMRABORTPATH EMRSETMETARGN; alias EMRSETMETARGN* PEMRSETMETARGN; -alias TypeDef!(EMRABORTPATH) EMRSAVEDC; +alias EMRABORTPATH EMRSAVEDC; alias EMRSAVEDC* PEMRSAVEDC; -alias TypeDef!(EMRABORTPATH) EMRREALIZEPALETTE; +alias EMRABORTPATH EMRREALIZEPALETTE; alias EMRREALIZEPALETTE* PEMRREALIZEPALETTE; struct EMRSELECTCLIPPATH { @@ -3256,24 +3256,24 @@ struct EMRSELECTCLIPPATH { DWORD iMode; } alias EMRSELECTCLIPPATH* PEMRSELECTCLIPPATH; -alias TypeDef!(EMRSELECTCLIPPATH) EMRSETBKMODE; +alias EMRSELECTCLIPPATH EMRSETBKMODE; alias EMRSETBKMODE* PEMRSETBKMODE; -alias TypeDef!(EMRSELECTCLIPPATH) EMRSETMAPMODE; +alias EMRSELECTCLIPPATH EMRSETMAPMODE; alias EMRSETMAPMODE* PEMRSETMAPMODE; -alias TypeDef!(EMRSELECTCLIPPATH) EMRSETPOLYFILLMODE; +alias EMRSELECTCLIPPATH EMRSETPOLYFILLMODE; alias EMRSETPOLYFILLMODE* PEMRSETPOLYFILLMODE; -alias TypeDef!(EMRSELECTCLIPPATH) EMRSETROP2; +alias EMRSELECTCLIPPATH EMRSETROP2; alias EMRSETROP2* PEMRSETROP2; -alias TypeDef!(EMRSELECTCLIPPATH) EMRSETSTRETCHBLTMODE; +alias EMRSELECTCLIPPATH EMRSETSTRETCHBLTMODE; alias EMRSETSTRETCHBLTMODE* PEMRSETSTRETCHBLTMODE; -alias TypeDef!(EMRSELECTCLIPPATH) EMRSETICMMODE; +alias EMRSELECTCLIPPATH EMRSETICMMODE; alias EMRSETICMMODE* PEMRSETICMMODE; -alias TypeDef!(EMRSELECTCLIPPATH) EMRSETTEXTALIGN; +alias EMRSELECTCLIPPATH EMRSETTEXTALIGN; alias EMRSETTEXTALIGN* PEMRSETTEXTALIGN; -alias TypeDef!(EMRSELECTCLIPPATH) EMRENABLEICM; +alias EMRSELECTCLIPPATH EMRENABLEICM; alias EMRENABLEICM* PEMRENABLEICM; static if (_WIN32_WINNT >= 0x500) { - alias TypeDef!(EMRSELECTCLIPPATH) EMRSETLAYOUT; + alias EMRSELECTCLIPPATH EMRSETLAYOUT; alias EMRSETLAYOUT* PEMRSETLAYOUT; } diff --git a/libphobos/libdruntime/core/sys/windows/winuser.d b/libphobos/libdruntime/core/sys/windows/winuser.d index 71cd882..829952d 100644 --- a/libphobos/libdruntime/core/sys/windows/winuser.d +++ b/libphobos/libdruntime/core/sys/windows/winuser.d @@ -3421,7 +3421,7 @@ align(4) LUID luid; } alias BSMINFO* PBSMINFO; - alias TypeDef!(HANDLE) HRAWINPUT; + alias HANDLE HRAWINPUT; struct RAWINPUTHEADER { DWORD dwType; @@ -4155,7 +4155,7 @@ extern (C) { // These shouldn't be necessary for D. -alias TypeDef!(char*) va_list_; +alias char* va_list_; int wvsprintfA(LPSTR, LPCSTR, va_list_ arglist); int wvsprintfW(LPWSTR, LPCWSTR, va_list_ arglist); diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index b0889b6..f3af209 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -748,7 +748,7 @@ class TypeInfo /** Return info used by the garbage collector to do precise collection. */ - @property immutable(void)* rtInfo() nothrow pure const @safe @nogc { return rtinfoHasPointers; } // better safe than sorry + @property immutable(void)* rtInfo() nothrow pure const @trusted @nogc { return rtinfoHasPointers; } // better safe than sorry } @system unittest @@ -2929,6 +2929,25 @@ void clear(Value, Key)(Value[Key]* aa) assert("k1" !in aa); } +// Issue 20559 +@system unittest +{ + static class Foo + { + int[string] aa; + alias aa this; + } + + auto v = new Foo(); + v["Hello World"] = 42; + v.clear; + assert("Hello World" !in v); + + // Test for T* + static assert(!__traits(compiles, (&v).clear)); + static assert( __traits(compiles, (*(&v)).clear)); +} + /*********************************** * Reorganizes the associative array in place so that lookups are more * efficient. @@ -4294,6 +4313,44 @@ void destroy(bool initialize = true, T)(T obj) if (is(T == interface)) @system unittest { + // class with an `alias this` + class A + { + static int dtorCount; + ~this() + { + dtorCount++; + } + } + + class B + { + A a; + alias a this; + this() + { + a = new A; + } + static int dtorCount; + ~this() + { + dtorCount++; + } + } + auto b = new B; + assert(A.dtorCount == 0); + assert(B.dtorCount == 0); + destroy(b); + assert(A.dtorCount == 0); + assert(B.dtorCount == 1); + + auto a = new A; + destroy(a); + assert(A.dtorCount == 1); +} + +@system unittest +{ interface I { } { class A: I { string s = "A"; this() {} } @@ -4505,6 +4562,43 @@ if (__traits(isStaticArray, T)) } } +// https://issues.dlang.org/show_bug.cgi?id=19218 +@system unittest +{ + static struct S + { + static dtorCount = 0; + ~this() { ++dtorCount; } + } + + static interface I + { + ref S[3] getArray(); + alias getArray this; + } + + static class C : I + { + static dtorCount = 0; + ~this() { ++dtorCount; } + + S[3] a; + alias a this; + + ref S[3] getArray() { return a; } + } + + C c = new C(); + destroy(c); + assert(S.dtorCount == 3); + assert(C.dtorCount == 1); + + I i = new C(); + destroy(i); + assert(S.dtorCount == 6); + assert(C.dtorCount == 2); +} + /// ditto void destroy(bool initialize = true, T)(ref T obj) if (!is(T == struct) && !is(T == interface) && !is(T == class) && !__traits(isStaticArray, T)) diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index a5414f16..0424d7b 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -330d6a4fdbe82683e081959d0aeb53597b025bc4 +d7e79f024606f18e989ae8b5fe298f9d07c7dced The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/array.d b/libphobos/src/std/array.d index 2652803..a613a8d 100644 --- a/libphobos/src/std/array.d +++ b/libphobos/src/std/array.d @@ -4700,24 +4700,16 @@ unittest } /++ -Constructs a static array from `a`. -The type of elements can be specified implicitly so that $(D [1, 2].staticArray) results in `int[2]`, -or explicitly, e.g. $(D [1, 2].staticArray!float) returns `float[2]`. -When `a` is a range whose length is not known at compile time, the number of elements must be -given as template argument (e.g. `myrange.staticArray!2`). -Size and type can be combined, if the source range elements are implicitly -convertible to the requested element type (eg: `2.iota.staticArray!(long[2])`). -When the range `a` is known at compile time, it can also be specified as a -template argument to avoid having to specify the number of elements -(e.g.: `staticArray!(2.iota)` or `staticArray!(double, 2.iota)`). +Constructs a static array from a dynamic array whose length is known at compile-time. +The element type can be inferred or specified explicitly: + +* $(D [1, 2].staticArray) returns `int[2]` +* $(D [1, 2].staticArray!float) returns `float[2]` Note: `staticArray` returns by value, so expressions involving large arrays may be inefficient. Params: - a = The input elements. If there are less elements than the specified length of the static array, - the rest of it is default-initialized. If there are more than specified, the first elements - up to the specified length are used. - rangeLength = outputs the number of elements used from `a` to it. Optional. + a = The input array. Returns: A static array constructed from `a`. +/ @@ -4774,7 +4766,23 @@ nothrow pure @safe @nogc unittest [cast(byte) 1, cast(byte) 129].staticArray.checkStaticArray!byte([1, -127]); } -/// ditto +/** +Constructs a static array from a range. +When `a.length` is not known at compile time, the number of elements must be +given as a template argument (e.g. `myrange.staticArray!2`). +Size and type can be combined, if the source range elements are implicitly +convertible to the requested element type (eg: `2.iota.staticArray!(long[2])`). + +When the range `a` is known at compile time, it can be given as a +template argument to avoid having to specify the number of elements +(e.g.: `staticArray!(2.iota)` or `staticArray!(double, 2.iota)`). + +Params: + a = The input range. If there are less elements than the specified length of the static array, + the rest of it is default-initialized. If there are more than specified, the first elements + up to the specified length are used. + rangeLength = Output for the number of elements used from `a`. Optional. +*/ auto staticArray(size_t n, T)(scope T a) if (isInputRange!T) { diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d index aabcd78..4248e4b9 100644 --- a/libphobos/src/std/conv.d +++ b/libphobos/src/std/conv.d @@ -190,8 +190,9 @@ Conversions from string _to numeric types differ from the C equivalents `atoi()` and `atol()` by checking for overflow and not allowing whitespace. For conversion of strings _to signed types, the grammar recognized is: -$(PRE $(I Integer): $(I Sign UnsignedInteger) -$(I UnsignedInteger) +$(PRE $(I Integer): + $(I Sign UnsignedInteger) + $(I UnsignedInteger) $(I Sign): $(B +) $(B -)) @@ -260,7 +261,7 @@ template to(T) } /** - * When converting strings _to numeric types, note that the D hexadecimal and binary + * When converting strings _to numeric types, note that D hexadecimal and binary * literals are not handled. Neither the prefixes that indicate the base, nor the * horizontal bar used _to separate groups of digits are recognized. This also * applies to the suffixes that indicate the type. @@ -397,7 +398,7 @@ template to(T) * $(LI Pointer to string conversions convert the pointer to a `size_t` value. * If pointer is `char*`, treat it as C-style strings. * In that case, this function is `@system`.)) - * See $(REF formatValue, std,format) on how toString should be defined. + * See $(REF formatValue, std,format) on how `toString` should be defined. */ @system pure unittest // @system due to cast and ptr { @@ -423,6 +424,22 @@ template to(T) assert(c == "abcx"); } +/** + * Strings can be converted to enum types. The enum member with the same name as the + * input string is returned. The comparison is case-sensitive. + * + * A $(LREF ConvException) is thrown if the enum does not have the specified member. + */ +@safe pure unittest +{ + import std.exception : assertThrown; + + enum E { a, b, c } + assert(to!E("a") == E.a); + assert(to!E("b") == E.b); + assertThrown!ConvException(to!E("A")); +} + // Tests for https://issues.dlang.org/show_bug.cgi?id=6175 @safe pure nothrow unittest { @@ -2247,19 +2264,21 @@ template roundTo(Target) } /** -The `parse` family of functions works quite like the `to` +$(PANEL +The `parse` family of functions works quite like the $(LREF to) family, except that: $(OL $(LI It only works with character ranges as input.) - $(LI It takes the input by reference. (This means that rvalues - such - as string literals - are not accepted: use `to` instead.)) + $(LI It takes the input by reference. This means that rvalues (such + as string literals) are not accepted: use `to` instead.) $(LI It advances the input to the position following the conversion.) $(LI It does not throw if it could not convert the entire input.)) +) -This overload converts a character input range to a `bool`. +This overload parses a `bool` from a character input range. Params: - Target = the type to convert to + Target = the boolean type to convert to source = the lvalue of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) doCount = the flag for deciding to report the number of consumed characters @@ -2276,9 +2295,9 @@ Note: to `parse` and do not require lvalues. */ auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source source) -if (isInputRange!Source && - isSomeChar!(ElementType!Source) && - is(immutable Target == immutable bool)) +if (is(immutable Target == immutable bool) && + isInputRange!Source && + isSomeChar!(ElementType!Source)) { import std.ascii : toLower; @@ -2377,8 +2396,7 @@ Lerr: } /** -Parses a character $(REF_ALTTEXT input range, isInputRange, std,range,primitives) -to an integral value. +Parses an integer from a character $(REF_ALTTEXT input range, isInputRange, std,range,primitives). Params: Target = the integral type to convert to @@ -2395,8 +2413,8 @@ Throws: if no character of the input was meaningfully converted. */ auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref scope Source s) -if (isSomeChar!(ElementType!Source) && - isIntegral!Target && !is(Target == enum)) +if (isIntegral!Target && !is(Target == enum) && + isSomeChar!(ElementType!Source)) { static if (Target.sizeof < int.sizeof) { @@ -2817,8 +2835,8 @@ Lerr: /// ditto auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source source, uint radix) -if (isSomeChar!(ElementType!Source) && - isIntegral!Target && !is(Target == enum)) +if (isIntegral!Target && !is(Target == enum) && + isSomeChar!(ElementType!Source)) in { assert(radix >= 2 && radix <= 36, "radix must be in range [2,36]"); @@ -2969,7 +2987,7 @@ do } /** - * Takes a string representing an `enum` type and returns that type. + * Parses an `enum` type from a string representing an enum member name. * * Params: * Target = the `enum` type to convert to @@ -2986,8 +3004,7 @@ do * represented by `s`. */ auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s) -if (isSomeString!Source && !is(Source == enum) && - is(Target == enum)) +if (is(Target == enum) && isSomeString!Source && !is(Source == enum)) { import std.algorithm.searching : startsWith; import std.traits : Unqual, EnumMembers; @@ -3079,7 +3096,7 @@ if (isSomeString!Source && !is(Source == enum) && } /** - * Parses a character range to a floating point number. + * Parses a floating point number from a character range. * * Params: * Target = a floating point type @@ -3097,8 +3114,8 @@ if (isSomeString!Source && !is(Source == enum) && * parsed, or if an overflow occurred. */ auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source source) -if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) && - isFloatingPoint!Target && !is(Target == enum)) +if (isFloatingPoint!Target && !is(Target == enum) && + isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum)) { import std.ascii : isDigit, isAlpha, toLower, toUpper, isHexDigit; import std.exception : enforce; @@ -3790,7 +3807,7 @@ if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum } /** -Parsing one character off a range returns the first element and calls `popFront`. +Parses one character from a character range. Params: Target = the type to convert to @@ -3806,8 +3823,8 @@ Throws: A $(LREF ConvException) if the range is empty. */ auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s) -if (isSomeString!Source && !is(Source == enum) && - staticIndexOf!(immutable Target, immutable dchar, immutable ElementEncodingType!Source) >= 0) +if (staticIndexOf!(immutable Target, immutable dchar, immutable ElementEncodingType!Source) >= 0 && + isSomeString!Source && !is(Source == enum)) { if (s.empty) throw convError!(Source, Target)(s); @@ -3863,8 +3880,8 @@ if (isSomeString!Source && !is(Source == enum) && /// ditto auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s) -if (!isSomeString!Source && isInputRange!Source && isSomeChar!(ElementType!Source) && - isSomeChar!Target && Target.sizeof >= ElementType!Source.sizeof && !is(Target == enum)) +if (isSomeChar!Target && Target.sizeof >= ElementType!Source.sizeof && !is(Target == enum) && + !isSomeString!Source && isInputRange!Source && isSomeChar!(ElementType!Source)) { if (s.empty) throw convError!(Source, Target)(s); @@ -3931,7 +3948,7 @@ if (!isSomeString!Source && isInputRange!Source && isSomeChar!(ElementType!Sourc } /** -Parsing a character range to `typeof(null)` returns `null` if the range +Parses `typeof(null)` from a character range if the range spells `"null"`. This function is case insensitive. Params: @@ -3948,9 +3965,9 @@ Throws: A $(LREF ConvException) if the range doesn't represent `null`. */ auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s) -if (isInputRange!Source && - isSomeChar!(ElementType!Source) && - is(immutable Target == immutable typeof(null))) +if (is(immutable Target == immutable typeof(null)) && + isInputRange!Source && + isSomeChar!(ElementType!Source)) { import std.ascii : toLower; foreach (c; "null") @@ -4062,8 +4079,8 @@ package auto skipWS(R, Flag!"doCount" doCount = No.doCount)(ref R r) */ auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar comma = ',') -if (isSomeString!Source && !is(Source == enum) && - isDynamicArray!Target && !is(Target == enum)) +if (isDynamicArray!Target && !is(Target == enum) && + isSomeString!Source && !is(Source == enum)) { import std.array : appender; @@ -4249,8 +4266,8 @@ if (isSomeString!Source && !is(Source == enum) && /// ditto auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar comma = ',') -if (isExactSomeString!Source && - isStaticArray!Target && !is(Target == enum)) +if (isStaticArray!Target && !is(Target == enum) && + isExactSomeString!Source) { static if (hasIndirections!Target) Target result = Target.init[0].init; @@ -4358,8 +4375,8 @@ Lfewerr: */ auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar keyval = ':', dchar comma = ',') -if (isSomeString!Source && !is(Source == enum) && - isAssociativeArray!Target && !is(Target == enum)) +if (isAssociativeArray!Target && !is(Target == enum) && + isSomeString!Source && !is(Source == enum)) { alias KeyType = typeof(Target.init.keys[0]); alias ValType = typeof(Target.init.values[0]); diff --git a/libphobos/src/std/digest/md.d b/libphobos/src/std/digest/md.d index 0c4e42b..f4d6200 100644 --- a/libphobos/src/std/digest/md.d +++ b/libphobos/src/std/digest/md.d @@ -295,7 +295,8 @@ struct MD5 */ void put(scope const(ubyte)[] data...) @trusted pure nothrow @nogc { - uint i, index, partLen; + size_t i; + uint index, partLen; auto inputLen = data.length; //Compute number of bytes mod 64 diff --git a/libphobos/src/std/digest/sha.d b/libphobos/src/std/digest/sha.d index 5bbf7ea..5c7c3d5 100644 --- a/libphobos/src/std/digest/sha.d +++ b/libphobos/src/std/digest/sha.d @@ -650,7 +650,9 @@ struct SHA(uint hashBlockSize, uint digestSize) void put(scope const(ubyte)[] input...) @trusted pure nothrow @nogc { enum blockSizeInBytes = blockSize/8; - uint i, index, partLen; + + size_t i; + uint index, partLen; auto inputLen = input.length; /* Compute number of bytes mod block size (64 or 128 bytes) */ diff --git a/libphobos/src/std/exception.d b/libphobos/src/std/exception.d index 1d93d35..5c78685 100644 --- a/libphobos/src/std/exception.d +++ b/libphobos/src/std/exception.d @@ -416,13 +416,16 @@ void assertThrown(T : Throwable = Exception, E) Returns: `value`, if `cast(bool) value` is true. Otherwise, depending on the chosen overload, `new Exception(msg)`, `dg()` or `ex` is thrown. - Note: - `enforce` is used to throw exceptions and is therefore intended to + $(PANEL + $(NOTE `enforce` is used to throw exceptions and is therefore intended to aid in error handling. It is $(I not) intended for verifying the logic - of your program. That is what `assert` is for. Also, do not use + of your program - that is what `assert` is for.) + + Do not use `enforce` inside of contracts (i.e. inside of `in` and `out` blocks and `invariant`s), because contracts are compiled out when compiling with $(I -release). + ) If a delegate is passed, the safety and purity of this function are inferred from `Dg`'s safety and purity. @@ -836,7 +839,7 @@ string letters() ) The use in the example above is correct because `result` -was private to `letters` and is inaccessible in writing +was private to `letters` and the memory it referenced can no longer be written to after the function returns. The following example shows an incorrect use of `assumeUnique`. @@ -859,8 +862,8 @@ string letters(char first, char last) ---- ) -The example above wreaks havoc on client code because it is -modifying arrays that callers considered immutable. To obtain an +The example above wreaks havoc on client code because it modifies the +returned array that the previous caller considered immutable. To obtain an immutable array from the writable array `buffer`, replace the last line with: @@ -868,13 +871,14 @@ the last line with: return to!(string)(sneaky); // not that sneaky anymore ---- -The call will duplicate the array appropriately. +The `to` call will duplicate the array appropriately. -Note that checking for uniqueness during compilation is +$(PANEL +$(NOTE Checking for uniqueness during compilation is possible in certain cases, especially when a function is -marked as a pure function. The following example does not +marked (or inferred) as `pure`. The following example does not need to call `assumeUnique` because the compiler can infer the -uniqueness of the array in the pure function: +uniqueness of the array in the pure function:) $(RUNNABLE_EXAMPLE ---- @@ -894,6 +898,7 @@ For more on infering uniqueness see the $(B unique) and $(B lent) keywords in the $(HTTP www.cs.cmu.edu/~aldrich/papers/aldrich-dissertation.pdf, ArchJava) language. +) The downside of using `assumeUnique`'s convention-based usage is that at this time there is no diff --git a/libphobos/src/std/format/internal/write.d b/libphobos/src/std/format/internal/write.d index 8eb70ea..85954fa 100644 --- a/libphobos/src/std/format/internal/write.d +++ b/libphobos/src/std/format/internal/write.d @@ -2529,35 +2529,37 @@ if ((is(T == struct) || is(T == union)) && (hasToString!(T, Char) || !is(Builtin enum right = ")"; put(w, left); - foreach (i, e; val.tupleof) - { + static foreach (i; 0 .. T.tupleof.length) + {{ static if (__traits(identifier, val.tupleof[i]) == "this") - continue; - else static if (0 < i && val.tupleof[i-1].offsetof == val.tupleof[i].offsetof) { - static if (i == val.tupleof.length - 1 || val.tupleof[i].offsetof != val.tupleof[i+1].offsetof) + // ignore hidden context pointer + } + else static if (0 < i && T.tupleof[i-1].offsetof == T.tupleof[i].offsetof) + { + static if (i == T.tupleof.length - 1 || T.tupleof[i].offsetof != T.tupleof[i+1].offsetof) { - enum el = separator ~ val.tupleof[i].stringof[4 .. $] ~ "}"; + enum el = separator ~ __traits(identifier, T.tupleof[i]) ~ "}"; put(w, el); } else { - enum el = separator ~ val.tupleof[i].stringof[4 .. $]; + enum el = separator ~ __traits(identifier, T.tupleof[i]); put(w, el); } } - else static if (i+1 < val.tupleof.length && val.tupleof[i].offsetof == val.tupleof[i+1].offsetof) + else static if (i+1 < T.tupleof.length && T.tupleof[i].offsetof == T.tupleof[i+1].offsetof) { - enum el = (i > 0 ? separator : "") ~ "#{overlap " ~ val.tupleof[i].stringof[4 .. $]; + enum el = (i > 0 ? separator : "") ~ "#{overlap " ~ __traits(identifier, T.tupleof[i]); put(w, el); } else { static if (i > 0) put(w, separator); - formatElement(w, e, f); + formatElement(w, val.tupleof[i], f); } - } + }} put(w, right); } else @@ -2660,7 +2662,7 @@ if ((is(T == struct) || is(T == union)) && (hasToString!(T, Char) || !is(Builtin { int n; string s; - string toString() const { return s; } + string toString() @trusted const { return s; } } U2 u2; () @trusted { u2.s = "hello"; } (); diff --git a/libphobos/src/std/int128.d b/libphobos/src/std/int128.d index fc992f8..b20fa1f 100644 --- a/libphobos/src/std/int128.d +++ b/libphobos/src/std/int128.d @@ -18,8 +18,8 @@ private import core.int128; public struct Int128 { - @safe pure nothrow @nogc: - + @safe pure nothrow @nogc + { Cent data; /// core.int128.Cent /**************** @@ -153,6 +153,7 @@ public struct Int128 { return tst(this.data); } + } // @safe pure nothrow @nogc /** Support binary arithmetic operators + - * / % & | ^ << >> >>> * Params: @@ -190,21 +191,49 @@ public struct Int128 } /// ditto - Int128 opBinary(string op)(long op2) const - if (op == "+" || op == "-" || + Int128 opBinary(string op, Int)(const Int op2) const + if ((op == "+" || op == "-" || op == "*" || op == "/" || op == "%" || - op == "&" || op == "|" || op == "^") + op == "&" || op == "|" || op == "^") && + is(Int : long) && __traits(isIntegral, Int)) { - return mixin("this " ~ op ~ " Int128(0, op2)"); + static if (__traits(isUnsigned, Int)) + return mixin("this " ~ op ~ " Int128(0, op2)"); + else + return mixin("this " ~ op ~ " Int128((cast(long) op2) >> 63 , op2)"); } /// ditto - Int128 opBinaryRight(string op)(long op2) const - if (op == "+" || op == "-" || + Int128 opBinary(string op, IntLike)(auto ref IntLike op2) const + if ((op == "+" || op == "-" || op == "*" || op == "/" || op == "%" || - op == "&" || op == "|" || op == "^") + op == "&" || op == "|" || op == "^") && + is(IntLike : long) && !__traits(isIntegral, IntLike)) + { + return opBinary!(op)(__traits(getMember, op2, __traits(getAliasThis, IntLike)[0])); + } + + /// ditto + Int128 opBinaryRight(string op, Int)(const Int op2) const + if ((op == "+" || op == "-" || + op == "*" || op == "/" || op == "%" || + op == "&" || op == "|" || op == "^") && + is(Int : long) && __traits(isIntegral, Int)) + { + static if (__traits(isUnsigned, Int)) + mixin("return Int128(0, op2) " ~ op ~ " this;"); + else + mixin("return Int128((cast(long) op2) >> 63, op2) " ~ op ~ " this;"); + } + + /// ditto + Int128 opBinaryRight(string op, IntLike)(auto ref IntLike op2) const + if ((op == "+" || op == "-" || + op == "*" || op == "/" || op == "%" || + op == "&" || op == "|" || op == "^") && + is(IntLike : long) && !__traits(isIntegral, IntLike)) { - mixin("return Int128(0, op2) " ~ op ~ " this;"); + return opBinaryRight!(op)(__traits(getMember, op2, __traits(getAliasThis, IntLike)[0])); } /// ditto @@ -244,32 +273,182 @@ public struct Int128 } /// ditto - ref Int128 opOpAssign(string op)(long op2) - if (op == "+" || op == "-" || + ref Int128 opOpAssign(string op, Int)(auto ref Int op2) + if ((op == "+" || op == "-" || op == "*" || op == "/" || op == "%" || op == "&" || op == "|" || op == "^" || op == "<<" || op == ">>" || op == ">>>") + && is(Int : long)) { mixin("this = this " ~ op ~ " op2;"); return this; } - /** support signed arithmentic comparison operators < <= > >= + /** support arithmentic comparison operators < <= > >= * Params: op2 = right hand operand * Returns: -1 for less than, 0 for equals, 1 for greater than */ - int opCmp(Int128 op2) const + int opCmp(Int128 op2) const @nogc nothrow pure @safe { return this == op2 ? 0 : gt(this.data, op2.data) * 2 - 1; } - /** support signed arithmentic comparison operators < <= > >= - * Params: op2 = right hand operand - * Returns: -1 for less than, 0 for equals, 1 for greater than + /// ditto + int opCmp(Int)(const Int op2) const @nogc nothrow pure @safe + if (is(Int : long) && __traits(isIntegral, Int)) + { + static if (__traits(isUnsigned, Int)) + return opCmp(Int128(0, op2)); + else + return opCmp(Int128((cast(long) op2) >> 63, op2)); + } + + /// ditto + int opCmp(IntLike)(auto ref IntLike op2) const + if (is(IntLike : long) && !__traits(isIntegral, IntLike)) + { + return opCmp(__traits(getMember, op2, __traits(getAliasThis, IntLike)[0])); + } + + /** + * Formats `Int128` with either `%d`, `%x`, `%X`, or `%s` (same as `%d`). + * + * Params: + * sink = $(REF_ALTTEXT Output range, isOutputRange, std, range, primitives) + * to write to. + * fmt = A $(REF FormatSpec, std,format) which controls how the number + * is displayed. + * + * Throws: + * $(REF FormatException, std,format) if the format specifier is + * not one of 'd', 'x', 'X', 's'. + * + * See_Also: $(REF formatValue, std,format) */ - int opCmp(long op2) const + void toString(Writer, FormatSpec)(scope ref Writer sink, scope const ref FormatSpec fmt) const { - return opCmp(Int128(0, op2)); + import std.range.primitives : put; + import std.format : FormatException, Fmt = FormatSpec; + + static if (is(FormatSpec == Fmt!Char, Char)) + { + // Puts "Char" into scope if the pattern matches. + } + static assert(is(Char), + "Expecting `FormatSpec` to be instantiation of `std.format.FormatSpec`"); + + Char[39] buf = void; + size_t bufStart = void; + Char signChar = 0; + if (fmt.spec == 'd' || fmt.spec == 's') + { + const bool isNeg = 0 > cast(long) this.data.hi; + Cent val = isNeg ? neg(this.data) : this.data; + immutable Cent radix = { lo: 10, hi: 0 }; + Cent modulus; + bufStart = buf.length; + do + { + uint x = void; + if (ugt(radix, val)) + { + x = cast(uint) val.lo; + val = Cent(0, 0); + } + else + { + val = udivmod(val, radix, modulus); + x = cast(uint) modulus.lo; + } + buf[--bufStart] = cast(Char) ('0' + x); + } while (tst(val)); + if (isNeg) + signChar = '-'; + else if (fmt.flPlus) + signChar = '+'; + else if (fmt.flSpace) + signChar = ' '; + } + else if (fmt.spec == 'x' || fmt.spec == 'X') + { + immutable hexDigits = fmt.spec == 'X' ? "0123456789ABCDEF" : "0123456789abcdef"; + ulong a = data.lo; + bufStart = buf.length - 1; + size_t penPos = buf.length - 1; + do + { + if ((buf[penPos] = hexDigits[0xF & cast(uint) a]) != '0') + bufStart = penPos; + a >>>= 4; + } while (--penPos >= buf.length - 16); + a = data.hi; + do + { + if ((buf[penPos] = hexDigits[0xF & cast(uint) a]) != '0') + bufStart = penPos; + a >>>= 4; + } while (--penPos >= buf.length - 32); + } + else + { + throw new FormatException("Format specifier not understood: %" ~ fmt.spec); + } + + const minw = (buf.length - bufStart) + int(signChar != 0); + const maxw = minw < fmt.width ? fmt.width : minw; + const difw = maxw - minw; + + static void putRepeatedChars(Char c)(scope ref Writer sink, size_t n) + { + static immutable Char[8] array = [c, c, c, c, c, c, c, c]; + foreach (_; 0 .. n / 8) + put(sink, array[0 .. 8]); + if (n & 7) + put(sink, array[0 .. n & 7]); + } + + if (!fmt.flDash && !fmt.flZero && difw) + putRepeatedChars!' '(sink, difw); + + if (signChar) + { + Char[1] signCharBuf = signChar; + put(sink, signCharBuf[0 .. 1]); + } + + if (!fmt.flDash && fmt.flZero && difw) + putRepeatedChars!'0'(sink, difw); + + put(sink, buf[bufStart .. $]); + + if (fmt.flDash && difw) + putRepeatedChars!' '(sink, difw); + } + + /** + `toString` is rarely directly invoked; the usual way of using it is via + $(REF format, std, format): + */ + @safe unittest + { + import std.format : format; + + assert(format("%s", Int128.max) == "170141183460469231731687303715884105727"); + assert(format("%s", Int128.min) == "-170141183460469231731687303715884105728"); + assert(format("%x", Int128.max) == "7fffffffffffffffffffffffffffffff"); + assert(format("%X", Int128.max) == "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); + assert(format("%032X", Int128(123L)) == "0000000000000000000000000000007B"); + assert(format("%+ 40d", Int128(123L)) == " +123"); + assert(format("%+-40d", Int128(123L)) == "+123 "); + } + + /// Also can format as `wchar` or `dchar`. + @safe unittest + { + import std.conv : to; + + assert(to!wstring(Int128.max) == "170141183460469231731687303715884105727"w); + assert(to!dstring(Int128.max) == "170141183460469231731687303715884105727"d); } enum min = Int128(long.min, 0); /// minimum value @@ -372,3 +551,59 @@ unittest c = Int128(-1L); assert(c == -1L); } + +@system unittest +{ + alias Seq(T...) = T; + Int128 c = Int128(-1L); + assert(c.opCmp(-1L) == 0); + // To avoid regression calling opCmp with any integral type needs to + // work without the compiler complaining "opCmp called with argument + // X matches both <...>". + static foreach (Int; Seq!(long, int, short, byte, ulong, uint, ushort, ubyte, dchar, wchar, char)) + assert(c < Int.max); + static foreach (Int; Seq!(int, short, byte)) + assert(c.opCmp(Int(-1)) == 0); + assert(c < true); + // To avoid regression calling opCmp with any type that converts to an + // integral type through alias this needs to work regardless of whether + // the alias is safe/pure/nothrow/nogc and regardless of whether the + // type has a disabled postblit. + static struct Wrapped(T) + { + T value; + uint count; + T get() @system { ++count; return value; } // not const + alias get this; + @disable this(this); // no implicit copies + } + assert(c.opCmp(Wrapped!long(-1)) == 0); + auto w = Wrapped!ulong(ulong.max); + w.count++; // avoid invalid D-Scanner message that w could have been declared const + assert(c < w); + + const zero = Int128(0L); + const one = Int128(1L); + const neg_one = Int128(-1L); + const neg_two = Int128(-2L); + // Correct result with ulong.max: + assert(zero + ulong.max == ulong.max); + assert(one * ulong.max == ulong.max); + assert((neg_one & ulong.max) == ulong.max); + assert((zero | ulong.max) == ulong.max); + assert((zero ^ ulong.max) == ulong.max); + // Correct result with negative arguments: + assert(zero + -1L == -1L); + assert(neg_two * -3L == 6L); + assert(neg_two / -2L == 1L); + assert(neg_two % -2L == 0L); + assert((neg_one & -1L) == -1L); + assert((zero | -1L) == -1L); + assert((zero ^ -1L) == -1L); + // Ensure alias this still works. + { + Int128 a = zero; + assert((a ^= w) == ulong.max); + } + assert((Wrapped!long(-1L) + zero) == -1L); +} diff --git a/libphobos/src/std/json.d b/libphobos/src/std/json.d index 7d48890..6e94a5d 100644 --- a/libphobos/src/std/json.d +++ b/libphobos/src/std/json.d @@ -70,25 +70,25 @@ String literals used to represent special float values within JSON strings. */ enum JSONFloatLiteral : string { - nan = "NaN", /// string representation of floating-point NaN - inf = "Infinite", /// string representation of floating-point Infinity - negativeInf = "-Infinite", /// string representation of floating-point negative Infinity + nan = "NaN", /// String representation of floating-point NaN + inf = "Infinite", /// String representation of floating-point Infinity + negativeInf = "-Infinite", /// String representation of floating-point negative Infinity } /** -Flags that control how json is encoded and parsed. +Flags that control how JSON is encoded and parsed. */ enum JSONOptions { - none, /// standard parsing - specialFloatLiterals = 0x1, /// encode NaN and Inf float values as strings - escapeNonAsciiChars = 0x2, /// encode non ascii characters with an unicode escape sequence - doNotEscapeSlashes = 0x4, /// do not escape slashes ('/') + none, /// Standard parsing and encoding + specialFloatLiterals = 0x1, /// Encode NaN and Inf float values as strings + escapeNonAsciiChars = 0x2, /// Encode non-ASCII characters with a Unicode escape sequence + doNotEscapeSlashes = 0x4, /// Do not escape slashes ('/') strictParsing = 0x8, /// Strictly follow RFC-8259 grammar when parsing } /** -JSON type enumeration +Enumeration of JSON types */ enum JSONType : byte { @@ -275,7 +275,7 @@ struct JSONValue * Value getter/setter for `JSONType.object`. * Throws: `JSONException` for read access if `type` is not * `JSONType.object`. - * Note: this is @system because of the following pattern: + * Note: This is @system because of the following pattern: --- auto a = &(json.object()); json.uinteger = 0; // overwrite AA pointer @@ -297,9 +297,11 @@ struct JSONValue /*** * Value getter for `JSONType.object`. - * Unlike `object`, this retrieves the object by value and can be used in @safe code. + * Unlike `object`, this retrieves the object by value + * and can be used in @safe code. * - * A caveat is that, if the returned value is null, modifications will not be visible: + * One possible caveat is that, if the returned value is null, + * modifications will not be visible: * --- * JSONValue json; * json.object = null; @@ -321,7 +323,7 @@ struct JSONValue * Value getter/setter for `JSONType.array`. * Throws: `JSONException` for read access if `type` is not * `JSONType.array`. - * Note: this is @system because of the following pattern: + * Note: This is @system because of the following pattern: --- auto a = &(json.array()); json.uinteger = 0; // overwrite array pointer @@ -345,8 +347,8 @@ struct JSONValue * Value getter for `JSONType.array`. * Unlike `array`, this retrieves the array by value and can be used in @safe code. * - * A caveat is that, if you append to the returned array, the new values aren't visible in the - * JSONValue: + * One possible caveat is that, if you append to the returned array, + * the new values aren't visible in the `JSONValue`: * --- * JSONValue json; * json.array = [JSONValue("hello")]; @@ -371,9 +373,8 @@ struct JSONValue } /*** - * Generic type value getter * A convenience getter that returns this `JSONValue` as the specified D type. - * Note: only numeric, `bool`, `string`, `JSONValue[string]` and `JSONValue[]` types are accepted + * Note: Only numeric types, `bool`, `string`, `JSONValue[string]`, and `JSONValue[]` types are accepted * Throws: `JSONException` if `T` cannot hold the contents of this `JSONValue` * `ConvException` in case of integer overflow when converting to `T` */ @@ -659,7 +660,7 @@ struct JSONValue } /*** - * Array syntax for json arrays. + * Array syntax for JSON arrays. * Throws: `JSONException` if `type` is not `JSONType.array`. */ ref inout(JSONValue) opIndex(size_t i) inout pure @safe @@ -678,7 +679,7 @@ struct JSONValue } /*** - * Hash syntax for json objects. + * Hash syntax for JSON objects. * Throws: `JSONException` if `type` is not `JSONType.object`. */ ref inout(JSONValue) opIndex(return scope string k) inout pure @safe @@ -695,10 +696,12 @@ struct JSONValue } /*** - * Operator sets `value` for element of JSON object by `key`. + * Provides support for index assignments, which sets the + * corresponding value of the JSON object's `key` field to `value`. * - * If JSON value is null, then operator initializes it with object and then - * sets `value` for it. + * If the `JSONValue` is `JSONType.null_`, then this function + * initializes it with a JSON object and then performs + * the index assignment. * * Throws: `JSONException` if `type` is not `JSONType.object` * or `JSONType.null_`. @@ -777,12 +780,12 @@ struct JSONValue } /** - * Support for the `in` operator. + * Provides support for the `in` operator. * - * Tests wether a key can be found in an object. + * Tests whether a key can be found in an object. * * Returns: - * when found, the `inout(JSONValue)*` that matches to the key, + * When found, the `inout(JSONValue)*` that matches to the key, * otherwise `null`. * * Throws: `JSONException` if the right hand side argument `JSONType` diff --git a/libphobos/src/std/math/package.d b/libphobos/src/std/math/package.d index b5f914a..614f4d3 100644 --- a/libphobos/src/std/math/package.d +++ b/libphobos/src/std/math/package.d @@ -3,7 +3,7 @@ /** * Contains the elementary mathematical functions (powers, roots, * and trigonometric functions), and low-level floating-point operations. - * Mathematical special functions are available in `std.mathspecial`. + * Mathematical special functions are available in $(MREF std, mathspecial). * $(SCRIPT inhibitQuickIndex = 1;) diff --git a/libphobos/src/std/range/package.d b/libphobos/src/std/range/package.d index 191ec32..1b4f233 100644 --- a/libphobos/src/std/range/package.d +++ b/libphobos/src/std/range/package.d @@ -1384,7 +1384,7 @@ if (Ranges.length > 0 && // force staticMap type conversion to Rebindable static struct ResultRanges { - staticMap!(Rebindable, Ranges) fields; + staticMap!(Rebindable, typeof(source)) fields; } auto sourceI(size_t i)() => rebindable(this.source[i]); auto resultRanges = ResultRanges(staticMap!(sourceI, aliasSeqOf!(R.length.iota))).fields; @@ -1672,6 +1672,17 @@ pure @safe unittest assert(range.array == [S(5), S(6)]); } +/// https://issues.dlang.org/show_bug.cgi?id=24064 +pure @safe nothrow unittest +{ + import std.algorithm.comparison : equal; + import std.typecons : Nullable; + + immutable Nullable!string foo = "b"; + string[] bar = ["a"]; + assert(chain(bar, foo).equal(["a", "b"])); +} + pure @safe nothrow @nogc unittest { // support non-copyable items diff --git a/libphobos/src/std/regex/internal/ir.d b/libphobos/src/std/regex/internal/ir.d index 3b38f9c..069d75f 100644 --- a/libphobos/src/std/regex/internal/ir.d +++ b/libphobos/src/std/regex/internal/ir.d @@ -1045,7 +1045,7 @@ if (!hasElaborateDestructor!T) return isBig ? big.ptr[0 .. length] : small[0 .. length]; } - this(this) + this(this) @trusted { if (isBig) { diff --git a/libphobos/src/std/socket.d b/libphobos/src/std/socket.d index 3359c8e..4052479 100644 --- a/libphobos/src/std/socket.d +++ b/libphobos/src/std/socket.d @@ -181,16 +181,13 @@ string formatSocketError(int err) @trusted return "Socket error " ~ to!string(err); } -/// Retrieve the error message for the most recently encountered network error. +/// Returns the error message of the most recently encountered network error. @property string lastSocketError() { return formatSocketError(_lasterr()); } -/** - * Socket exceptions representing network errors reported by the operating - * system. - */ +/// Socket exception representing network errors reported by the operating system. class SocketOSException: SocketException { int errorCode; /// Platform-specific error code. @@ -234,14 +231,14 @@ class SocketOSException: SocketException } } -/// Socket exceptions representing invalid parameters specified by user code. +/// Socket exception representing invalid parameters specified by user code. class SocketParameterException: SocketException { mixin basicExceptionCtors; } /** - * Socket exceptions representing attempts to use network capabilities not + * Socket exception representing attempts to use network capabilities not * available on the current system. */ class SocketFeatureException: SocketException @@ -254,7 +251,7 @@ class SocketFeatureException: SocketException * Returns: * `true` if the last socket operation failed because the socket * was in non-blocking mode and the operation would have blocked, - * or if the socket is in blocking mode and set a SNDTIMEO or RCVTIMEO, + * or if the socket is in blocking mode and set a `SNDTIMEO` or `RCVTIMEO`, * and the operation timed out. */ bool wouldHaveBlocked() nothrow @nogc @@ -334,7 +331,7 @@ shared static ~this() @system nothrow @nogc enum AddressFamily: ushort { UNSPEC = AF_UNSPEC, /// Unspecified address family - UNIX = AF_UNIX, /// Local communication + UNIX = AF_UNIX, /// Local communication (Unix socket) INET = AF_INET, /// Internet Protocol version 4 IPX = AF_IPX, /// Novell IPX APPLETALK = AF_APPLETALK, /// AppleTalk @@ -374,7 +371,7 @@ enum ProtocolType: int /** - * `Protocol` is a class for retrieving protocol information. + * Class for retrieving protocol information. * * Example: * --- @@ -473,7 +470,7 @@ version (CRuntime_Bionic) {} else /** - * `Service` is a class for retrieving service information. + * Class for retrieving service information. * * Example: * --- @@ -618,7 +615,7 @@ class HostException: SocketOSException } /** - * `InternetHost` is a class for resolving IPv4 addresses. + * Class for resolving IPv4 addresses. * * Consider using `getAddress`, `parseAddress` and `Address` methods * instead of using this class directly. @@ -1220,7 +1217,7 @@ class AddressException: SocketOSException /** - * `Address` is an abstract class for representing a socket addresses. + * Abstract class for representing a socket address. * * Example: * --- @@ -1402,7 +1399,7 @@ abstract class Address } /** - * `UnknownAddress` encapsulates an unknown socket address. + * Encapsulates an unknown socket address. */ class UnknownAddress: Address { @@ -1431,7 +1428,7 @@ public: /** - * `UnknownAddressReference` encapsulates a reference to an arbitrary + * Encapsulates a reference to an arbitrary * socket address. */ class UnknownAddressReference: Address @@ -1474,8 +1471,7 @@ public: /** - * `InternetAddress` encapsulates an IPv4 (Internet Protocol version 4) - * socket address. + * Encapsulates an IPv4 (Internet Protocol version 4) socket address. * * Consider using `getAddress`, `parseAddress` and `Address` methods * instead of using this class directly. @@ -1624,7 +1620,8 @@ public: } /** - * Compares with another InternetAddress of same type for equality + * Provides support for comparing equality with another + * InternetAddress of the same type. * Returns: true if the InternetAddresses share the same address and * port number. */ @@ -1728,8 +1725,7 @@ public: /** - * `Internet6Address` encapsulates an IPv6 (Internet Protocol version 6) - * socket address. + * Encapsulates an IPv6 (Internet Protocol version 6) socket address. * * Consider using `getAddress`, `parseAddress` and `Address` methods * instead of using this class directly. @@ -1913,8 +1909,8 @@ version (StdDdoc) } /** - * `UnixAddress` encapsulates an address for a Unix domain socket - * (`AF_UNIX`), i.e. a socket bound to a path name in the file system. + * Encapsulates an address for a Unix domain socket (`AF_UNIX`), + * i.e. a socket bound to a path name in the file system. * Available only on supported systems. * * Linux also supports an abstract address namespace, in which addresses @@ -2111,7 +2107,7 @@ static if (is(sockaddr_un)) /** - * Class for exceptions thrown by `Socket.accept`. + * Exception thrown by `Socket.accept`. */ class SocketAcceptException: SocketOSException { @@ -2127,7 +2123,7 @@ enum SocketShutdown: int } -/// Flags may be OR'ed together: +/// Socket flags that may be OR'ed together: enum SocketFlags: int { NONE = 0, /// no flags specified @@ -2622,7 +2618,7 @@ enum SocketOption: int /** - * `Socket` is a class that creates a network communication endpoint using + * Class that creates a network communication endpoint using * the Berkeley sockets interface. */ class Socket @@ -2969,7 +2965,7 @@ public: /** - * Returns: the local machine's host name + * Returns: The local machine's host name */ static @property string hostName() @trusted // getter { @@ -3518,7 +3514,7 @@ public: /** * Can be overridden to support other addresses. - * Returns: a new `Address` object for the current address family. + * Returns: A new `Address` object for the current address family. */ protected Address createAddress() pure nothrow { @@ -3549,7 +3545,7 @@ public: } -/// `TcpSocket` is a shortcut class for a TCP Socket. +/// Shortcut class for a TCP Socket. class TcpSocket: Socket { /// Constructs a blocking TCP Socket. @@ -3566,7 +3562,7 @@ class TcpSocket: Socket //shortcut - /// Constructs a blocking TCP Socket and connects to an `Address`. + /// Constructs a blocking TCP Socket and connects to the given `Address`. this(Address connectTo) { this(connectTo.addressFamily); @@ -3575,7 +3571,7 @@ class TcpSocket: Socket } -/// `UdpSocket` is a shortcut class for a UDP Socket. +/// Shortcut class for a UDP Socket. class UdpSocket: Socket { /// Constructs a blocking UDP Socket. diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d index d9291b1..40dc854 100644 --- a/libphobos/src/std/stdio.d +++ b/libphobos/src/std/stdio.d @@ -122,17 +122,12 @@ alias KeepTerminator = Flag!"keepTerminator"; version (CRuntime_Microsoft) { - version = MICROSOFT_STDIO; } else version (CRuntime_DigitalMars) { - // Specific to the way Digital Mars C does stdio - version = DIGITAL_MARS_STDIO; } else version (CRuntime_Glibc) { - // Specific to the way Gnu C does stdio - version = GCC_IO; } else version (CRuntime_Bionic) { @@ -220,7 +215,7 @@ version (Posix) static import core.sys.posix.stdio; // getdelim, flockfile } -version (DIGITAL_MARS_STDIO) +version (CRuntime_DigitalMars) { private alias _FPUTC = _fputc_nlock; private alias _FPUTWC = _fputwc_nlock; @@ -229,7 +224,7 @@ version (DIGITAL_MARS_STDIO) private alias _FLOCK = __fp_lock; private alias _FUNLOCK = __fp_unlock; - // Alias for MICROSOFT_STDIO compatibility. + // Alias for CRuntime_Microsoft compatibility. // @@@DEPRECATED_2.107@@@ // Rename this back to _setmode once the deprecation phase has ended. private alias __setmode = setmode; @@ -267,7 +262,7 @@ version (DIGITAL_MARS_STDIO) ~ "std.stdio and will be removed afer 2.107") fileno_t _fileno(FILE* f) { return f._file; } } -else version (MICROSOFT_STDIO) +else version (CRuntime_Microsoft) { private alias _FPUTC = _fputc_nolock; private alias _FPUTWC = _fputwc_nolock; @@ -277,7 +272,7 @@ else version (MICROSOFT_STDIO) private alias _FUNLOCK = _unlock_file; // @@@DEPRECATED_2.107@@@ - // Remove this once the deprecation phase for DIGITAL_MARS_STDIO has ended. + // Remove this once the deprecation phase for CRuntime_DigitalMars has ended. private alias __setmode = _setmode; // @@@DEPRECATED_2.107@@@ @@ -305,7 +300,7 @@ else version (MICROSOFT_STDIO) ~ "std.stdio and will be removed afer 2.107") alias FUNLOCK = _unlock_file; } -else version (GCC_IO) +else version (CRuntime_Glibc) { private alias _FPUTC = fputc_unlocked; private alias _FPUTWC = fputwc_unlocked; @@ -419,7 +414,7 @@ private extern (C) @nogc nothrow { pragma(mangle, _FPUTC.mangleof) int trustedFPUTC(int ch, _iobuf* h) @trusted; - version (DIGITAL_MARS_STDIO) + version (CRuntime_DigitalMars) pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(int ch, _iobuf* h) @trusted; else pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(wchar_t ch, _iobuf* h) @trusted; @@ -598,7 +593,7 @@ Throws: `ErrnoException` if the file could not be opened. name); // MSVCRT workaround (https://issues.dlang.org/show_bug.cgi?id=14422) - version (MICROSOFT_STDIO) + version (CRuntime_Microsoft) { setAppendWin(stdioOpenmode); } @@ -726,7 +721,7 @@ Throws: `ErrnoException` in case of error. } _p = cast(Impl*) enforce(malloc(Impl.sizeof), "Out of memory"); initImpl(handle, name, 1, isPopened); - version (MICROSOFT_STDIO) + version (CRuntime_Microsoft) { setAppendWin(stdioOpenmode); } @@ -761,7 +756,7 @@ Throws: `ErrnoException` in case of error. } } - version (MICROSOFT_STDIO) + version (CRuntime_Microsoft) { private void setAppendWin(scope const(char)[] stdioOpenmode) @safe { @@ -894,7 +889,7 @@ Params: auto modez = stdioOpenmode.tempCString(); detach(); - version (DIGITAL_MARS_STDIO) + version (CRuntime_DigitalMars) { // This is a re-implementation of DMC's fdopen, but without the // mucking with the file descriptor. POSIX standard requires the @@ -909,17 +904,20 @@ Params: iob._flag &= ~_IOTRAN; _FUNLOCK(fp); } - else + else version (CRuntime_Microsoft) { - version (Windows) // MSVCRT - auto fp = _fdopen(fd, modez); - else version (Posix) - { - import core.sys.posix.stdio : fdopen; - auto fp = fdopen(fd, modez); - } + auto fp = _fdopen(fd, modez); errnoEnforce(fp); } + else version (Posix) + { + import core.sys.posix.stdio : fdopen; + auto fp = fdopen(fd, modez); + errnoEnforce(fp); + } + else + static assert(0, "no fdopen() available"); + this = File(fp, name); } @@ -945,7 +943,7 @@ Throws: `ErrnoException` in case of error. import std.format : format; // Create file descriptors from the handles - version (DIGITAL_MARS_STDIO) + version (CRuntime_DigitalMars) auto fd = _handleToFD(handle, FHND_DEVICE); else // MSVCRT { @@ -1190,7 +1188,7 @@ Throws: `ErrnoException` if the file is not opened or the call to `fread` fails. immutable fileno_t fd = .fileno(_p.handle); immutable mode = .__setmode(fd, _O_BINARY); scope(exit) .__setmode(fd, mode); - version (DIGITAL_MARS_STDIO) + version (CRuntime_DigitalMars) { import core.atomic : atomicOp; @@ -1288,7 +1286,7 @@ Throws: `ErrnoException` if the file is not opened or if the call to `fwrite` fa .__setmode(fd, _O_BINARY); } - version (DIGITAL_MARS_STDIO) + version (CRuntime_DigitalMars) { import core.atomic : atomicOp; @@ -2351,7 +2349,7 @@ Returns the underlying operating system `HANDLE` (Windows only). version (Windows) @property HANDLE windowsHandle() { - version (DIGITAL_MARS_STDIO) + version (CRuntime_DigitalMars) return _fdToHandle(fileno); else return cast(HANDLE)_get_osfhandle(fileno); @@ -3147,7 +3145,7 @@ is empty, throws an `Exception`. In case of an I/O error throws file_ = f; FILE* fps = f._p.handle; - version (MICROSOFT_STDIO) + version (CRuntime_Microsoft) { // Microsoft doesn't implement fwide. Instead, there's the // concept of ANSI/UNICODE mode. fputc doesn't work in UNICODE @@ -3388,7 +3386,7 @@ is empty, throws an `Exception`. In case of an I/O error throws { fileno_t fd; int oldMode; - version (DIGITAL_MARS_STDIO) + version (CRuntime_DigitalMars) ubyte oldInfo; } @@ -3410,7 +3408,7 @@ is empty, throws an `Exception`. In case of an I/O error throws .fflush(fps); // before changing translation mode fd = .fileno(fps); oldMode = .__setmode(fd, _O_BINARY); - version (DIGITAL_MARS_STDIO) + version (CRuntime_DigitalMars) { import core.atomic : atomicOp; @@ -3431,7 +3429,7 @@ is empty, throws an `Exception`. In case of an I/O error throws version (Windows) { .fflush(fps); // before restoring translation mode - version (DIGITAL_MARS_STDIO) + version (CRuntime_DigitalMars) { // https://issues.dlang.org/show_bug.cgi?id=4243 __fhnd_info[fd] = oldInfo; @@ -3889,7 +3887,7 @@ void main() return setlocale(LC_CTYPE, loc.ptr).fromStringz.endsWith(loc); }); scope(exit) () @trusted { setlocale(LC_CTYPE, oldCt); } (); - version (DIGITAL_MARS_STDIO) // DM can't handle Unicode above U+07FF. + version (CRuntime_DigitalMars) // DM can't handle Unicode above U+07FF. { alias strs = AliasSeq!("xä\u07FE", "yö\u07FF"w); } @@ -3899,7 +3897,7 @@ void main() } { auto f = File(deleteme, "w"); - version (MICROSOFT_STDIO) + version (CRuntime_Microsoft) { () @trusted { __setmode(fileno(f.getFP()), _O_U8TEXT); } (); } @@ -5539,7 +5537,7 @@ private struct LockedFile // Private implementation of readln private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation) @safe { - version (DIGITAL_MARS_STDIO) + version (CRuntime_DigitalMars) return () @trusted { auto lf = LockedFile(fps); ReadlnAppender app; @@ -5652,7 +5650,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie buf = app.data; return buf.length; }(); - else version (MICROSOFT_STDIO) + else version (CRuntime_Microsoft) { auto lf = LockedFile(fps); diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d index 4dc569d..2ed7ee5 100644 --- a/libphobos/src/std/traits.d +++ b/libphobos/src/std/traits.d @@ -1125,7 +1125,7 @@ if (isCallable!func && variadicFunctionStyle!func == Variadic.no) } /** -Get tuple, one per function parameter, of the storage classes of the parameters. +Get a tuple of the storage classes of a function's parameters. Params: func = function symbol or type of function, delegate, or pointer to function Returns: @@ -1154,22 +1154,16 @@ if (isCallable!func) static if (is(Func PT == __parameters)) { - template StorageClass(size_t i) + alias ParameterStorageClassTuple = AliasSeq!(); + static foreach (i; 0 .. PT.length) { - static if (i < PT.length) - { - alias StorageClass = AliasSeq!( - extractParameterStorageClassFlags!(__traits(getParameterStorageClasses, Func, i)), - StorageClass!(i + 1)); - } - else - alias StorageClass = AliasSeq!(); + ParameterStorageClassTuple = AliasSeq!(ParameterStorageClassTuple, + extractParameterStorageClassFlags!(__traits(getParameterStorageClasses, Func, i))); } - alias ParameterStorageClassTuple = StorageClass!0; } else { - static assert(0, func[0].stringof ~ " is not a function"); + static assert(0, func.stringof, " is not a function"); alias ParameterStorageClassTuple = AliasSeq!(); } } @@ -1317,7 +1311,8 @@ if (isCallable!func) { static if (is(FunctionTypeOf!func PT == __parameters)) { - template Get(size_t i) + alias ParameterIdentifierTuple = AliasSeq!(); + static foreach (i; 0 .. PT.length) { static if (!isFunctionPointer!func && !isDelegate!func // Unnamed parameters yield CT error. @@ -1325,32 +1320,21 @@ if (isCallable!func) // Filter out unnamed args, which look like (Type) instead of (Type name). && PT[i].stringof != PT[i .. i+1].stringof[1..$-1]) { - enum Get = __traits(identifier, PT[i .. i+1]); + ParameterIdentifierTuple = AliasSeq!(ParameterIdentifierTuple, + __traits(identifier, PT[i .. i+1])); } else { - enum Get = ""; + ParameterIdentifierTuple = AliasSeq!(ParameterIdentifierTuple, ""); } } } else { static assert(0, func.stringof ~ " is not a function"); - - // Define dummy entities to avoid pointless errors - template Get(size_t i) { enum Get = ""; } - alias PT = AliasSeq!(); - } - - template Impl(size_t i = 0) - { - static if (i == PT.length) - alias Impl = AliasSeq!(); - else - alias Impl = AliasSeq!(Get!i, Impl!(i+1)); + // avoid pointless errors + alias ParameterIdentifierTuple = AliasSeq!(); } - - alias ParameterIdentifierTuple = Impl!(); } /// @@ -1408,7 +1392,7 @@ if (isCallable!func) /** -Get, as a tuple, the default value of the parameters to a function symbol. +Get, as a tuple, the default values of the parameters to a function symbol. If a parameter doesn't have the default value, `void` is returned instead. */ template ParameterDefaults(alias func) @@ -1426,48 +1410,36 @@ if (isCallable!func) enum args = "args" ~ (name == "args" ? "_" : ""); enum val = "val" ~ (name == "val" ? "_" : ""); enum ptr = "ptr" ~ (name == "ptr" ? "_" : ""); - mixin(" - enum hasDefaultArg = (PT[i .. i+1] " ~ args ~ ") { return true; }; - "); + enum hasDefaultArg = mixin("(PT[i .. i+1] ", args, ") => true"); static if (is(typeof(hasDefaultArg()))) { - mixin(" - // workaround scope escape check, see - // https://issues.dlang.org/show_bug.cgi?id=16582 - // should use return scope once available - enum get = (PT[i .. i+1] " ~ args ~ ") @trusted + enum get = mixin("(return scope PT[i .. i+1] ", args, ") { // If the parameter is lazy, we force it to be evaluated // like this. - auto " ~ val ~ " = " ~ args ~ "[0]; - auto " ~ ptr ~ " = &" ~ val ~ "; - return *" ~ ptr ~ "; - };"); + auto ", val, " = ", args, "[0]; + auto ", ptr, " = &", val, "; + return *", ptr, "; + }"); enum Get = get(); } else alias Get = void; // If default arg doesn't exist, returns void instead. } + alias ParameterDefaults = AliasSeq!(); + static foreach (i; 0 .. PT.length) + { + ParameterDefaults = AliasSeq!(ParameterDefaults, + Get!i); + } } else { static assert(0, func.stringof ~ " is not a function"); - - // Define dummy entities to avoid pointless errors - template Get(size_t i) { enum Get = ""; } - alias PT = AliasSeq!(); + // avoid pointless errors + alias ParameterDefaults = AliasSeq!(); } - - template Impl(size_t i = 0) - { - static if (i == PT.length) - alias Impl = AliasSeq!(); - else - alias Impl = AliasSeq!(Get!i, Impl!(i+1)); - } - - alias ParameterDefaults = Impl!(); } /// diff --git a/libphobos/src/std/uni/package.d b/libphobos/src/std/uni/package.d index 6ab6ba0..9903d6c 100644 --- a/libphobos/src/std/uni/package.d +++ b/libphobos/src/std/uni/package.d @@ -7697,6 +7697,15 @@ public: static assert(false, "No operation "~op~" defined for Grapheme"); } + // This is not a good `opEquals`, but formerly the automatically generated + // opEquals was used, which was inferred `@safe` because of bugzilla 20655: + // https://issues.dlang.org/show_bug.cgi?id=20655 + // This `@trusted opEquals` is only here to prevent breakage. + bool opEquals(R)(const auto ref R other) const @trusted + { + return this.tupleof == other.tupleof; + } + /++ True if this object contains valid extended grapheme cluster. Decoding primitives of this module always return a valid `Grapheme`. |