Skip to content

Commit 902a4c5

Browse files
committed
Merge remote-tracking branch 'upstream/master' into dirEntries-pred
2 parents ca3caf4 + 29a71ef commit 902a4c5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1872
-4941
lines changed

.dscanner.ini

Lines changed: 9 additions & 18 deletions
Large diffs are not rendered by default.

CODEOWNERS

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ std/digest/* @jpf91
3636
std/experimental/allocator/* @andralex @wilzbach @PetarKirov
3737
std/experimental/checkedint/* @andralex
3838
std/experimental/logger/* @burner
39-
# std/experimental/typecons.d
4039
std/file.d @CyberShadow
4140
# std/format.d
4241
# std/functional.d
@@ -72,6 +71,5 @@ std/utf.d @jmdavis
7271
std/uuid.d @jpf91
7372
# std/variant.d
7473
std/windows/* @CyberShadow
75-
# std/xml.d
7674
std/zip.d @CyberShadow
7775
std/zlib.d @CyberShadow

changelog/borrow_for_refcounted.dd

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
Added `SafeRefCounted`, that can be used in `@safe` with `-preview=dip1000`.
2+
3+
`RefCounted` is only available for `@system` code, because of the possibility of
4+
escaping a reference to its payload past the end of its lifetime. a modified
5+
copy of it, `std.typecons.SafeRefCounted` has been added. Also added is a
6+
`borrow` function, that lets one safely access and modify the payload.
7+
`-preview=dip1000` prevents escaping a reference to it in `@safe` code.
8+
9+
-------
10+
@safe pure nothrow void fun()
11+
{
12+
import std.typecons;
13+
14+
auto rcInt = safeRefCounted(5);
15+
assert(rcInt.borrow!(theInt => theInt) == 5);
16+
auto sameInt = rcInt;
17+
assert(sameInt.borrow!"a" == 5);
18+
19+
// using `ref` in the function
20+
auto arr = [0, 1, 2, 3, 4, 5, 6];
21+
sameInt.borrow!(ref (x) => arr[x]) = 10;
22+
assert(arr == [0, 1, 2, 3, 4, 10, 6]);
23+
24+
// modifying the payload via an alias
25+
sameInt.borrow!"a*=2";
26+
assert(rcInt.borrow!"a" == 10);
27+
}
28+
-------
29+
30+
Direct access to the payload unfortunately has to be `@system`, though. While
31+
`-dip1000` could prevent escaping the reference, it is possible to destroy the
32+
last reference before the end of it's scope:
33+
34+
-------
35+
int destroyFirstAndUseLater()
36+
{
37+
import std.typecons;
38+
39+
auto rc = SafeRefCounted!int(123);
40+
int* ptr = &rc.refCountedPayload();
41+
destroy(rc);
42+
return *ptr; // Reads from freed memory. Don't do this.
43+
}
44+
-------
45+
46+
As a side effect, this enabled us to make $(REF dirEntries, std, file) `@safe`
47+
with `-preview=dip1000`.
48+
49+
Some member functions of `RefCounted` that are `@safe` are not so in
50+
`SafeRefCounted`. The `RefCounted` type and `refCounted` function are still
51+
available for the old behaviour. However, their main purpose is backwards
52+
compatibility. They are not recommended for new code.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
std.experimental.typecons has been removed
2+
3+
This was an attempt to update `std.typecons.wrap` with an implementation that could work with struct, but it did not go anywhere.
4+
See [this post on the forum](https://forum.dlang.org/post/ialskabybaxtqamgtwge@forum.dlang.org).

changelog/remove-std-digest-digest.dd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
std.digest.digest has been removed
2+
3+
This module was initially deprecated in 2.076.1, and has been empty since
4+
2.092.0 when all deprecated symbols were removed in favour of importing
5+
`std.digest` or its submodules instead.

changelog/remove-std-xml.dd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
std.xml has been removed
2+
3+
This module is considered out-dated and not up to Phobos' current standards.
4+
If you still need it, go to $(LINK https://github.com/DigitalMars/undeaD)

index.dd

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ $(BOOKTABLE ,
7070
$(TDNW $(MREF std,json))
7171
$(TD Read/write data in JSON format.)
7272
)
73-
$(TR
74-
$(TDNW $(MREF std,xml))
75-
$(TD Read/write data in XML format.)
76-
)
7773
$(TR
7874
$(TDNW $(MREF std,zip))
7975
$(TD Read/write data in the ZIP archive format.)

posix.mak

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ PACKAGE_std = array ascii base64 bigint bitmanip checkedint compiler complex con
216216
functional getopt int128 json mathspecial meta mmfile numeric \
217217
outbuffer package parallelism path process random signals socket stdint \
218218
stdio string sumtype system traits typecons \
219-
uri utf uuid variant xml zip zlib
220-
PACKAGE_std_experimental = checkedint typecons
219+
uri utf uuid variant zip zlib
220+
PACKAGE_std_experimental = checkedint
221221
PACKAGE_std_algorithm = comparison iteration mutation package searching setops \
222222
sorting
223223
PACKAGE_std_container = array binaryheap dlist package rbtree slist util
@@ -259,7 +259,6 @@ EXTRA_DOCUMENTABLES := $(EXTRA_MODULES_COMMON)
259259

260260
EXTRA_MODULES_INTERNAL := $(addprefix std/, \
261261
algorithm/internal \
262-
digest/digest \
263262
$(addprefix internal/, \
264263
cstring memory digest/sha_SSSE3 \
265264
$(addprefix math/, biguintcore biguintnoasm biguintx86 \

std/algorithm/comparison.d

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,14 +577,24 @@ Returns:
577577
and `T3` are different.
578578
*/
579579
T1 clamp(T1, T2, T3)(T1 val, T2 lower, T3 upper)
580-
if (is(typeof(val.lessThan(lower) ? lower : val.greaterThan(upper) ? upper : val) : T1))
580+
if (is(typeof(val.lessThan(lower) ? lower : val.greaterThan(upper) ? upper : val))
581+
&& (is(T2 : T1) && is(T3 : T1)))
582+
// cannot use :
583+
// `if (is(typeof(val.lessThan(lower) ? lower : val.greaterThan(upper) ? upper : val) : T1))
584+
// because of https://issues.dlang.org/show_bug.cgi?id=16235.
585+
// Once that is fixed, we can simply use the ternary in both the template constraint
586+
// and the template body
581587
in
582588
{
583589
assert(!lower.greaterThan(upper), "Lower can't be greater than upper.");
584590
}
585591
do
586592
{
587-
return val.lessThan(lower) ? lower : val.greaterThan(upper) ? upper : val;
593+
if (val.lessThan(lower))
594+
return lower;
595+
else if (val.greaterThan(upper))
596+
return upper;
597+
return val;
588598
}
589599

