diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-12-15 19:47:02 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-12-15 19:51:30 +0100 |
commit | fd43568cc54e17c8b4a845677872c6282bc6dbb7 (patch) | |
tree | 24f591392a2978706aef4d58e377b8b42b5ba418 /libphobos | |
parent | 639ece7abfa3688008cb791aec4c7a1a4f76e59f (diff) | |
download | gcc-fd43568cc54e17c8b4a845677872c6282bc6dbb7.zip gcc-fd43568cc54e17c8b4a845677872c6282bc6dbb7.tar.gz gcc-fd43568cc54e17c8b4a845677872c6282bc6dbb7.tar.bz2 |
d: Merge upstream dmd 93108bb9e, druntime 6364e010, phobos 575b67a9b.
D front-end changes:
- Import dmd v2.098.1-beta.1.
- Default extern(C++) compatibility to C++17.
Druntime changes:
- Import druntime v2.098.1-beta.1.
- Fix definition of stat_t on MIPS64 (PR103604)
Phobos changes:
- Import phobos v2.098.1-beta.1.
gcc/d/ChangeLog:
* d-lang.cc (d_init_options): Set default -fextern-std= to C++17.
* dmd/MERGE: Merge upstream dmd 93108bb9e.
* gdc.texi (Runtime Options): Document the default for -fextern-std=.
libphobos/ChangeLog:
PR d/103604
* configure: Regenerate.
* configure.ac (libtool_VERSION): Update to 3:0:0.
* libdruntime/MERGE: Merge upstream druntime 6364e010.
* src/MERGE: Merge upstream phobos 575b67a9b.
* testsuite/libphobos.traits/all_satisfy.d: New test.
* testsuite/libphobos.traits/traits.exp: New test.
Diffstat (limited to 'libphobos')
-rwxr-xr-x | libphobos/configure | 2 | ||||
-rw-r--r-- | libphobos/configure.ac | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/MERGE | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/core/internal/traits.d | 40 | ||||
-rw-r--r-- | libphobos/libdruntime/core/lifetime.d | 109 | ||||
-rw-r--r-- | libphobos/libdruntime/core/runtime.d | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/core/sys/openbsd/execinfo.d | 139 | ||||
-rw-r--r-- | libphobos/libdruntime/core/sys/posix/sys/stat.d | 46 | ||||
-rw-r--r-- | libphobos/libdruntime/object.d | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/rt/monitor_.d | 36 | ||||
-rw-r--r-- | libphobos/src/MERGE | 2 | ||||
-rw-r--r-- | libphobos/src/std/algorithm/searching.d | 12 | ||||
-rw-r--r-- | libphobos/src/std/datetime/timezone.d | 3 | ||||
-rw-r--r-- | libphobos/src/std/parallelism.d | 6 | ||||
-rw-r--r-- | libphobos/src/std/regex/package.d | 16 | ||||
-rw-r--r-- | libphobos/src/std/traits.d | 5 | ||||
-rw-r--r-- | libphobos/testsuite/libphobos.traits/all_satisfy.d | 24 | ||||
-rw-r--r-- | libphobos/testsuite/libphobos.traits/traits.exp | 27 |
18 files changed, 239 insertions, 236 deletions
diff --git a/libphobos/configure b/libphobos/configure index 14298a0..17b2656 100755 --- a/libphobos/configure +++ b/libphobos/configure @@ -15566,7 +15566,7 @@ SPEC_PHOBOS_DEPS="$LIBS" # Libdruntime / phobos soname version -libtool_VERSION=2:0:0 +libtool_VERSION=3:0:0 # Set default flags (after DRUNTIME_WERROR!) diff --git a/libphobos/configure.ac b/libphobos/configure.ac index 3b5a830..c961e68 100644 --- a/libphobos/configure.ac +++ b/libphobos/configure.ac @@ -265,7 +265,7 @@ SPEC_PHOBOS_DEPS="$LIBS" AC_SUBST(SPEC_PHOBOS_DEPS) # Libdruntime / phobos soname version -libtool_VERSION=2:0:0 +libtool_VERSION=3:0:0 AC_SUBST(libtool_VERSION) # Set default flags (after DRUNTIME_WERROR!) diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index edb1017..b3da906 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -bc58b1e9ea68051af9094651a26313371297b79f +6364e010bc87f3621028c8ac648133535c126fb3 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/core/internal/traits.d b/libphobos/libdruntime/core/internal/traits.d index 60d9be3..0d733f2 100644 --- a/libphobos/libdruntime/core/internal/traits.d +++ b/libphobos/libdruntime/core/internal/traits.d @@ -185,22 +185,38 @@ template dtorIsNothrow(T) } // taken from std.meta.allSatisfy -enum allSatisfy(alias pred, items...) = +template allSatisfy(alias F, T...) { - static foreach (item; items) - static if (!pred!item) - if (__ctfe) return false; - return true; -}(); + static foreach (Ti; T) + { + static if (!is(typeof(allSatisfy) == bool) && // not yet defined + !F!(Ti)) + { + enum allSatisfy = false; + } + } + static if (!is(typeof(allSatisfy) == bool)) // if not yet defined + { + enum allSatisfy = true; + } +} // taken from std.meta.anySatisfy -enum anySatisfy(alias pred, items...) = +template anySatisfy(alias F, Ts...) { - static foreach (item; items) - static if (pred!item) - if (__ctfe) return true; - return false; -}(); + static foreach (T; Ts) + { + static if (!is(typeof(anySatisfy) == bool) && // not yet defined + F!T) + { + enum anySatisfy = true; + } + } + static if (!is(typeof(anySatisfy) == bool)) // if not yet defined + { + enum anySatisfy = false; + } +} // simplified from std.traits.maxAlignment template maxAlignment(Ts...) diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d index b45e95f..8fb61a5 100644 --- a/libphobos/libdruntime/core/lifetime.d +++ b/libphobos/libdruntime/core/lifetime.d @@ -2111,9 +2111,6 @@ private T trustedMoveImpl(T)(return scope ref T source) @trusted // target must be first-parameter, because in void-functions DMD + dip1000 allows it to take the place of a return-scope private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source) { - import core.stdc.string : memcpy, memset; - import core.internal.traits; - // TODO: this assert pulls in half of phobos. we need to work out an alternative assert strategy. // static if (!is(T == class) && hasAliasing!T) if (!__ctfe) // { @@ -2124,11 +2121,16 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source) static if (is(T == struct)) { + import core.internal.traits; + // Unsafe when compiling without -preview=dip1000 assert((() @trusted => &source !is &target)(), "source and target must not be identical"); static if (hasElaborateAssign!T || !isAssignable!T) + { + import core.stdc.string : memcpy; () @trusted { memcpy(&target, &source, T.sizeof); }(); + } else target = source; @@ -2146,15 +2148,21 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source) enum sz = T.sizeof; static if (__traits(isZeroInit, T)) + { + import core.stdc.string : memset; () @trusted { memset(&source, 0, sz); }(); + } else + { + import core.stdc.string : memcpy; () @trusted { memcpy(&source, __traits(initSymbol, T).ptr, sz); }(); + } } } else static if (__traits(isStaticArray, T)) { for (size_t i = 0; i < source.length; ++i) - move(source[i], target[i]); + moveEmplaceImpl(target[i], source[i]); } else { @@ -2204,6 +2212,34 @@ pure nothrow @nogc @system unittest assert(val == 0); } +@betterC +pure nothrow @nogc @system unittest +{ + static struct Foo + { + pure nothrow @nogc: + this(int* ptr) { _ptr = ptr; } + ~this() { if (_ptr) ++*_ptr; } + int* _ptr; + } + + int val; + { + Foo[1] foo1 = void; // uninitialized + Foo[1] foo2 = [Foo(&val)];// initialized + assert(foo2[0]._ptr is &val); + + // Using `move(foo2, foo1)` would have an undefined effect because it would destroy + // the uninitialized foo1. + // moveEmplace directly overwrites foo1 without destroying or initializing it first. + moveEmplace(foo2, foo1); + assert(foo1[0]._ptr is &val); + assert(foo2[0]._ptr is null); + assert(val == 0); + } + assert(val == 1); +} + // issue 18913 @safe unittest { @@ -2222,17 +2258,10 @@ pure nothrow @nogc @system unittest f(move(ncarray)); } -/** - * This is called for a delete statement where the value - * being deleted is a pointer to a struct with a destructor - * but doesn't have an overloaded delete operator. - * - * Params: - * p = pointer to the value to be deleted - */ -void _d_delstruct(T)(ref T *p) +/// Implementation of `_d_delstruct` and `_d_delstructTrace` +template _d_delstructImpl(T) { - if (p) + private void _d_delstructImpure(ref T p) { debug(PRINTF) printf("_d_delstruct(%p)\n", p); @@ -2242,21 +2271,61 @@ void _d_delstruct(T)(ref T *p) GC.free(p); p = null; } + + /** + * This is called for a delete statement where the value being deleted is a + * pointer to a struct with a destructor but doesn't have an overloaded + * `delete` operator. + * + * Params: + * p = pointer to the value to be deleted + * + * Bugs: + * This function template was ported from a much older runtime hook that + * bypassed safety, purity, and throwabilty checks. To prevent breaking + * existing code, this function template is temporarily declared + * `@trusted` until the implementation can be brought up to modern D + * expectations. + */ + void _d_delstruct(ref T p) @trusted @nogc pure nothrow + { + if (p) + { + alias Type = void function(ref T P) @nogc pure nothrow; + (cast(Type) &_d_delstructImpure)(p); + } + } + + import core.internal.array.utils : _d_HookTraceImpl; + + private enum errorMessage = "Cannot delete struct if compiling without support for runtime type information!"; + + /** + * TraceGC wrapper around $(REF _d_delstruct, core,lifetime,_d_delstructImpl). + * + * Bugs: + * This function template was ported from a much older runtime hook that + * bypassed safety, purity, and throwabilty checks. To prevent breaking + * existing code, this function template is temporarily declared + * `@trusted` until the implementation can be brought up to modern D + * expectations. + */ + alias _d_delstructTrace = _d_HookTraceImpl!(T, _d_delstruct, errorMessage); } -@system unittest +@system pure nothrow unittest { int dtors = 0; struct S { ~this() { ++dtors; } } S *s = new S(); - _d_delstruct(s); + _d_delstructImpl!(typeof(s))._d_delstruct(s); assert(s == null); assert(dtors == 1); } -@system unittest +@system pure unittest { int innerDtors = 0; int outerDtors = 0; @@ -2277,16 +2346,16 @@ void _d_delstruct(T)(ref T *p) { ++outerDtors; - _d_delstruct(i1); + _d_delstructImpl!(typeof(i1))._d_delstruct(i1); assert(i1 == null); - _d_delstruct(i2); + _d_delstructImpl!(typeof(i2))._d_delstruct(i2); assert(i2 == null); } } Outer *o = new Outer(0); - _d_delstruct(o); + _d_delstructImpl!(typeof(o))._d_delstruct(o); assert(o == null); assert(innerDtors == 2); diff --git a/libphobos/libdruntime/core/runtime.d b/libphobos/libdruntime/core/runtime.d index b08ec52..81d2d26 100644 --- a/libphobos/libdruntime/core/runtime.d +++ b/libphobos/libdruntime/core/runtime.d @@ -798,7 +798,7 @@ else static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInf enum CALL_INSTRUCTION_SIZE = 1; static if (__traits(compiles, backtrace((void**).init, int.init))) - numframes = backtrace(this.callstack.ptr, MAXFRAMES); + numframes = cast(int) backtrace(this.callstack.ptr, MAXFRAMES); // Backtrace succeeded, adjust the frame to point to the caller if (numframes >= 2) foreach (ref elem; this.callstack) diff --git a/libphobos/libdruntime/core/sys/openbsd/execinfo.d b/libphobos/libdruntime/core/sys/openbsd/execinfo.d index f5b317f..cd9cd16 100644 --- a/libphobos/libdruntime/core/sys/openbsd/execinfo.d +++ b/libphobos/libdruntime/core/sys/openbsd/execinfo.d @@ -11,137 +11,10 @@ module core.sys.openbsd.execinfo; version (OpenBSD): extern (C): nothrow: +@nogc: -version (GNU) - version = BacktraceExternal; - -version (BacktraceExternal) -{ - size_t backtrace(void**, size_t); - char** backtrace_symbols(const(void*)*, size_t); - void backtrace_symbols_fd(const(void*)*, size_t, int); - char** backtrace_symbols_fmt(const(void*)*, size_t, const char*); - int backtrace_symbols_fd_fmt(const(void*)*, size_t, int, const char*); -} -else -{ - import core.sys.openbsd.dlfcn; - - // Use extern (D) so that these functions don't collide with libexecinfo. - - extern (D) int backtrace(void** buffer, int size) - { - import core.thread : thread_stackBottom; - - void** p, pend=cast(void**)thread_stackBottom(); - version (D_InlineAsm_X86) - asm nothrow @trusted { mov p[EBP], EBP; } - else version (D_InlineAsm_X86_64) - asm nothrow @trusted { mov p[RBP], RBP; } - else - static assert(false, "Architecture not supported."); - - int i; - for (; i < size && p < pend; ++i) - { - buffer[i] = *(p + 1); - auto pnext = cast(void**)*p; - if (pnext <= p) break; - p = pnext; - } - return i; - } - - - extern (D) char** backtrace_symbols(const(void*)* buffer, int size) - { - static void* realloc(void* p, size_t len) nothrow - { - static import cstdlib=core.stdc.stdlib; - auto res = cstdlib.realloc(p, len); - if (res is null) cstdlib.free(p); - return res; - } - - if (size <= 0) return null; - - size_t pos = size * (char*).sizeof; - char** p = cast(char**)realloc(null, pos); - if (p is null) return null; - - Dl_info info; - foreach (i, addr; buffer[0 .. size]) - { - if (dladdr(addr, &info) == 0) - (cast(ubyte*)&info)[0 .. info.sizeof] = 0; - fixupDLInfo(addr, info); - - immutable len = formatStackFrame(null, 0, addr, info); - assert(len > 0); - - p = cast(char**)realloc(p, pos + len); - if (p is null) return null; - - formatStackFrame(cast(char*)p + pos, len, addr, info) == len || assert(0); - - p[i] = cast(char*)pos; - pos += len; - } - foreach (i; 0 .. size) - { - pos = cast(size_t)p[i]; - p[i] = cast(char*)p + pos; - } - return p; - } - - - extern (D) void backtrace_symbols_fd(const(void*)* buffer, int size, int fd) - { - import core.sys.posix.unistd : write; - import core.stdc.stdlib : alloca; - - if (size <= 0) return; - - Dl_info info; - foreach (i, addr; buffer[0 .. size]) - { - if (dladdr(addr, &info) == 0) - (cast(ubyte*)&info)[0 .. info.sizeof] = 0; - fixupDLInfo(addr, info); - - enum maxAlloca = 1024; - enum min = (size_t a, size_t b) => a <= b ? a : b; - immutable len = min(formatStackFrame(null, 0, addr, info), maxAlloca); - assert(len > 0); - - auto p = cast(char*)alloca(len); - if (p is null) return; - - formatStackFrame(p, len, addr, info) >= len || assert(0); - p[len - 1] = '\n'; - write(fd, p, len); - } - } - - - private void fixupDLInfo(const(void)* addr, ref Dl_info info) - { - if (info.dli_fname is null) info.dli_fname = "???"; - if (info.dli_fbase is null) info.dli_fbase = null; - if (info.dli_sname is null) info.dli_sname = "???"; - if (info.dli_saddr is null) info.dli_saddr = cast(void*)addr; - } - - - private size_t formatStackFrame(char* p, size_t plen, const(void)* addr, const ref Dl_info info) - { - import core.stdc.stdio : snprintf; - - immutable off = addr - info.dli_saddr; - immutable len = snprintf(p, plen, "%p <%s+%zd> at %s", - addr, info.dli_sname, off, info.dli_fname); - assert(len > 0); - return cast(size_t)len + 1; // + '\0' - } -} +size_t backtrace(void**, size_t); +char** backtrace_symbols(const(void*)*, size_t); +void backtrace_symbols_fd(const(void*)*, size_t, int); +char** backtrace_symbols_fmt(const(void*)*, size_t, const char*); +int backtrace_symbols_fd_fmt(const(void*)*, size_t, int, const char*); diff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d index 6b4d022..7d0b170 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/stat.d +++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d @@ -340,26 +340,23 @@ version (CRuntime_Glibc) } c_long[14] st_pad5; } + static if (!__USE_FILE_OFFSET64) + static assert(stat_t.sizeof == 144); + else + static assert(stat_t.sizeof == 160); } else version (MIPS64) { struct stat_t { - c_ulong st_dev; + dev_t st_dev; int[3] st_pad1; - static if (!__USE_FILE_OFFSET64) - { - ino_t st_ino; - } - else - { - c_ulong st_ino; - } + ino_t st_ino; mode_t st_mode; nlink_t st_nlink; uid_t st_uid; gid_t st_gid; - c_ulong st_rdev; + dev_t st_rdev; static if (!__USE_FILE_OFFSET64) { uint[2] st_pad2; @@ -368,8 +365,8 @@ version (CRuntime_Glibc) } else { - c_long[3] st_pad2; - c_long st_size; + uint[3] st_pad2; + off_t st_size; } static if (__USE_MISC || __USE_XOPEN2K8) { @@ -394,15 +391,26 @@ version (CRuntime_Glibc) } blksize_t st_blksize; uint st_pad4; + blkcnt_t st_blocks; + int[14] st_pad5; + } + version (MIPS_N32) + { static if (!__USE_FILE_OFFSET64) - { - blkcnt_t st_blocks; - } + static assert(stat_t.sizeof == 160); else - { - c_long st_blocks; - } - c_long[14] st_pad5; + static assert(stat_t.sizeof == 176); + } + else version (MIPS_O64) + { + static if (!__USE_FILE_OFFSET64) + static assert(stat_t.sizeof == 160); + else + static assert(stat_t.sizeof == 176); + } + else + { + static assert(stat_t.sizeof == 216); } } else version (PPC) diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index fee19ae..29b5d58 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -4651,7 +4651,7 @@ public import core.internal.array.construction : _d_arrayctor; public import core.internal.array.construction : _d_arraysetctor; public import core.internal.array.capacity: _d_arraysetlengthTImpl; -public import core.lifetime : _d_delstruct; +public import core.lifetime : _d_delstructImpl; public import core.internal.dassert: _d_assert_fail; diff --git a/libphobos/libdruntime/rt/monitor_.d b/libphobos/libdruntime/rt/monitor_.d index 763f439..0f1d0e9 100644 --- a/libphobos/libdruntime/rt/monitor_.d +++ b/libphobos/libdruntime/rt/monitor_.d @@ -6,10 +6,6 @@ * Authors: Walter Bright, Sean Kelly, Martin Nowak * Source: $(DRUNTIMESRC rt/_monitor_.d) */ - -/* NOTE: This file has been patched from the original DMD distribution to - * work with the GDC compiler. - */ module rt.monitor_; import core.atomic, core.stdc.stdlib, core.stdc.string; @@ -175,37 +171,7 @@ package: alias IMonitor = Object.Monitor; alias DEvent = void delegate(Object); -version (GNU) -{ - import gcc.config; - static if (GNU_Thread_Model == ThreadModel.Single) - version = SingleThreaded; - // Ignore ThreadModel, we don't want posix threads on windows and - // will always use native threading instead. -} - -version (SingleThreaded) -{ -@nogc: - alias Mutex = int; - - void initMutex(Mutex* mtx) - { - } - - void destroyMutex(Mutex* mtx) - { - } - - void lockMutex(Mutex* mtx) - { - } - - void unlockMutex(Mutex* mtx) - { - } -} -else version (Windows) +version (Windows) { version (CRuntime_DigitalMars) { diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 68fefcb..c9d166b 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -12329adb67fb43891d6e4e543e7257bc34db0aa7 +575b67a9b4f78415f96ca77ad50b2de4c667cc74 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/algorithm/searching.d b/libphobos/src/std/algorithm/searching.d index 9635206..55a1438 100644 --- a/libphobos/src/std/algorithm/searching.d +++ b/libphobos/src/std/algorithm/searching.d @@ -638,7 +638,7 @@ Returns: */ size_t count(alias pred = "a == b", Range, E)(Range haystack, E needle) if (isInputRange!Range && !isInfinite!Range && - is(typeof(binaryFun!pred(haystack.front, needle)) : bool)) + is(typeof(binaryFun!pred(haystack.front, needle)))) { bool pred2(ElementType!Range a) { return binaryFun!pred(a, needle); } return count!pred2(haystack); @@ -693,7 +693,7 @@ if (isInputRange!Range && !isInfinite!Range && size_t count(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle) if (isForwardRange!R1 && !isInfinite!R1 && isForwardRange!R2 && - is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool)) + is(typeof(binaryFun!pred(haystack.front, needle.front)))) { assert(!needle.empty, "Cannot count occurrences of an empty range"); @@ -716,7 +716,7 @@ if (isForwardRange!R1 && !isInfinite!R1 && /// Ditto size_t count(alias pred, R)(R haystack) if (isInputRange!R && !isInfinite!R && - is(typeof(unaryFun!pred(haystack.front)) : bool)) + is(typeof(unaryFun!pred(haystack.front)))) { size_t result; alias T = ElementType!R; //For narrow strings forces dchar iteration @@ -745,6 +745,12 @@ if (isInputRange!R && !isInfinite!R) assert([1, 2, 3].count([2, 3]) == 1); } +// https://issues.dlang.org/show_bug.cgi?id=22582 +@safe unittest +{ + assert([1, 2, 3].count!"a & 1" == 2); +} + /++ Counts elements in the given $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) diff --git a/libphobos/src/std/datetime/timezone.d b/libphobos/src/std/datetime/timezone.d index a55411b..28255f4 100644 --- a/libphobos/src/std/datetime/timezone.d +++ b/libphobos/src/std/datetime/timezone.d @@ -2464,7 +2464,8 @@ public: if (!tzName.extension().empty || !tzName.startsWith(subName) || baseName(tzName) == "leapseconds" || - tzName == "+VERSION") + tzName == "+VERSION" || + tzName == "SECURITY") { continue; } diff --git a/libphobos/src/std/parallelism.d b/libphobos/src/std/parallelism.d index bd467d2..971cfa0 100644 --- a/libphobos/src/std/parallelism.d +++ b/libphobos/src/std/parallelism.d @@ -2738,7 +2738,7 @@ public: immutable size_t nBytesNeeded = nWorkUnits * RTask.sizeof; import core.stdc.stdlib : malloc, free; - if (nBytesNeeded < maxStack) + if (nBytesNeeded <= maxStack) { tasks = (cast(RTask*) buf.ptr)[0 .. nWorkUnits]; } @@ -3045,11 +3045,11 @@ public: Since the underlying data for this struct is heap-allocated, this struct has reference semantics when passed between functions. - The main uses cases for `WorkerLocalStorageStorage` are: + The main uses cases for `WorkerLocalStorage` are: 1. Performing parallel reductions with an imperative, as opposed to functional, programming style. In this case, it's useful to treat - `WorkerLocalStorageStorage` as local to each thread for only the parallel + `WorkerLocalStorage` as local to each thread for only the parallel portion of an algorithm. 2. Recycling temporary buffers across iterations of a parallel foreach loop. diff --git a/libphobos/src/std/regex/package.d b/libphobos/src/std/regex/package.d index 82207b6..8db0b1e 100644 --- a/libphobos/src/std/regex/package.d +++ b/libphobos/src/std/regex/package.d @@ -70,7 +70,7 @@ $(TR $(TD Objects) $(TD ... // multi-pattern regex - auto multi = regex([`\d+,\d+`,`(a-z]+):(\d+)`]); + auto multi = regex([`\d+,\d+`, `([a-z]+):(\d+)`]); auto m = "abc:43 12,34".matchAll(multi); assert(m.front.whichPattern == 2); assert(m.front[1] == "abc"); @@ -80,9 +80,17 @@ $(TR $(TD Objects) $(TD assert(m.front[1] == "12"); ... - // The result of the `matchAll/matchFirst` is directly testable with if/assert/while. - // e.g. test if a string consists of letters: - assert(matchFirst("Letter", `^\p{L}+$`)); + // The result of `matchAll/matchFirst` is directly testable with `if/assert/while`, + // e.g. test if a string consists of letters only: + assert(matchFirst("LettersOnly", `^\p{L}+$`)); + + // And we can take advantage of the ability to define a variable in the $(LINK2 https://dlang.org/spec/statement.html#IfCondition `IfCondition`): + if (const auto captures = matchFirst("At l34st one digit, but maybe more...", `((\d)(\d*))`)) + { + assert(captures[2] == "3"); + assert(captures[3] == "4"); + assert(captures[1] == "34"); + } --- $(SECTION Syntax and general information) diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d index 1541415..c1d6bc9 100644 --- a/libphobos/src/std/traits.d +++ b/libphobos/src/std/traits.d @@ -829,6 +829,10 @@ private template fqnType(T, { enum fqnType = "dstring"; } + else static if (is(T == typeof(null))) + { + enum fqnType = "typeof(null)"; + } else static if (isBasicType!T && !is(T == enum)) { enum fqnType = chain!((Unqual!T).stringof); @@ -919,6 +923,7 @@ private template fqnType(T, static assert(fqn!(string) == "string"); static assert(fqn!(wstring) == "wstring"); static assert(fqn!(dstring) == "dstring"); + static assert(fqn!(typeof(null)) == "typeof(null)"); static assert(fqn!(void) == "void"); static assert(fqn!(const(void)) == "const(void)"); static assert(fqn!(shared(void)) == "shared(void)"); diff --git a/libphobos/testsuite/libphobos.traits/all_satisfy.d b/libphobos/testsuite/libphobos.traits/all_satisfy.d new file mode 100644 index 0000000..2c008ce --- /dev/null +++ b/libphobos/testsuite/libphobos.traits/all_satisfy.d @@ -0,0 +1,24 @@ +// https://issues.dlang.org/show_bug.cgi?id=22210 + +import core.internal.traits : allSatisfy; + +enum isHashable(T) = __traits(compiles, + () { T.init; } +); + +class A +{ + static if (isHashable!B) {} +} + +class B +{ + static if (isHashable!C) {} +} + +class C +{ + static if (allSatisfy!(isHashable, int, B)) {} +} + +void main() {} diff --git a/libphobos/testsuite/libphobos.traits/traits.exp b/libphobos/testsuite/libphobos.traits/traits.exp new file mode 100644 index 0000000..cb78538 --- /dev/null +++ b/libphobos/testsuite/libphobos.traits/traits.exp @@ -0,0 +1,27 @@ +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# Initialize dg. +dg-init + +# Gather a list of all tests. +set tests [lsort [find $srcdir/$subdir *.d]] + +# Main loop. +dg-runtest $tests "" $DEFAULT_DFLAGS + +# All done. +dg-finish |