summaryrefslogtreecommitdiff
path: root/libphobos
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-04-21 14:25:26 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2022-04-21 20:03:08 +0100
commitae56e2da05e823e63972aff3118a659d7ca7a8b9 (patch)
tree13932a03f44d3892b2ea8accebe7e55fed6142e0 /libphobos
parent93dd7f36f2066ec52137178ee52052f293e5e743 (diff)
d: Merge upstream dmd eb7bee331, druntime 27834edb, phobos ac296f80c.
D front-end changes: - Import dmd v2.100.0-beta.1. - Print deprecation messages for scope violations unless `-frevert=dip1000' is used. - Fixed a missed case of switch case fallthrough not being caught by the compiler. D runtime changes: - Import druntime v2.100.0-beta.1. Phobos changes: - Import phobos v2.100.0-beta.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd eb7bee331. * dmd/VERSION: Update version to v2.100.0-beta.1. * d-lang.cc (d_handle_option): Handle OPT_frevert_dip1000. * lang.opt (frevert=dip1000): New option. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 27834edb. * src/MERGE: Merge upstream phobos ac296f80c. * src/Makefile.am (PHOBOS_DSOURCES): Add std/int128.d. * src/Makefile.in: Regenerate.
Diffstat (limited to 'libphobos')
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/core/exception.d84
-rw-r--r--libphobos/libdruntime/object.d4
-rw-r--r--libphobos/libdruntime/rt/aaA.d4
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/Makefile.am2
-rw-r--r--libphobos/src/Makefile.in4
-rw-r--r--libphobos/src/std/base64.d20
-rw-r--r--libphobos/src/std/int128.d374
-rw-r--r--libphobos/src/std/path.d2
-rw-r--r--libphobos/src/std/traits.d21
11 files changed, 455 insertions, 64 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 5e2566c9ceb..e08d9cdc0fd 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-9ba9a6ae2b8f6811cb85107cb56701df04f36ac6
+27834edb5e1613e3abd43e09880c36d9fc961938
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/exception.d b/libphobos/libdruntime/core/exception.d
index a6928660773..81aa43b27d0 100644
--- a/libphobos/libdruntime/core/exception.d
+++ b/libphobos/libdruntime/core/exception.d
@@ -19,29 +19,6 @@ void __switch_errorT()(string file = __FILE__, size_t line = __LINE__) @trusted
assert(0, "No appropriate switch clause found");
}
-version (D_BetterC)
-{
- // When compiling with -betterC we use template functions so if they are
- // used the bodies are copied into the user's program so there is no need
- // for the D runtime during linking.
-
- // In the future we might want to convert all functions in this module to
- // templates even for ordinary builds instead of providing them as an
- // extern(C) library.
-
- void onOutOfMemoryError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
- {
- assert(0, "Memory allocation failed");
- }
- alias onOutOfMemoryErrorNoGC = onOutOfMemoryError;
-
- void onInvalidMemoryOperationError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
- {
- assert(0, "Invalid memory operation");
- }
-}
-else:
-
/**
* Thrown on a range error.
*/
@@ -218,17 +195,17 @@ private void rangeMsgPut(ref char[] r, scope const(char)[] e) @nogc nothrow pure
*/
class AssertError : Error
{
- @safe pure nothrow this( string file, size_t line )
+ @safe pure nothrow @nogc this( string file, size_t line )
{
this(cast(Throwable)null, file, line);
}
- @safe pure nothrow this( Throwable next, string file = __FILE__, size_t line = __LINE__ )
+ @safe pure nothrow @nogc this( Throwable next, string file = __FILE__, size_t line = __LINE__ )
{
this( "Assertion failure", file, line, next);
}
- @safe pure nothrow this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
+ @safe pure nothrow @nogc this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
{
super( msg, file, line, next );
}
@@ -692,26 +669,49 @@ extern (C) void onFinalizeError( TypeInfo info, Throwable e, string file = __FIL
throw staticError!FinalizeError(info, e, file, line);
}
-/**
- * A callback for out of memory errors in D. An $(LREF OutOfMemoryError) will be
- * thrown.
- *
- * Throws:
- * $(LREF OutOfMemoryError).
- */
-extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
+version (D_BetterC)
{
- // NOTE: Since an out of memory condition exists, no allocation must occur
- // while generating this object.
- throw staticError!OutOfMemoryError();
-}
+ // When compiling with -betterC we use template functions so if they are
+ // used the bodies are copied into the user's program so there is no need
+ // for the D runtime during linking.
-extern (C) void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc
-{
- // suppress stacktrace until they are @nogc
- throw staticError!OutOfMemoryError(false);
+ // In the future we might want to convert all functions in this module to
+ // templates even for ordinary builds instead of providing them as an
+ // extern(C) library.
+
+ void onOutOfMemoryError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
+ {
+ assert(0, "Memory allocation failed");
+ }
+ alias onOutOfMemoryErrorNoGC = onOutOfMemoryError;
+
+ void onInvalidMemoryOperationError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
+ {
+ assert(0, "Invalid memory operation");
+ }
}
+else
+{
+ /**
+ * A callback for out of memory errors in D. An $(LREF OutOfMemoryError) will be
+ * thrown.
+ *
+ * Throws:
+ * $(LREF OutOfMemoryError).
+ */
+ extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
+ {
+ // NOTE: Since an out of memory condition exists, no allocation must occur
+ // while generating this object.
+ throw staticError!OutOfMemoryError();
+ }
+ extern (C) void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc
+ {
+ // suppress stacktrace until they are @nogc
+ throw staticError!OutOfMemoryError(false);
+ }
+}
/**
* A callback for invalid memory operations in D. An
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index a15616c6e0f..e58afa2f985 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -2830,8 +2830,8 @@ extern (C)
private struct AA { void* impl; }
// size_t _aaLen(in AA aa) pure nothrow @nogc;
- private void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey) pure nothrow;
- private void* _aaGetX(AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey, out bool found) pure nothrow;
+ private void* _aaGetY(scope AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey) pure nothrow;
+ private void* _aaGetX(scope AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey, out bool found) pure nothrow;
// inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz, in void* pkey);
inout(void[]) _aaValues(inout AA aa, const size_t keysz, const size_t valsz, const TypeInfo tiValueArray) pure nothrow;
inout(void[]) _aaKeys(inout AA aa, const size_t keysz, const TypeInfo tiKeyArray) pure nothrow;
diff --git a/libphobos/libdruntime/rt/aaA.d b/libphobos/libdruntime/rt/aaA.d
index 0c38622a879..ab93f191634 100644
--- a/libphobos/libdruntime/rt/aaA.d
+++ b/libphobos/libdruntime/rt/aaA.d
@@ -504,7 +504,7 @@ extern (C) size_t _aaLen(scope const AA aa) pure nothrow @nogc
* If key was not in the aa, a mutable pointer to newly inserted value which
* is set to all zeros
*/
-extern (C) void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti,
+extern (C) void* _aaGetY(scope AA* paa, const TypeInfo_AssociativeArray ti,
const size_t valsz, scope const void* pkey)
{
bool found;
@@ -525,7 +525,7 @@ extern (C) void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti,
* If key was not in the aa, a mutable pointer to newly inserted value which
* is set to all zeros
*/
-extern (C) void* _aaGetX(AA* paa, const TypeInfo_AssociativeArray ti,
+extern (C) void* _aaGetX(scope AA* paa, const TypeInfo_AssociativeArray ti,
const size_t valsz, scope const void* pkey, out bool found)
{
// lazily alloc implementation
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 0feb0b01ef5..3218ace50a0 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-c0cc5e917db105301dd1199b4b3c854626526407
+ac296f80cda437483b743f953dc69cb1271c82df
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/Makefile.am b/libphobos/src/Makefile.am
index 75f83974e99..da7a2004ff8 100644
--- a/libphobos/src/Makefile.am
+++ b/libphobos/src/Makefile.am
@@ -130,7 +130,7 @@ PHOBOS_DSOURCES = etc/c/curl.d etc/c/zlib.d std/algorithm/comparison.d \
std/experimental/typecons.d std/file.d std/format/internal/floats.d \
std/format/internal/read.d std/format/internal/write.d \
std/format/package.d std/format/read.d std/format/spec.d \
- std/format/write.d std/functional.d std/getopt.d \
+ std/format/write.d std/functional.d std/getopt.d std/int128.d \
std/internal/attributes.d std/internal/cstring.d \
std/internal/math/biguintcore.d std/internal/math/biguintnoasm.d \
std/internal/math/errorfunction.d std/internal/math/gammafunction.d \
diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in
index f2395e2caf7..6f58fee01ac 100644
--- a/libphobos/src/Makefile.in
+++ b/libphobos/src/Makefile.in
@@ -228,6 +228,7 @@ am__dirstamp = $(am__leading_dot)dirstamp
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/spec.lo \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/write.lo \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/functional.lo std/getopt.lo \
+@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/int128.lo \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/attributes.lo \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/cstring.lo \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/math/biguintcore.lo \
@@ -591,7 +592,7 @@ libgphobos_la_LINK = $(LIBTOOL) --tag=D $(libgphobos_la_LIBTOOLFLAGS) \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/experimental/typecons.d std/file.d std/format/internal/floats.d \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/internal/read.d std/format/internal/write.d \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/package.d std/format/read.d std/format/spec.d \
-@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/write.d std/functional.d std/getopt.d \
+@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/write.d std/functional.d std/getopt.d std/int128.d \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/attributes.d std/internal/cstring.d \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/math/biguintcore.d std/internal/math/biguintnoasm.d \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/math/errorfunction.d std/internal/math/gammafunction.d \
@@ -846,6 +847,7 @@ std/format/spec.lo: std/format/$(am__dirstamp)
std/format/write.lo: std/format/$(am__dirstamp)
std/functional.lo: std/$(am__dirstamp)
std/getopt.lo: std/$(am__dirstamp)
+std/int128.lo: std/$(am__dirstamp)
std/internal/$(am__dirstamp):
@$(MKDIR_P) std/internal
@: > std/internal/$(am__dirstamp)
diff --git a/libphobos/src/std/base64.d b/libphobos/src/std/base64.d
index 866f7005060..d971dba1c71 100644
--- a/libphobos/src/std/base64.d
+++ b/libphobos/src/std/base64.d
@@ -63,7 +63,7 @@ import std.range.primitives : empty, front, isInputRange, isOutputRange,
import std.traits : isArray;
// Make sure module header code examples work correctly.
-@safe unittest
+pure @safe unittest
{
ubyte[] data = [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e];
@@ -82,7 +82,7 @@ import std.traits : isArray;
alias Base64 = Base64Impl!('+', '/');
///
-@safe unittest
+pure @safe unittest
{
ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];
assert(Base64.encode(data) == "g9cwegE/");
@@ -98,7 +98,7 @@ alias Base64 = Base64Impl!('+', '/');
alias Base64URL = Base64Impl!('-', '_');
///
-@safe unittest
+pure @safe unittest
{
ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];
assert(Base64URL.encode(data) == "g9cwegE_");
@@ -114,7 +114,7 @@ alias Base64URL = Base64Impl!('-', '_');
alias Base64URLNoPadding = Base64Impl!('-', '_', Base64.NoPadding);
///
-@safe unittest
+pure @safe unittest
{
ubyte[] data = [0x83, 0xd7, 0x30, 0x7b, 0xef];
assert(Base64URLNoPadding.encode(data) == "g9cwe-8");
@@ -180,7 +180,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=')
* Returns:
* The length of a Base64 encoding of an array of the given length.
*/
- @safe
+ @safe @nogc
pure nothrow size_t encodeLength(in size_t sourceLength)
{
static if (Padding == NoPadding)
@@ -218,8 +218,8 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=')
* The slice of $(D_PARAM buffer) that contains the encoded string.
*/
@trusted
- pure char[] encode(R1, R2)(in R1 source, return scope R2 buffer) if (isArray!R1 && is(ElementType!R1 : ubyte) &&
- is(R2 == char[]))
+ pure char[] encode(R1, R2)(const scope R1 source, return scope R2 buffer)
+ if (isArray!R1 && is(ElementType!R1 : ubyte) && is(R2 == char[]))
in
{
assert(buffer.length >= encodeLength(source.length), "Insufficient buffer for encoding");
@@ -277,9 +277,9 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=')
}
///
- @safe unittest
+ @nogc nothrow @safe unittest
{
- ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];
+ ubyte[6] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];
char[32] buffer; // much bigger than necessary
// Just to be sure...
@@ -287,7 +287,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=')
assert(buffer.length >= encodedLength);
// encode() returns a slice to the provided buffer.
- auto encoded = Base64.encode(data, buffer[]);
+ auto encoded = Base64.encode(data[], buffer[]);
assert(encoded is buffer[0 .. encodedLength]);
assert(encoded == "g9cwegE/");
}
diff --git a/libphobos/src/std/int128.d b/libphobos/src/std/int128.d
new file mode 100644
index 00000000000..fc992f82422
--- /dev/null
+++ b/libphobos/src/std/int128.d
@@ -0,0 +1,374 @@
+// Written in the D programming language
+/**
+ * Implements a signed 128 bit integer type.
+ *
+ Author: Walter Bright
+ Copyright: Copyright (c) 2022, D Language Foundation
+ License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ Source: $(PHOBOSSRC std/int128.d)
+ */
+module std.int128;
+
+private import core.int128;
+
+
+/***********************************
+ * 128 bit signed integer type.
+ */
+
+public struct Int128
+{
+ @safe pure nothrow @nogc:
+
+ Cent data; /// core.int128.Cent
+
+ /****************
+ * Construct an `Int128` from a `long` value.
+ * The upper 64 bits are formed by sign extension.
+ * Params:
+ * lo = signed lower 64 bits
+ */
+ this(long lo)
+ {
+ data.lo = lo;
+ data.hi = lo < 0 ? ~0L : 0;
+ }
+
+ /****************
+ * Construct an `Int128` from a `ulong` value.
+ * The upper 64 bits are set to zero.
+ * Params:
+ * lo = unsigned lower 64 bits
+ */
+ this(ulong lo)
+ {
+ data.lo = lo;
+ data.hi = 0;
+ }
+
+ /****************
+ * Construct an `Int128` from a `long` value.
+ * Params:
+ * hi = upper 64 bits
+ * lo = lower 64 bits
+ */
+ this(long hi, long lo)
+ {
+ data.hi = hi;
+ data.lo = lo;
+ }
+
+ /********************
+ * Construct an `Int128` from a `Cent`.
+ * Params:
+ * data = Cent data
+ */
+ this(Cent data)
+ {
+ this.data = data;
+ }
+
+ /********************
+ * Returns: hash value for Int128
+ */
+ size_t toHash() const
+ {
+ return cast(size_t)((data.lo & 0xFFFF_FFFF) + (data.hi & 0xFFFF_FFFF) + (data.lo >> 32) + (data.hi >> 32));
+ }
+
+ /************************
+ * Compare for equality
+ * Params: lo = signed value to compare with
+ * Returns: true if Int128 equals value
+ */
+ bool opEquals(long lo) const
+ {
+ return data.lo == lo && data.hi == (lo >> 63);
+ }
+
+ /************************
+ * Compare for equality
+ * Params: lo = unsigned value to compare with
+ * Returns: true if Int128 equals value
+ */
+ bool opEquals(ulong lo) const
+ {
+ return data.hi == 0 && data.lo == lo;
+ }
+
+ /************************
+ * Compare for equality
+ * Params: op2 = value to compare with
+ * Returns: true if Int128 equals value
+ */
+ bool opEquals(Int128 op2) const
+ {
+ return data.hi == op2.data.hi && data.lo == op2.data.lo;
+ }
+
+ /** Support unary arithmentic operator +
+ * Params: op = "+"
+ * Returns: lvalue of result
+ */
+ Int128 opUnary(string op)() const
+ if (op == "+")
+ {
+ return this;
+ }
+
+ /** Support unary arithmentic operator - ~
+ * Params: op = "-", "~"
+ * Returns: lvalue of result
+ */
+ Int128 opUnary(string op)() const
+ if (op == "-" || op == "~")
+ {
+ static if (op == "-")
+ return Int128(neg(this.data));
+ else static if (op == "~")
+ return Int128(com(this.data));
+ }
+
+ /** Support unary arithmentic operator ++ --
+ * Params: op = "++", "--"
+ * Returns: lvalue of result
+ */
+ Int128 opUnary(string op)()
+ if (op == "++" || op == "--")
+ {
+ static if (op == "++")
+ this.data = inc(this.data);
+ else static if (op == "--")
+ this.data = dec(this.data);
+ else
+ static assert(0, op);
+ return this;
+ }
+
+ /** Support casting to a bool
+ * Params: T = bool
+ * Returns: boolean result
+ */
+ bool opCast(T : bool)() const
+ {
+ return tst(this.data);
+ }
+
+ /** Support binary arithmetic operators + - * / % & | ^ << >> >>>
+ * Params:
+ * op = one of the arithmetic binary operators
+ * op2 = second operand
+ * Returns: value after the operation is applied
+ */
+ Int128 opBinary(string op)(Int128 op2) const
+ if (op == "+" || op == "-" ||
+ op == "*" || op == "/" || op == "%" ||
+ op == "&" || op == "|" || op == "^")
+ {
+ static if (op == "+")
+ return Int128(add(this.data, op2.data));
+ else static if (op == "-")
+ return Int128(sub(this.data, op2.data));
+ else static if (op == "*")
+ return Int128(mul(this.data, op2.data));
+ else static if (op == "/")
+ return Int128(div(this.data, op2.data));
+ else static if (op == "%")
+ {
+ Cent modulus;
+ divmod(this.data, op2.data, modulus);
+ return Int128(modulus);
+ }
+ else static if (op == "&")
+ return Int128(and(this.data, op2.data));
+ else static if (op == "|")
+ return Int128(or(this.data, op2.data));
+ else static if (op == "^")
+ return Int128(xor(this.data, op2.data));
+ else
+ static assert(0, "wrong op value");
+ }
+
+ /// ditto
+ Int128 opBinary(string op)(long op2) const
+ if (op == "+" || op == "-" ||
+ op == "*" || op == "/" || op == "%" ||
+ op == "&" || op == "|" || op == "^")
+ {
+ return mixin("this " ~ op ~ " Int128(0, op2)");
+ }
+
+ /// ditto
+ Int128 opBinaryRight(string op)(long op2) const
+ if (op == "+" || op == "-" ||
+ op == "*" || op == "/" || op == "%" ||
+ op == "&" || op == "|" || op == "^")
+ {
+ mixin("return Int128(0, op2) " ~ op ~ " this;");
+ }
+
+ /// ditto
+ Int128 opBinary(string op)(long op2) const
+ if (op == "<<")
+ {
+ return Int128(shl(this.data, cast(uint) op2));
+ }
+
+ /// ditto
+ Int128 opBinary(string op)(long op2) const
+ if (op == ">>")
+ {
+ return Int128(sar(this.data, cast(uint) op2));
+ }
+
+ /// ditto
+ Int128 opBinary(string op)(long op2) const
+ if (op == ">>>")
+ {
+ return Int128(shr(this.data, cast(uint) op2));
+ }
+
+ /** arithmetic assignment operators += -= *= /= %= &= |= ^= <<= >>= >>>=
+ * Params: op = one of +, -, etc.
+ * op2 = second operand
+ * Returns: lvalue of updated left operand
+ */
+ ref Int128 opOpAssign(string op)(Int128 op2)
+ if (op == "+" || op == "-" ||
+ op == "*" || op == "/" || op == "%" ||
+ op == "&" || op == "|" || op == "^" ||
+ op == "<<" || op == ">>" || op == ">>>")
+ {
+ mixin("this = this " ~ op ~ " op2;");
+ return this;
+ }
+
+ /// ditto
+ ref Int128 opOpAssign(string op)(long op2)
+ if (op == "+" || op == "-" ||
+ op == "*" || op == "/" || op == "%" ||
+ op == "&" || op == "|" || op == "^" ||
+ op == "<<" || op == ">>" || op == ">>>")
+ {
+ mixin("this = this " ~ op ~ " op2;");
+ return this;
+ }
+
+ /** support signed 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
+ {
+ 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
+ */
+ int opCmp(long op2) const
+ {
+ return opCmp(Int128(0, op2));
+ }
+
+ enum min = Int128(long.min, 0); /// minimum value
+ enum max = Int128(long.max, ulong.max); /// maximum value
+}
+
+/********************************************* Tests ************************************/
+
+version (unittest)
+{
+import core.stdc.stdio;
+
+@trusted void print(Int128 c)
+{
+ printf("%lld, %lld\n", c.data.hi, c.data.lo);
+}
+
+@trusted void printx(Int128 c)
+{
+ printf("%llx, %llx\n", c.data.hi, c.data.lo);
+}
+}
+
+/// Int128 tests
+@safe pure nothrow @nogc
+unittest
+{
+ Int128 c = Int128(5, 6);
+ assert(c == c);
+ assert(c == +c);
+ assert(c == - -c);
+ assert(~c == Int128(~5, ~6));
+ ++c;
+ assert(c == Int128(5, 7));
+ assert(--c == Int128(5, 6));
+ assert(!!c);
+ assert(!Int128());
+
+ assert(c + Int128(10, 20) == Int128(15, 26));
+ assert(c - Int128(1, 2) == Int128(4, 4));
+ assert(c * Int128(100, 2) == Int128(610, 12));
+ assert(c / Int128(3, 2) == Int128(0, 1));
+ assert(c % Int128(3, 2) == Int128(2, 4));
+ assert((c & Int128(3, 2)) == Int128(1, 2));
+ assert((c | Int128(3, 2)) == Int128(7, 6));
+ assert((c ^ Int128(3, 2)) == Int128(6, 4));
+
+ assert(c + 15 == Int128(5, 21));
+ assert(c - 15 == Int128(4, -9));
+ assert(c * 15 == Int128(75, 90));
+ assert(c / 15 == Int128(0, 6148914691236517205));
+ assert(c % 15 == Int128(0, 11));
+ assert((c & 15) == Int128(0, 6));
+ assert((c | 15) == Int128(5, 15));
+ assert((c ^ 15) == Int128(5, 9));
+
+ assert(15 + c == Int128(5, 21));
+ assert(15 - c == Int128(-5, 9));
+ assert(15 * c == Int128(75, 90));
+ assert(15 / c == Int128(0, 0));
+ assert(15 % c == Int128(0, 15));
+ assert((15 & c) == Int128(0, 6));
+ assert((15 | c) == Int128(5, 15));
+ assert((15 ^ c) == Int128(5, 9));
+
+ assert(c << 1 == Int128(10, 12));
+ assert(-c >> 1 == Int128(-3, 9223372036854775805));
+ assert(-c >>> 1 == Int128(9223372036854775805, 9223372036854775805));
+
+ assert((c += 1) == Int128(5, 7));
+ assert((c -= 1) == Int128(5, 6));
+ assert((c += Int128(0, 1)) == Int128(5, 7));
+ assert((c -= Int128(0, 1)) == Int128(5, 6));
+ assert((c *= 2) == Int128(10, 12));
+ assert((c /= 2) == Int128(5, 6));
+ assert((c %= 2) == Int128());
+ c += Int128(5, 6);
+ assert((c *= Int128(10, 20)) == Int128(160, 120));
+ assert((c /= Int128(10, 20)) == Int128(0, 15));
+ c += Int128(72, 0);
+ assert((c %= Int128(10, 20)) == Int128(1, -125));
+ assert((c &= Int128(3, 20)) == Int128(1, 0));
+ assert((c |= Int128(8, 2)) == Int128(9, 2));
+ assert((c ^= Int128(8, 2)) == Int128(1, 0));
+ c |= Int128(10, 5);
+ assert((c <<= 1) == Int128(11 * 2, 5 * 2));
+ assert((c >>>= 1) == Int128(11, 5));
+ c = Int128(long.min, long.min);
+ assert((c >>= 1) == Int128(long.min >> 1, cast(ulong) long.min >> 1));
+
+ assert(-Int128.min == Int128.min);
+ assert(Int128.max + 1 == Int128.min);
+
+ c = Int128(5, 6);
+ assert(c < Int128(6, 5));
+ assert(c > 10);
+
+ c = Int128(-1UL);
+ assert(c == -1UL);
+ c = Int128(-1L);
+ assert(c == -1L);
+}
diff --git a/libphobos/src/std/path.d b/libphobos/src/std/path.d
index 20518b86333..de180fcc548 100644
--- a/libphobos/src/std/path.d
+++ b/libphobos/src/std/path.d
@@ -1519,7 +1519,7 @@ if (isSomeChar!C)
import std.range;
// ir() wraps an array in a plain (i.e. non-forward) input range, so that
// we can test both code paths
- InputRange!(C[]) ir(C)(C[][] p...) { return inputRangeObject(p); }
+ InputRange!(C[]) ir(C)(C[][] p...) { return inputRangeObject(p.dup); }
version (Posix)
{
assert(buildPath("foo") == "foo");
diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d
index 9ca676d312a..18400e3e859 100644
--- a/libphobos/src/std/traits.d
+++ b/libphobos/src/std/traits.d
@@ -1422,6 +1422,11 @@ if (isCallable!func)
enum val = "val" ~ (name == "val" ? "_" : "");
enum ptr = "ptr" ~ (name == "ptr" ? "_" : "");
mixin("
+ enum hasDefaultArg = (PT[i .. i+1] " ~ args ~ ") { return 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
@@ -1432,10 +1437,9 @@ if (isCallable!func)
auto " ~ val ~ " = " ~ args ~ "[0];
auto " ~ ptr ~ " = &" ~ val ~ ";
return *" ~ ptr ~ ";
- };
- ");
- static if (is(typeof(get())))
+ };");
enum Get = get();
+ }
else
alias Get = void;
// If default arg doesn't exist, returns void instead.
@@ -1483,6 +1487,17 @@ if (isCallable!func)
static foreach (V; Voids) static assert(is(V == void));
}
+// https://issues.dlang.org/show_bug.cgi?id=20182
+@safe pure nothrow @nogc unittest
+{
+ struct S
+ {
+ this(ref S) {}
+ }
+
+ static assert(__traits(compiles, ParameterDefaults!(S.__ctor)));
+}
+
/**
* Alternate name for $(LREF ParameterDefaults), kept for legacy compatibility.
*/