590600
///
@@ -637,6 +647,12 @@ do
637647
assert(x.clamp(lo, hi).y == 42);
638648
}
639649

650+
// https://issues.dlang.org/show_bug.cgi?id=23268
651+
@safe pure nothrow @nogc unittest
652+
{
653+
static assert(__traits(compiles, clamp(short.init, short.init, cast(const) short.init)));
654+
}
655+
640656
// cmp
641657
/**********************************
642658
Performs a lexicographical comparison on two

std/algorithm/iteration.d

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,23 @@ private struct MapResult(alias fun, Range)
771771
assert(dd.length == 4);
772772
}
773773

774+
// Verify fix for: https://issues.dlang.org/show_bug.cgi?id=16034
775+
@safe unittest
776+
{
777+
struct One
778+
{
779+
int entry = 1;
780+
@disable this(this);
781+
}
782+
783+
One[] ones = [One(), One()];
784+
785+
import std.algorithm.comparison : equal;
786+
787+
assert(ones.map!`a.entry + 1`.equal([2, 2]));
788+
}
789+
790+
774791
@safe unittest
775792
{
776793
import std.algorithm.comparison : equal;
@@ -1798,7 +1815,7 @@ if (isInputRange!R)
17981815
assert(equal(g3, [ tuple(1, 2u), tuple(2, 2u) ]));
17991816

18001817
interface I {}
1801-
class C : I { override size_t toHash() const nothrow @safe { return 0; } }
1818+
static class C : I { override size_t toHash() const nothrow @safe { return 0; } }
18021819
const C[] a4 = [new const C()];
18031820
auto g4 = a4.group!"a is b";
18041821
assert(g4.front[1] == 1);
@@ -2255,25 +2272,26 @@ if (isForwardRange!Range)
22552272
import std.algorithm.comparison : equal;
22562273

22572274
size_t popCount = 0;
2258-
class RefFwdRange
2275+
static class RefFwdRange
22592276
{
22602277
int[] impl;
2278+
size_t* pcount;
22612279

22622280
@safe nothrow:
22632281

2264-
this(int[] data) { impl = data; }
2282+
this(int[] data, size_t* pcount) { impl = data; this.pcount = pcount; }
22652283
@property bool empty() { return impl.empty; }
22662284
@property auto ref front() { return impl.front; }
22672285
void popFront()
22682286
{
22692287
impl.popFront();
2270-
popCount++;
2288+
(*pcount)++;
22712289
}
2272-
@property auto save() { return new RefFwdRange(impl); }
2290+
@property auto save() { return new RefFwdRange(impl, pcount); }
22732291
}
22742292
static assert(isForwardRange!RefFwdRange);
22752293

2276-
auto testdata = new RefFwdRange([1, 3, 5, 2, 4, 7, 6, 8, 9]);
2294+
auto testdata = new RefFwdRange([1, 3, 5, 2, 4, 7, 6, 8, 9], &popCount);
22772295
auto groups = testdata.chunkBy!((a,b) => (a % 2) == (b % 2));
22782296
auto outerSave1 = groups.save;
22792297

@@ -6058,7 +6076,7 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
60586076
import std.algorithm.comparison : equal;
60596077

60606078
// Test by-reference separator
6061-
class RefSep {
6079+
static class RefSep {
60626080
@safe:
60636081
string _impl;
60646082
this(string s) { _impl = s; }
@@ -7908,7 +7926,13 @@ if (isRandomAccessRange!Range && hasLength!Range)
79087926
_indices = iota(size_t(r.length)).array;
79097927
_empty = r.length == 0;
79107928
}
7911-
7929+
private this(size_t[] indices, size_t[] state, Range r, bool empty_)
7930+
{
7931+
_indices = indices;
7932+
_state = state;
7933+
_r = r;
7934+
_empty = empty_;
7935+
}
79127936
/// Returns: `true` if the range is empty, `false` otherwise.
79137937
@property bool empty() const pure nothrow @safe @nogc
79147938
{
@@ -7949,6 +7973,11 @@ if (isRandomAccessRange!Range && hasLength!Range)
79497973

79507974
next(2);
79517975
}
7976+
/// Returns: an independent copy of the permutations range.
7977+
auto save()
7978+
{
7979+
return typeof(this)(_indices.dup, _state.dup, _r.save, _empty);
7980+
}
79527981
}
79537982

79547983
///
@@ -7964,3 +7993,15 @@ if (isRandomAccessRange!Range && hasLength!Range)
79647993
[1, 2, 0],
79657994
[2, 1, 0]]));
79667995
}
7996+
7997+
@safe unittest
7998+
{
7999+
import std.algorithm.comparison : equal;
8000+
import std.range : ElementType;
8001+
import std.array : array;
8002+
auto p = [1, 2, 3].permutations;
8003+
auto x = p.save.front;
8004+
p.popFront;
8005+
auto y = p.front;
8006+
assert(x != y);
8007+
}

0 commit comments

Comments
 (0)