aboutsummaryrefslogtreecommitdiff
path: root/libphobos/src
diff options
context:
space:
mode:
Diffstat (limited to 'libphobos/src')
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/algorithm/setops.d2
-rw-r--r--libphobos/src/std/bitmanip.d3
-rw-r--r--libphobos/src/std/datetime/interval.d4
-rw-r--r--libphobos/src/std/datetime/systime.d4
-rw-r--r--libphobos/src/std/experimental/allocator/mallocator.d1
-rw-r--r--libphobos/src/std/functional.d165
-rw-r--r--libphobos/src/std/sumtype.d1
-rw-r--r--libphobos/src/std/utf.d12
9 files changed, 186 insertions, 8 deletions
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 5fd357c..963ffe0 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-a1f8c4c0700ce4e256f4130ad7883c6ea3890901
+16cb085b584f100fa677e2e64ff6b6dbb4921ad1
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/setops.d b/libphobos/src/std/algorithm/setops.d
index ede1831..cc6f5b7 100644
--- a/libphobos/src/std/algorithm/setops.d
+++ b/libphobos/src/std/algorithm/setops.d
@@ -404,7 +404,7 @@ if (ranges.length >= 2 &&
r = ranges[i].save; // rollover
}
}
- @property Result save() scope return
+ @property Result save() return scope
{
Result copy = this;
foreach (i, r; ranges)
diff --git a/libphobos/src/std/bitmanip.d b/libphobos/src/std/bitmanip.d
index 9af9d72..de2e0fb 100644
--- a/libphobos/src/std/bitmanip.d
+++ b/libphobos/src/std/bitmanip.d
@@ -1447,7 +1447,8 @@ public:
size_t bitCount;
foreach (i; 0 .. fullWords)
bitCount += countBitsSet(_ptr[i]);
- bitCount += countBitsSet(_ptr[fullWords] & endMask);
+ if (endBits)
+ bitCount += countBitsSet(_ptr[fullWords] & endMask);
return bitCount;
}
else
diff --git a/libphobos/src/std/datetime/interval.d b/libphobos/src/std/datetime/interval.d
index ba2a210..d787e3a 100644
--- a/libphobos/src/std/datetime/interval.d
+++ b/libphobos/src/std/datetime/interval.d
@@ -7848,12 +7848,12 @@ if (isTimePoint!TP &&
duration = The duration which separates each successive time point in
the range.
+/
-TP delegate(scope const TP) everyDuration(TP, Direction dir = Direction.fwd, D)(D duration) nothrow
+TP delegate(return scope const TP) everyDuration(TP, Direction dir = Direction.fwd, D)(D duration) nothrow
if (isTimePoint!TP &&
__traits(compiles, TP.init + duration) &&
(dir == Direction.fwd || dir == Direction.bwd))
{
- TP func(scope const TP tp)
+ TP func(return scope const TP tp)
{
static if (dir == Direction.fwd)
return tp + duration;
diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d
index db325f7..949ad7d 100644
--- a/libphobos/src/std/datetime/systime.d
+++ b/libphobos/src/std/datetime/systime.d
@@ -6269,7 +6269,7 @@ public:
duration = The $(REF Duration, core,time) to add to or subtract from
this $(LREF SysTime).
+/
- SysTime opBinary(string op)(Duration duration) @safe const pure nothrow scope
+ SysTime opBinary(string op)(Duration duration) @safe const pure nothrow return scope
if (op == "+" || op == "-")
{
SysTime retval = SysTime(this._stdTime, this._timezone);
@@ -7668,7 +7668,7 @@ public:
$(LREF SysTime) for the last day in the month that this Date is in.
The time portion of endOfMonth is always 23:59:59.9999999.
+/
- @property SysTime endOfMonth() @safe const nothrow scope
+ @property SysTime endOfMonth() @safe const nothrow return scope
{
immutable hnsecs = adjTime;
immutable days = getUnitsFromHNSecs!"days"(hnsecs);
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index 895d588..de9afbb 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -392,6 +392,7 @@ version (Posix)
AlignedMallocator.instance.alignedReallocate(c, 32, 32);
assert(c.ptr);
+ version (LDC_AddressSanitizer) {} else // AddressSanitizer does not support such large memory allocations (0x10000000000 max)
version (DragonFlyBSD) {} else /* FIXME: Malloc on DragonFly does not return NULL when allocating more than UINTPTR_MAX
* $(LINK: https://bugs.dragonflybsd.org/issues/3114, dragonfly bug report)
* $(LINK: https://github.com/dlang/druntime/pull/1999#discussion_r157536030, PR Discussion) */
diff --git a/libphobos/src/std/functional.d b/libphobos/src/std/functional.d
index da698e0..90b0f91 100644
--- a/libphobos/src/std/functional.d
+++ b/libphobos/src/std/functional.d
@@ -1847,3 +1847,168 @@ if (isCallable!(F))
static assert(! is(typeof(dg_xtrnC) == typeof(dg_xtrnD)));
}
}
+
+// Converts an unsigned integer to a compile-time string constant.
+private enum toCtString(ulong n) = n.stringof[0 .. $ - "LU".length];
+
+// Check that .stringof does what we expect, since it's not guaranteed by the
+// language spec.
+@safe unittest
+{
+ assert(toCtString!0 == "0");
+ assert(toCtString!123456 == "123456");
+}
+
+/**
+ * Passes the fields of a struct as arguments to a function.
+ *
+ * Can be used with a $(LINK2 https://dlang.org/spec/expression.html#function_literals,
+ * function literal) to give temporary names to the fields of a struct or
+ * tuple.
+ *
+ * Params:
+ * fun = Callable that the struct's fields will be passed to.
+ *
+ * Returns:
+ * A function that accepts a single struct as an argument and passes its
+ * fields to `fun` when called.
+ */
+template bind(alias fun)
+{
+ /**
+ * Params:
+ * args = The struct or tuple whose fields will be used as arguments.
+ *
+ * Returns: `fun(args.tupleof)`
+ */
+ auto ref bind(T)(auto ref T args)
+ if (is(T == struct))
+ {
+ import std.meta : Map = staticMap;
+ import core.lifetime : move;
+
+ // Forwards the i'th member of `args`
+ // Needed because core.lifetime.forward doesn't work on struct members
+ template forwardArg(size_t i)
+ {
+ static if (__traits(isRef, args) || !is(typeof(move(args.tupleof[i]))))
+ enum forwardArg = "args.tupleof[" ~ toCtString!i ~ "], ";
+ else
+ enum forwardArg = "move(args.tupleof[" ~ toCtString!i ~ "]), ";
+ }
+
+ static if (args.tupleof.length == 0)
+ enum argList = "";
+ else
+ alias argList = Map!(forwardArg, Iota!(args.tupleof.length));
+
+ return mixin("fun(", argList, ")");
+ }
+}
+
+/// Giving names to tuple elements
+@safe unittest
+{
+ import std.typecons : tuple;
+
+ auto name = tuple("John", "Doe");
+ string full = name.bind!((first, last) => first ~ " " ~ last);
+ assert(full == "John Doe");
+}
+
+/// Passing struct fields to a function
+@safe unittest
+{
+ import std.algorithm.comparison : min, max;
+
+ struct Pair
+ {
+ int a;
+ int b;
+ }
+
+ auto p = Pair(123, 456);
+ assert(p.bind!min == 123); // min(p.a, p.b)
+ assert(p.bind!max == 456); // max(p.a, p.b)
+}
+
+/// In a range pipeline
+@safe unittest
+{
+ import std.algorithm.iteration : map, filter;
+ import std.algorithm.comparison : equal;
+ import std.typecons : tuple;
+
+ auto ages = [
+ tuple("Alice", 35),
+ tuple("Bob", 64),
+ tuple("Carol", 21),
+ tuple("David", 39),
+ tuple("Eve", 50)
+ ];
+
+ auto overForty = ages
+ .filter!(bind!((name, age) => age > 40))
+ .map!(bind!((name, age) => name));
+
+ assert(overForty.equal(["Bob", "Eve"]));
+}
+
+// Zero arguments
+@safe unittest
+{
+ struct Empty {}
+
+ assert(Empty().bind!(() => 123) == 123);
+}
+
+// Non-copyable arguments
+@safe unittest
+{
+ import std.typecons : tuple;
+
+ static struct NoCopy
+ {
+ int n;
+ @disable this(this);
+ }
+
+ static struct Pair
+ {
+ NoCopy a, b;
+ }
+
+ static auto fun(NoCopy a, NoCopy b)
+ {
+ return tuple(a.n, b.n);
+ }
+
+ auto expected = fun(NoCopy(1), NoCopy(2));
+ assert(Pair(NoCopy(1), NoCopy(2)).bind!fun == expected);
+}
+
+// ref arguments
+@safe unittest
+{
+ import std.typecons : tuple;
+
+ auto t = tuple(123, 456);
+ t.bind!((ref int a, int b) { a = 789; b = 1011; });
+
+ assert(t[0] == 789);
+ assert(t[1] == 456);
+}
+
+// auto ref arguments
+@safe unittest
+{
+ import std.typecons : tuple;
+
+ auto t = tuple(123);
+ t.bind!((auto ref x) {
+ static assert(__traits(isRef, x));
+ });
+ tuple(123).bind!((auto ref x) {
+ static assert(!__traits(isRef, x));
+ });
+}
diff --git a/libphobos/src/std/sumtype.d b/libphobos/src/std/sumtype.d
index 3833c84..8da38bd 100644
--- a/libphobos/src/std/sumtype.d
+++ b/libphobos/src/std/sumtype.d
@@ -13,6 +13,7 @@ include:
License: Boost License 1.0
Authors: Paul Backus
+Source: $(PHOBOSSRC std/sumtype.d)
+/
module std.sumtype;
diff --git a/libphobos/src/std/utf.d b/libphobos/src/std/utf.d
index 5c23684..f0200ce 100644
--- a/libphobos/src/std/utf.d
+++ b/libphobos/src/std/utf.d
@@ -1209,6 +1209,15 @@ do
assert("ë"w.decode(i) == 'ë' && i == 1);
}
+@safe pure unittest // https://issues.dlang.org/show_bug.cgi?id=22867
+{
+ import std.conv : hexString;
+ string data = hexString!"f787a598";
+ size_t offset = 0;
+ try data.decode(offset);
+ catch (UTFException ex) assert(offset == 0);
+}
+
/++
`decodeFront` is a variant of $(LREF decode) which specifically decodes
the first code point. Unlike $(LREF decode), `decodeFront` accepts any
@@ -1671,7 +1680,6 @@ if (
}
}
- index += i + 1;
static if (i == 3)
{
if (d > dchar.max)
@@ -1682,6 +1690,8 @@ if (
throw invalidUTF();
}
}
+
+ index += i + 1;
return d;
}
}