aboutsummaryrefslogtreecommitdiff
path: root/libphobos
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2021-12-15 19:47:02 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2021-12-15 19:51:30 +0100
commitfd43568cc54e17c8b4a845677872c6282bc6dbb7 (patch)
tree24f591392a2978706aef4d58e377b8b42b5ba418 /libphobos
parent639ece7abfa3688008cb791aec4c7a1a4f76e59f (diff)
downloadgcc-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-xlibphobos/configure2
-rw-r--r--libphobos/configure.ac2
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/core/internal/traits.d40
-rw-r--r--libphobos/libdruntime/core/lifetime.d109
-rw-r--r--libphobos/libdruntime/core/runtime.d2
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/execinfo.d139
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/stat.d46
-rw-r--r--libphobos/libdruntime/object.d2
-rw-r--r--libphobos/libdruntime/rt/monitor_.d36
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/algorithm/searching.d12
-rw-r--r--libphobos/src/std/datetime/timezone.d3
-rw-r--r--libphobos/src/std/parallelism.d6
-rw-r--r--libphobos/src/std/regex/package.d16
-rw-r--r--libphobos/src/std/traits.d5
-rw-r--r--libphobos/testsuite/libphobos.traits/all_satisfy.d24
-rw-r--r--libphobos/testsuite/libphobos.traits/traits.exp27
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