diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-04-21 14:25:26 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-04-21 20:03:08 +0100 |
commit | ae56e2da05e823e63972aff3118a659d7ca7a8b9 (patch) | |
tree | 13932a03f44d3892b2ea8accebe7e55fed6142e0 /libphobos | |
parent | 93dd7f36f2066ec52137178ee52052f293e5e743 (diff) | |
download | gcc-ae56e2da05e823e63972aff3118a659d7ca7a8b9.zip gcc-ae56e2da05e823e63972aff3118a659d7ca7a8b9.tar.gz gcc-ae56e2da05e823e63972aff3118a659d7ca7a8b9.tar.bz2 |
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/MERGE | 2 | ||||
-rw-r--r-- | libphobos/libdruntime/core/exception.d | 84 | ||||
-rw-r--r-- | libphobos/libdruntime/object.d | 4 | ||||
-rw-r--r-- | libphobos/libdruntime/rt/aaA.d | 4 | ||||
-rw-r--r-- | libphobos/src/MERGE | 2 | ||||
-rw-r--r-- | libphobos/src/Makefile.am | 2 | ||||
-rw-r--r-- | libphobos/src/Makefile.in | 4 | ||||
-rw-r--r-- | libphobos/src/std/base64.d | 20 | ||||
-rw-r--r-- | libphobos/src/std/int128.d | 374 | ||||
-rw-r--r-- | libphobos/src/std/path.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/traits.d | 21 |
11 files changed, 455 insertions, 64 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 5e2566c..e08d9cd 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 a692866..81aa43b 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 a15616c..e58afa2 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 0c38622..ab93f19 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 0feb0b0..3218ace 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 75f8397..da7a200 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 f2395e2..6f58fee 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 866f700..d971dba 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 0000000..fc992f8 --- /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 20518b8..de180fc 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 9ca676d..18400e3 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. */ |