summaryrefslogtreecommitdiffstats
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
parentlibstdc++: Avoid ASCII assumptions in floating_from_chars.cc (diff)
downloadgcc-ae56e2da05e823e63972aff3118a659d7ca7a8b9.tar.gz
gcc-ae56e2da05e823e63972aff3118a659d7ca7a8b9.tar.bz2
gcc-ae56e2da05e823e63972aff3118a659d7ca7a8b9.tar.xz
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 @@
19ba9a6ae2b8f6811cb85107cb56701df04f36ac6 127834edb5e1613e3abd43e09880c36d9fc961938
2 2
3The first line of this file holds the git revision number of the last 3The first line of this file holds the git revision number of the last
4merge done from the dlang/druntime repository. 4merge 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
19 assert(0, "No appropriate switch clause found"); 19 assert(0, "No appropriate switch clause found");
20} 20}
21 21
22version (D_BetterC)
23{
24 // When compiling with -betterC we use template functions so if they are
25 // used the bodies are copied into the user's program so there is no need
26 // for the D runtime during linking.
27
28 // In the future we might want to convert all functions in this module to
29 // templates even for ordinary builds instead of providing them as an
30 // extern(C) library.
31
32 void onOutOfMemoryError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
33 {
34 assert(0, "Memory allocation failed");
35 }
36 alias onOutOfMemoryErrorNoGC = onOutOfMemoryError;
37
38 void onInvalidMemoryOperationError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
39 {
40 assert(0, "Invalid memory operation");
41 }
42}
43else:
44
45/** 22/**
46 * Thrown on a range error. 23 * Thrown on a range error.
47 */ 24 */
@@ -218,17 +195,17 @@ private void rangeMsgPut(ref char[] r, scope const(char)[] e) @nogc nothrow pure
218 */ 195 */
219class AssertError : Error 196class AssertError : Error
220{ 197{
221 @safe pure nothrow this( string file, size_t line ) 198 @safe pure nothrow @nogc this( string file, size_t line )
222 { 199 {
223 this(cast(Throwable)null, file, line); 200 this(cast(Throwable)null, file, line);
224 } 201 }
225 202
226 @safe pure nothrow this( Throwable next, string file = __FILE__, size_t line = __LINE__ ) 203 @safe pure nothrow @nogc this( Throwable next, string file = __FILE__, size_t line = __LINE__ )
227 { 204 {
228 this( "Assertion failure", file, line, next); 205 this( "Assertion failure", file, line, next);
229 } 206 }
230 207
231 @safe pure nothrow this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) 208 @safe pure nothrow @nogc this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
232 { 209 {
233 super( msg, file, line, next ); 210 super( msg, file, line, next );
234 } 211 }
@@ -692,26 +669,49 @@ extern (C) void onFinalizeError( TypeInfo info, Throwable e, string file = __FIL
692 throw staticError!FinalizeError(info, e, file, line); 669 throw staticError!FinalizeError(info, e, file, line);
693} 670}
694 671
695/** 672version (D_BetterC)
696 * A callback for out of memory errors in D. An $(LREF OutOfMemoryError) will be
697 * thrown.
698 *
699 * Throws:
700 * $(LREF OutOfMemoryError).
701 */
702extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
703{ 673{
704 // NOTE: Since an out of memory condition exists, no allocation must occur 674 // When compiling with -betterC we use template functions so if they are
705 // while generating this object. 675 // used the bodies are copied into the user's program so there is no need
706 throw staticError!OutOfMemoryError(); 676 // for the D runtime during linking.
707}
708 677
709extern (C) void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc 678 // In the future we might want to convert all functions in this module to
710{ 679 // templates even for ordinary builds instead of providing them as an
711 // suppress stacktrace until they are @nogc 680 // extern(C) library.
712 throw staticError!OutOfMemoryError(false); 681
682 void onOutOfMemoryError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
683 {
684 assert(0, "Memory allocation failed");
685 }
686 alias onOutOfMemoryErrorNoGC = onOutOfMemoryError;
687
688 void onInvalidMemoryOperationError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
689 {
690 assert(0, "Invalid memory operation");
691 }
713} 692}
693else
694{
695 /**
696 * A callback for out of memory errors in D. An $(LREF OutOfMemoryError) will be
697 * thrown.
698 *
699 * Throws:
700 * $(LREF OutOfMemoryError).
701 */
702 extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
703 {
704 // NOTE: Since an out of memory condition exists, no allocation must occur
705 // while generating this object.
706 throw staticError!OutOfMemoryError();
707 }
714 708
709 extern (C) void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc
710 {
711 // suppress stacktrace until they are @nogc
712 throw staticError!OutOfMemoryError(false);
713 }
714}
715 715
716/** 716/**
717 * A callback for invalid memory operations in D. An 717 * 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)
2830 2830
2831 private struct AA { void* impl; } 2831 private struct AA { void* impl; }
2832 // size_t _aaLen(in AA aa) pure nothrow @nogc; 2832 // size_t _aaLen(in AA aa) pure nothrow @nogc;
2833 private void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey) pure nothrow; 2833 private void* _aaGetY(scope AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey) pure nothrow;
2834 private void* _aaGetX(AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey, out bool found) pure nothrow; 2834 private void* _aaGetX(scope AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey, out bool found) pure nothrow;
2835 // inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz, in void* pkey); 2835 // inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz, in void* pkey);
2836 inout(void[]) _aaValues(inout AA aa, const size_t keysz, const size_t valsz, const TypeInfo tiValueArray) pure nothrow; 2836 inout(void[]) _aaValues(inout AA aa, const size_t keysz, const size_t valsz, const TypeInfo tiValueArray) pure nothrow;
2837 inout(void[]) _aaKeys(inout AA aa, const size_t keysz, const TypeInfo tiKeyArray) pure nothrow; 2837 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
504 * If key was not in the aa, a mutable pointer to newly inserted value which 504 * If key was not in the aa, a mutable pointer to newly inserted value which
505 * is set to all zeros 505 * is set to all zeros
506 */ 506 */
507extern (C) void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti, 507extern (C) void* _aaGetY(scope AA* paa, const TypeInfo_AssociativeArray ti,
508 const size_t valsz, scope const void* pkey) 508 const size_t valsz, scope const void* pkey)
509{ 509{
510 bool found; 510 bool found;
@@ -525,7 +525,7 @@ extern (C) void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti,
525 * If key was not in the aa, a mutable pointer to newly inserted value which 525 * If key was not in the aa, a mutable pointer to newly inserted value which
526 * is set to all zeros 526 * is set to all zeros
527 */ 527 */
528extern (C) void* _aaGetX(AA* paa, const TypeInfo_AssociativeArray ti, 528extern (C) void* _aaGetX(scope AA* paa, const TypeInfo_AssociativeArray ti,
529 const size_t valsz, scope const void* pkey, out bool found) 529 const size_t valsz, scope const void* pkey, out bool found)
530{ 530{
531 // lazily alloc implementation 531 // 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 @@
1c0cc5e917db105301dd1199b4b3c854626526407 1ac296f80cda437483b743f953dc69cb1271c82df
2 2
3The first line of this file holds the git revision number of the last 3The first line of this file holds the git revision number of the last
4merge done from the dlang/phobos repository. 4merge 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 \
130 std/experimental/typecons.d std/file.d std/format/internal/floats.d \ 130 std/experimental/typecons.d std/file.d std/format/internal/floats.d \
131 std/format/internal/read.d std/format/internal/write.d \ 131 std/format/internal/read.d std/format/internal/write.d \
132 std/format/package.d std/format/read.d std/format/spec.d \ 132 std/format/package.d std/format/read.d std/format/spec.d \
133 std/format/write.d std/functional.d std/getopt.d \ 133 std/format/write.d std/functional.d std/getopt.d std/int128.d \
134 std/internal/attributes.d std/internal/cstring.d \ 134 std/internal/attributes.d std/internal/cstring.d \
135 std/internal/math/biguintcore.d std/internal/math/biguintnoasm.d \ 135 std/internal/math/biguintcore.d std/internal/math/biguintnoasm.d \
136 std/internal/math/errorfunction.d std/internal/math/gammafunction.d \ 136 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
228@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/spec.lo \ 228@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/spec.lo \
229@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/write.lo \ 229@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/write.lo \
230@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/functional.lo std/getopt.lo \ 230@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/functional.lo std/getopt.lo \
231@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/int128.lo \
231@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/attributes.lo \ 232@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/attributes.lo \
232@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/cstring.lo \ 233@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/cstring.lo \
233@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/math/biguintcore.lo \ 234@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/math/biguintcore.lo \
@@ -591,7 +592,7 @@ libgphobos_la_LINK = $(LIBTOOL) --tag=D $(libgphobos_la_LIBTOOLFLAGS) \
591@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/experimental/typecons.d std/file.d std/format/internal/floats.d \ 592@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/experimental/typecons.d std/file.d std/format/internal/floats.d \
592@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/internal/read.d std/format/internal/write.d \ 593@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/internal/read.d std/format/internal/write.d \
593@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/package.d std/format/read.d std/format/spec.d \ 594@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/package.d std/format/read.d std/format/spec.d \
594@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/write.d std/functional.d std/getopt.d \ 595@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/format/write.d std/functional.d std/getopt.d std/int128.d \
595@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/attributes.d std/internal/cstring.d \ 596@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/attributes.d std/internal/cstring.d \
596@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/math/biguintcore.d std/internal/math/biguintnoasm.d \ 597@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/math/biguintcore.d std/internal/math/biguintnoasm.d \
597@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/math/errorfunction.d std/internal/math/gammafunction.d \ 598@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)
846std/format/write.lo: std/format/$(am__dirstamp) 847std/format/write.lo: std/format/$(am__dirstamp)
847std/functional.lo: std/$(am__dirstamp) 848std/functional.lo: std/$(am__dirstamp)
848std/getopt.lo: std/$(am__dirstamp) 849std/getopt.lo: std/$(am__dirstamp)
850std/int128.lo: std/$(am__dirstamp)
849std/internal/$(am__dirstamp): 851std/internal/$(am__dirstamp):
850 @$(MKDIR_P) std/internal 852 @$(MKDIR_P) std/internal
851 @: > std/internal/$(am__dirstamp) 853 @: > 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,
63import std.traits : isArray; 63import std.traits : isArray;
64 64
65// Make sure module header code examples work correctly. 65// Make sure module header code examples work correctly.
66@safe unittest 66pure @safe unittest
67{ 67{
68 ubyte[] data = [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]; 68 ubyte[] data = [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e];
69 69
@@ -82,7 +82,7 @@ import std.traits : isArray;
82alias Base64 = Base64Impl!('+', '/'); 82alias Base64 = Base64Impl!('+', '/');
83 83
84/// 84///
85@safe unittest 85pure @safe unittest
86{ 86{
87 ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f]; 87 ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];
88 assert(Base64.encode(data) == "g9cwegE/"); 88 assert(Base64.encode(data) == "g9cwegE/");
@@ -98,7 +98,7 @@ alias Base64 = Base64Impl!('+', '/');
98alias Base64URL = Base64Impl!('-', '_'); 98alias Base64URL = Base64Impl!('-', '_');
99 99
100/// 100///
101@safe unittest 101pure @safe unittest
102{ 102{
103 ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f]; 103 ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];
104 assert(Base64URL.encode(data) == "g9cwegE_"); 104 assert(Base64URL.encode(data) == "g9cwegE_");
@@ -114,7 +114,7 @@ alias Base64URL = Base64Impl!('-', '_');
114alias Base64URLNoPadding = Base64Impl!('-', '_', Base64.NoPadding); 114alias Base64URLNoPadding = Base64Impl!('-', '_', Base64.NoPadding);
115 115
116/// 116///
117@safe unittest 117pure @safe unittest
118{ 118{
119 ubyte[] data = [0x83, 0xd7, 0x30, 0x7b, 0xef]; 119 ubyte[] data = [0x83, 0xd7, 0x30, 0x7b, 0xef];
120 assert(Base64URLNoPadding.encode(data) == "g9cwe-8"); 120 assert(Base64URLNoPadding.encode(data) == "g9cwe-8");
@@ -180,7 +180,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=')
180 * Returns: 180 * Returns:
181 * The length of a Base64 encoding of an array of the given length. 181 * The length of a Base64 encoding of an array of the given length.
182 */ 182 */
183 @safe 183 @safe @nogc
184 pure nothrow size_t encodeLength(in size_t sourceLength) 184 pure nothrow size_t encodeLength(in size_t sourceLength)
185 { 185 {
186 static if (Padding == NoPadding) 186 static if (Padding == NoPadding)
@@ -218,8 +218,8 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=')
218 * The slice of $(D_PARAM buffer) that contains the encoded string. 218 * The slice of $(D_PARAM buffer) that contains the encoded string.
219 */ 219 */
220 @trusted 220 @trusted
221 pure char[] encode(R1, R2)(in R1 source, return scope R2 buffer) if (isArray!R1 && is(ElementType!R1 : ubyte) && 221 pure char[] encode(R1, R2)(const scope R1 source, return scope R2 buffer)
222 is(R2 == char[])) 222 if (isArray!R1 && is(ElementType!R1 : ubyte) && is(R2 == char[]))
223 in 223 in
224 { 224 {
225 assert(buffer.length >= encodeLength(source.length), "Insufficient buffer for encoding"); 225 assert(buffer.length >= encodeLength(source.length), "Insufficient buffer for encoding");
@@ -277,9 +277,9 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=')
277 } 277 }
278 278
279 /// 279 ///
280 @safe unittest 280 @nogc nothrow @safe unittest
281 { 281 {
282 ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f]; 282 ubyte[6] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];
283 char[32] buffer; // much bigger than necessary 283 char[32] buffer; // much bigger than necessary
284 284
285 // Just to be sure... 285 // Just to be sure...
@@ -287,7 +287,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=')
287 assert(buffer.length >= encodedLength); 287 assert(buffer.length >= encodedLength);
288 288
289 // encode() returns a slice to the provided buffer. 289 // encode() returns a slice to the provided buffer.
290 auto encoded = Base64.encode(data, buffer[]); 290 auto encoded = Base64.encode(data[], buffer[]);
291 assert(encoded is buffer[0 .. encodedLength]); 291 assert(encoded is buffer[0 .. encodedLength]);
292 assert(encoded == "g9cwegE/"); 292 assert(encoded == "g9cwegE/");
293 } 293 }
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 @@
1// Written in the D programming language
2/**
3 * Implements a signed 128 bit integer type.
4 *
5 Author: Walter Bright
6 Copyright: Copyright (c) 2022, D Language Foundation
7 License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)
8 Source: $(PHOBOSSRC std/int128.d)
9 */
10module std.int128;
11
12private import core.int128;
13
14
15/***********************************
16 * 128 bit signed integer type.
17 */
18
19public struct Int128
20{
21 @safe pure nothrow @nogc:
22
23 Cent data; /// core.int128.Cent
24
25 /****************
26 * Construct an `Int128` from a `long` value.
27 * The upper 64 bits are formed by sign extension.
28 * Params:
29 * lo = signed lower 64 bits
30 */
31 this(long lo)
32 {
33 data.lo = lo;
34 data.hi = lo < 0 ? ~0L : 0;
35 }
36
37 /****************
38 * Construct an `Int128` from a `ulong` value.
39 * The upper 64 bits are set to zero.
40 * Params:
41 * lo = unsigned lower 64 bits
42 */
43 this(ulong lo)
44 {
45 data.lo = lo;
46 data.hi = 0;
47 }
48
49 /****************
50 * Construct an `Int128` from a `long` value.
51 * Params:
52 * hi = upper 64 bits
53 * lo = lower 64 bits
54 */
55 this(long hi, long lo)
56 {
57 data.hi = hi;
58 data.lo = lo;
59 }
60
61 /********************
62 * Construct an `Int128` from a `Cent`.
63 * Params:
64 * data = Cent data
65 */
66 this(Cent data)
67 {
68 this.data = data;
69 }
70
71 /********************
72 * Returns: hash value for Int128
73 */
74 size_t toHash() const
75 {
76 return cast(size_t)((data.lo & 0xFFFF_FFFF) + (data.hi & 0xFFFF_FFFF) + (data.lo >> 32) + (data.hi >> 32));
77 }
78
79 /************************
80 * Compare for equality
81 * Params: lo = signed value to compare with
82 * Returns: true if Int128 equals value
83 */
84 bool opEquals(long lo) const
85 {
86 return data.lo == lo && data.hi == (lo >> 63);
87 }
88
89 /************************
90 * Compare for equality
91 * Params: lo = unsigned value to compare with
92 * Returns: true if Int128 equals value
93 */
94 bool opEquals(ulong lo) const
95 {
96 return data.hi == 0 && data.lo == lo;
97 }
98
99 /************************
100 * Compare for equality
101 * Params: op2 = value to compare with
102 * Returns: true if Int128 equals value
103 */
104 bool opEquals(Int128 op2) const
105 {
106 return data.hi == op2.data.hi && data.lo == op2.data.lo;
107 }
108
109 /** Support unary arithmentic operator +
110 * Params: op = "+"
111 * Returns: lvalue of result
112 */
113 Int128 opUnary(string op)() const
114 if (op == "+")
115 {
116 return this;
117 }
118
119 /** Support unary arithmentic operator - ~
120 * Params: op = "-", "~"
121 * Returns: lvalue of result
122 */
123 Int128 opUnary(string op)() const
124 if (op == "-" || op == "~")
125 {
126 static if (op == "-")
127 return Int128(neg(this.data));
128 else static if (op == "~")
129 return Int128(com(this.data));
130 }
131
132 /** Support unary arithmentic operator ++ --
133 * Params: op = "++", "--"
134 * Returns: lvalue of result
135 */
136 Int128 opUnary(string op)()
137 if (op == "++" || op == "--")
138 {
139 static if (op == "++")
140 this.data = inc(this.data);
141 else static if (op == "--")
142 this.data = dec(this.data);
143 else
144 static assert(0, op);
145 return this;
146 }
147
148 /** Support casting to a bool
149 * Params: T = bool
150 * Returns: boolean result
151 */
152 bool opCast(T : bool)() const
153 {
154 return tst(this.data);
155 }
156
157 /** Support binary arithmetic operators + - * / % & | ^ << >> >>>
158 * Params:
159 * op = one of the arithmetic binary operators
160 * op2 = second operand
161 * Returns: value after the operation is applied
162 */
163 Int128 opBinary(string op)(Int128 op2) const
164 if (op == "+" || op == "-" ||
165 op == "*" || op == "/" || op == "%" ||
166 op == "&" || op == "|" || op == "^")
167 {
168 static if (op == "+")
169 return Int128(add(this.data, op2.data));
170 else static if (op == "-")
171 return Int128(sub(this.data, op2.data));
172 else static if (op == "*")
173 return Int128(mul(this.data, op2.data));
174 else static if (op == "/")
175 return Int128(div(this.data, op2.data));
176 else static if (op == "%")
177 {
178 Cent modulus;
179 divmod(this.data, op2.data, modulus);
180 return Int128(modulus);
181 }
182 else static if (op == "&")
183 return Int128(and(this.data, op2.data));
184 else static if (op == "|")
185 return Int128(or(this.data, op2.data));
186 else static if (op == "^")
187 return Int128(xor(this.data, op2.data));
188 else
189 static assert(0, "wrong op value");
190 }
191
192 /// ditto
193 Int128 opBinary(string op)(long op2) const
194 if (op == "+" || op == "-" ||
195 op == "*" || op == "/" || op == "%" ||
196 op == "&" || op == "|" || op == "^")
197 {
198 return mixin("this " ~ op ~ " Int128(0, op2)");
199 }
200
201 /// ditto
202 Int128 opBinaryRight(string op)(long op2) const
203 if (op == "+" || op == "-" ||
204 op == "*" || op == "/" || op == "%" ||
205 op == "&" || op == "|" || op == "^")
206 {
207 mixin("return Int128(0, op2) " ~ op ~ " this;");
208 }
209
210 /// ditto
211 Int128 opBinary(string op)(long op2) const
212 if (op == "<<")
213 {
214 return Int128(shl(this.data, cast(uint) op2));
215 }
216
217 /// ditto
218 Int128 opBinary(string op)(long op2) const
219 if (op == ">>")
220 {
221 return Int128(sar(this.data, cast(uint) op2));
222 }
223
224 /// ditto
225 Int128 opBinary(string op)(long op2) const
226 if (op == ">>>")
227 {
228 return Int128(shr(this.data, cast(uint) op2));
229 }
230
231 /** arithmetic assignment operators += -= *= /= %= &= |= ^= <<= >>= >>>=
232 * Params: op = one of +, -, etc.
233 * op2 = second operand
234 * Returns: lvalue of updated left operand
235 */
236 ref Int128 opOpAssign(string op)(Int128 op2)
237 if (op == "+" || op == "-" ||
238 op == "*" || op == "/" || op == "%" ||
239 op == "&" || op == "|" || op == "^" ||
240 op == "<<" || op == ">>" || op == ">>>")
241 {
242 mixin("this = this " ~ op ~ " op2;");
243 return this;
244 }
245
246 /// ditto
247 ref Int128 opOpAssign(string op)(long op2)
248 if (op == "+" || op == "-" ||
249 op == "*" || op == "/" || op == "%" ||
250 op == "&" || op == "|" || op == "^" ||
251 op == "<<" || op == ">>" || op == ">>>")
252 {
253 mixin("this = this " ~ op ~ " op2;");
254 return this;
255 }
256
257 /** support signed arithmentic comparison operators < <= > >=
258 * Params: op2 = right hand operand
259 * Returns: -1 for less than, 0 for equals, 1 for greater than
260 */
261 int opCmp(Int128 op2) const
262 {
263 return this == op2 ? 0 : gt(this.data, op2.data) * 2 - 1;
264 }
265
266 /** support signed arithmentic comparison operators < <= > >=
267 * Params: op2 = right hand operand
268 * Returns: -1 for less than, 0 for equals, 1 for greater than
269 */
270 int opCmp(long op2) const
271 {
272 return opCmp(Int128(0, op2));
273 }
274
275 enum min = Int128(long.min, 0); /// minimum value
276 enum max = Int128(long.max, ulong.max); /// maximum value
277}
278
279/********************************************* Tests ************************************/
280
281version (unittest)
282{
283import core.stdc.stdio;
284
285@trusted void print(Int128 c)
286{
287 printf("%lld, %lld\n", c.data.hi, c.data.lo);
288}
289
290@trusted void printx(Int128 c)
291{
292 printf("%llx, %llx\n", c.data.hi, c.data.lo);
293}
294}
295
296/// Int128 tests
297@safe pure nothrow @nogc
298unittest
299{
300 Int128 c = Int128(5, 6);
301 assert(c == c);
302 assert(c == +c);
303 assert(c == - -c);
304 assert(~c == Int128(~5, ~6));
305 ++c;
306 assert(c == Int128(5, 7));
307 assert(--c == Int128(5, 6));
308 assert(!!c);
309 assert(!Int128());
310
311 assert(c + Int128(10, 20) == Int128(15, 26));
312 assert(c - Int128(1, 2) == Int128(4, 4));
313 assert(c * Int128(100, 2) == Int128(610, 12));
314 assert(c / Int128(3, 2) == Int128(0, 1));
315 assert(c % Int128(3, 2) == Int128(2, 4));
316 assert((c & Int128(3, 2)) == Int128(1, 2));
317 assert((c | Int128(3, 2)) == Int128(7, 6));
318 assert((c ^ Int128(3, 2)) == Int128(6, 4));
319
320 assert(c + 15 == Int128(5, 21));
321 assert(c - 15 == Int128(4, -9));
322 assert(c * 15 == Int128(75, 90));
323 assert(c / 15 == Int128(0, 6148914691236517205));
324 assert(c % 15 == Int128(0, 11));
325 assert((c & 15) == Int128(0, 6));
326 assert((c | 15) == Int128(5, 15));
327 assert((c ^ 15) == Int128(5, 9));
328
329 assert(15 + c == Int128(5, 21));
330 assert(15 - c == Int128(-5, 9));
331 assert(15 * c == Int128(75, 90));
332 assert(15 / c == Int128(0, 0));
333 assert(15 % c == Int128(0, 15));
334 assert((15 & c) == Int128(0, 6));
335 assert((15 | c) == Int128(5, 15));
336 assert((15 ^ c) == Int128(5, 9));
337
338 assert(c << 1 == Int128(10, 12));
339 assert(-c >> 1 == Int128(-3, 9223372036854775805));
340 assert(-c >>> 1 == Int128(9223372036854775805, 9223372036854775805));
341
342 assert((c += 1) == Int128(5, 7));
343 assert((c -= 1) == Int128(5, 6));
344 assert((c += Int128(0, 1)) == Int128(5, 7));
345 assert((c -= Int128(0, 1)) == Int128(5, 6));
346 assert((c *= 2) == Int128(10, 12));
347 assert((c /= 2) == Int128(5, 6));
348 assert((c %= 2) == Int128());
349 c += Int128(5, 6);
350 assert((c *= Int128(10, 20)) == Int128(160, 120));
351 assert((c /= Int128(10, 20)) == Int128(0, 15));
352 c += Int128(72, 0);
353 assert((c %= Int128(10, 20)) == Int128(1, -125));
354 assert((c &= Int128(3, 20)) == Int128(1, 0));
355 assert((c |= Int128(8, 2)) == Int128(9, 2));
356 assert((c ^= Int128(8, 2)) == Int128(1, 0));
357 c |= Int128(10, 5);
358 assert((c <<= 1) == Int128(11 * 2, 5 * 2));
359 assert((c >>>= 1) == Int128(11, 5));
360 c = Int128(long.min, long.min);
361 assert((c >>= 1) == Int128(long.min >> 1, cast(ulong) long.min >> 1));
362
363 assert(-Int128.min == Int128.min);
364 assert(Int128.max + 1 == Int128.min);
365
366 c = Int128(5, 6);
367 assert(c < Int128(6, 5));
368 assert(c > 10);
369
370 c = Int128(-1UL);
371 assert(c == -1UL);
372 c = Int128(-1L);
373 assert(c == -1L);
374}
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)
1519 import std.range; 1519 import std.range;
1520 // ir() wraps an array in a plain (i.e. non-forward) input range, so that 1520 // ir() wraps an array in a plain (i.e. non-forward) input range, so that
1521 // we can test both code paths 1521 // we can test both code paths
1522 InputRange!(C[]) ir(C)(C[][] p...) { return inputRangeObject(p); } 1522 InputRange!(C[]) ir(C)(C[][] p...) { return inputRangeObject(p.dup); }
1523 version (Posix) 1523 version (Posix)
1524 { 1524 {
1525 assert(buildPath("foo") == "foo"); 1525 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)
1422 enum val = "val" ~ (name == "val" ? "_" : ""); 1422 enum val = "val" ~ (name == "val" ? "_" : "");
1423 enum ptr = "ptr" ~ (name == "ptr" ? "_" : ""); 1423 enum ptr = "ptr" ~ (name == "ptr" ? "_" : "");
1424 mixin(" 1424 mixin("
1425 enum hasDefaultArg = (PT[i .. i+1] " ~ args ~ ") { return true; };
1426 ");
1427 static if (is(typeof(hasDefaultArg())))
1428 {
1429 mixin("
1425 // workaround scope escape check, see 1430 // workaround scope escape check, see
1426 // https://issues.dlang.org/show_bug.cgi?id=16582 1431 // https://issues.dlang.org/show_bug.cgi?id=16582
1427 // should use return scope once available 1432 // should use return scope once available
@@ -1432,10 +1437,9 @@ if (isCallable!func)
1432 auto " ~ val ~ " = " ~ args ~ "[0]; 1437 auto " ~ val ~ " = " ~ args ~ "[0];
1433 auto " ~ ptr ~ " = &" ~ val ~ "; 1438 auto " ~ ptr ~ " = &" ~ val ~ ";
1434 return *" ~ ptr ~ "; 1439 return *" ~ ptr ~ ";
1435 }; 1440 };");
1436 ");
1437 static if (is(typeof(get())))
1438 enum Get = get(); 1441 enum Get = get();
1442 }
1439 else 1443 else
1440 alias Get = void; 1444 alias Get = void;
1441 // If default arg doesn't exist, returns void instead. 1445 // If default arg doesn't exist, returns void instead.
@@ -1483,6 +1487,17 @@ if (isCallable!func)
1483 static foreach (V; Voids) static assert(is(V == void)); 1487 static foreach (V; Voids) static assert(is(V == void));
1484} 1488}
1485 1489
1490// https://issues.dlang.org/show_bug.cgi?id=20182
1491@safe pure nothrow @nogc unittest
1492{
1493 struct S
1494 {
1495 this(ref S) {}
1496 }
1497
1498 static assert(__traits(compiles, ParameterDefaults!(S.__ctor)));
1499}
1500
1486/** 1501/**
1487 * Alternate name for $(LREF ParameterDefaults), kept for legacy compatibility. 1502 * Alternate name for $(LREF ParameterDefaults), kept for legacy compatibility.
1488 */ 1503 */