mirror of
https://github.com/dlang/phobos.git
synced 2025-05-03 16:40:48 +03:00
Merge pull request #7623 from MartinNowak/merge_stable
merge stable merged-on-behalf-of: Nathan Sashihara <n8sh@users.noreply.github.com>
This commit is contained in:
commit
56b1919e9b
3 changed files with 100 additions and 28 deletions
|
@ -154,6 +154,10 @@ ifdef NO_AUTODECODE
|
|||
override DFLAGS += -version=NoAutodecodeStrings
|
||||
endif
|
||||
|
||||
ifdef NO_AUTODECODE
|
||||
override DFLAGS += -version=NoAutodecodeStrings
|
||||
endif
|
||||
|
||||
UDFLAGS=-unittest -version=StdUnittest
|
||||
|
||||
# Set DOTOBJ and DOTEXE
|
||||
|
|
|
@ -3059,18 +3059,25 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R &&
|
|||
static if (is(typeof(unaryFun!transform(r.front))))
|
||||
{
|
||||
alias transformFun = unaryFun!transform;
|
||||
alias T = typeof(transformFun(r.front));
|
||||
alias TB = typeof(transformFun(r.front));
|
||||
enum isBinary = false;
|
||||
}
|
||||
else static if (is(typeof(binaryFun!transform(r.front, 0))))
|
||||
{
|
||||
alias transformFun = binaryFun!transform;
|
||||
alias T = typeof(transformFun(r.front, 0));
|
||||
alias TB = typeof(transformFun(r.front, 0));
|
||||
enum isBinary = true;
|
||||
}
|
||||
else
|
||||
static assert(false, "unsupported `transform` alias");
|
||||
|
||||
// The `transform` function might return a qualified type, e.g. const(int).
|
||||
// Strip qualifiers if possible s.t. the temporary array is sortable.
|
||||
static if (is(TB : Unqual!TB))
|
||||
alias T = Unqual!TB;
|
||||
else
|
||||
static assert(false, "`transform` returns an unsortable qualified type: " ~ TB.stringof);
|
||||
|
||||
static trustedMalloc(size_t len) @trusted
|
||||
{
|
||||
import core.checkedint : mulu;
|
||||
|
@ -3246,6 +3253,35 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
|
|||
assert(arr.isSorted());
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=21183
|
||||
@safe unittest
|
||||
{
|
||||
static T get(T)(int) { return T.init; }
|
||||
|
||||
// There's no need to actually sort, just checking type interference
|
||||
if (false)
|
||||
{
|
||||
int[] arr;
|
||||
|
||||
// Fine because there are no indirections
|
||||
arr.schwartzSort!(get!(const int));
|
||||
|
||||
// Fine because it decays to immutable(int)*
|
||||
arr.schwartzSort!(get!(immutable int*));
|
||||
|
||||
// Disallowed because it would require a non-const reference
|
||||
static assert(!__traits(compiles, arr.schwartzSort!(get!(const Object))));
|
||||
|
||||
static struct Wrapper
|
||||
{
|
||||
int* ptr;
|
||||
}
|
||||
|
||||
// Disallowed because Wrapper.ptr would become mutable
|
||||
static assert(!__traits(compiles, arr.schwartzSort!(get!(const Wrapper))));
|
||||
}
|
||||
}
|
||||
|
||||
// partialSort
|
||||
/**
|
||||
Reorders the random-access range `r` such that the range `r[0 .. mid]`
|
||||
|
|
|
@ -9736,11 +9736,14 @@ public:
|
|||
assert([1].map!(x => x).slide(2).equal!equal([[1]]));
|
||||
}
|
||||
|
||||
private struct OnlyResult(T, size_t arity)
|
||||
private struct OnlyResult(Values...)
|
||||
if (Values.length > 1)
|
||||
{
|
||||
private this(Values...)(return scope auto ref Values values)
|
||||
private enum arity = Values.length;
|
||||
|
||||
private this(return scope ref Values values)
|
||||
{
|
||||
this.data = [values];
|
||||
this.values = values;
|
||||
this.backIndex = arity;
|
||||
}
|
||||
|
||||
|
@ -9749,10 +9752,10 @@ private struct OnlyResult(T, size_t arity)
|
|||
return frontIndex >= backIndex;
|
||||
}
|
||||
|
||||
T front() @property
|
||||
CommonType!Values front() @property
|
||||
{
|
||||
assert(!empty, "Attempting to fetch the front of an empty Only range");
|
||||
return data[frontIndex];
|
||||
return this[0];
|
||||
}
|
||||
|
||||
void popFront()
|
||||
|
@ -9761,10 +9764,10 @@ private struct OnlyResult(T, size_t arity)
|
|||
++frontIndex;
|
||||
}
|
||||
|
||||
T back() @property
|
||||
CommonType!Values back() @property
|
||||
{
|
||||
assert(!empty, "Attempting to fetch the back of an empty Only range");
|
||||
return data[backIndex - 1];
|
||||
return this[$ - 1];
|
||||
}
|
||||
|
||||
void popBack()
|
||||
|
@ -9785,12 +9788,15 @@ private struct OnlyResult(T, size_t arity)
|
|||
|
||||
alias opDollar = length;
|
||||
|
||||
T opIndex(size_t idx)
|
||||
CommonType!Values opIndex(size_t idx)
|
||||
{
|
||||
// when i + idx points to elements popped
|
||||
// with popBack
|
||||
assert(idx < length, "Attempting to fetch an out of bounds index from an Only range");
|
||||
return data[frontIndex + idx];
|
||||
final switch (frontIndex + idx)
|
||||
static foreach (i, T; Values)
|
||||
case i:
|
||||
return values[i];
|
||||
}
|
||||
|
||||
OnlyResult opSlice()
|
||||
|
@ -9822,16 +9828,16 @@ private struct OnlyResult(T, size_t arity)
|
|||
{
|
||||
import std.traits : hasElaborateAssign;
|
||||
static if (hasElaborateAssign!T)
|
||||
private T[arity] data;
|
||||
private Values values;
|
||||
else
|
||||
private T[arity] data = void;
|
||||
private Values values = void;
|
||||
}
|
||||
else
|
||||
private T[arity] data;
|
||||
private Values values;
|
||||
}
|
||||
|
||||
// Specialize for single-element results
|
||||
private struct OnlyResult(T, size_t arity : 1)
|
||||
private struct OnlyResult(T)
|
||||
{
|
||||
@property T front()
|
||||
{
|
||||
|
@ -9895,7 +9901,7 @@ private struct OnlyResult(T, size_t arity : 1)
|
|||
}
|
||||
|
||||
// Specialize for the empty range
|
||||
private struct OnlyResult(T, size_t arity : 0)
|
||||
private struct OnlyResult()
|
||||
{
|
||||
private static struct EmptyElementType {}
|
||||
|
||||
|
@ -9945,7 +9951,7 @@ See_Also: $(LREF chain) to chain ranges
|
|||
auto only(Values...)(return scope Values values)
|
||||
if (!is(CommonType!Values == void) || Values.length == 0)
|
||||
{
|
||||
return OnlyResult!(CommonType!Values, Values.length)(values);
|
||||
return OnlyResult!Values(values);
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -9969,17 +9975,6 @@ if (!is(CommonType!Values == void) || Values.length == 0)
|
|||
.equal("T.D.P.L"));
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
// Verify that the same common type and same arity
|
||||
// results in the same template instantiation
|
||||
static assert(is(typeof(only(byte.init, int.init)) ==
|
||||
typeof(only(int.init, byte.init))));
|
||||
|
||||
static assert(is(typeof(only((const(char)[]).init, string.init)) ==
|
||||
typeof(only((const(char)[]).init, (const(char)[]).init))));
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=20314
|
||||
@safe unittest
|
||||
{
|
||||
|
@ -10153,6 +10148,43 @@ if (!is(CommonType!Values == void) || Values.length == 0)
|
|||
cast(void) only(test, test); // Works with mutable indirection
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=21129
|
||||
@safe unittest
|
||||
{
|
||||
auto range = () @safe {
|
||||
const(char)[5] staticStr = "Hello";
|
||||
|
||||
// `only` must store a char[5] - not a char[]!
|
||||
return only(staticStr, " World");
|
||||
} ();
|
||||
|
||||
assert(range.join == "Hello World");
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=21129
|
||||
@safe unittest
|
||||
{
|
||||
struct AliasedString
|
||||
{
|
||||
const(char)[5] staticStr = "Hello";
|
||||
|
||||
@property const(char)[] slice() const
|
||||
{
|
||||
return staticStr[];
|
||||
}
|
||||
alias slice this;
|
||||
}
|
||||
|
||||
auto range = () @safe {
|
||||
auto hello = AliasedString();
|
||||
|
||||
// a copy of AliasedString is stored in the range.
|
||||
return only(hello, " World");
|
||||
} ();
|
||||
|
||||
assert(range.join == "Hello World");
|
||||
}
|
||||
|
||||
/**
|
||||
Iterate over `range` with an attached index variable.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue