mirror of
https://github.com/dlang/phobos.git
synced 2025-05-07 19:49:36 +03:00
Merge remote-tracking branch 'upstream/stable' into merge_stable
This commit is contained in:
commit
1f49f65c51
5 changed files with 96 additions and 78 deletions
102
std/typecons.d
102
std/typecons.d
|
@ -3159,12 +3159,6 @@ struct Nullable(T)
|
|||
return this;
|
||||
}
|
||||
|
||||
/// ditto
|
||||
inout(typeof(this)) opIndex() inout
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/// ditto
|
||||
inout(typeof(this)) opIndex(size_t[2] dim) inout
|
||||
in (dim[0] <= length && dim[1] <= length && dim[1] >= dim[0])
|
||||
|
@ -3192,6 +3186,74 @@ struct Nullable(T)
|
|||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts `Nullable` to a range. Works even when the contained type is `immutable`.
|
||||
*/
|
||||
auto opSlice(this This)()
|
||||
{
|
||||
static struct NullableRange
|
||||
{
|
||||
private This value;
|
||||
|
||||
// starts out true if value is null
|
||||
private bool empty_;
|
||||
|
||||
@property bool empty() const @safe pure nothrow
|
||||
{
|
||||
return empty_;
|
||||
}
|
||||
|
||||
void popFront() @safe pure nothrow
|
||||
{
|
||||
empty_ = true;
|
||||
}
|
||||
|
||||
alias popBack = popFront;
|
||||
|
||||
@property ref inout(typeof(value.get())) front() inout @safe pure nothrow
|
||||
{
|
||||
return value.get();
|
||||
}
|
||||
|
||||
alias back = front;
|
||||
|
||||
@property inout(typeof(this)) save() inout
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
size_t[2] opSlice(size_t dim : 0)(size_t from, size_t to) const
|
||||
{
|
||||
return [from, to];
|
||||
}
|
||||
|
||||
@property size_t length() const @safe pure nothrow
|
||||
{
|
||||
return !empty;
|
||||
}
|
||||
|
||||
alias opDollar(size_t dim : 0) = length;
|
||||
|
||||
ref inout(typeof(value.get())) opIndex(size_t index) inout @safe pure nothrow
|
||||
in (index < length)
|
||||
{
|
||||
return value.get();
|
||||
}
|
||||
|
||||
inout(typeof(this)) opIndex(size_t[2] dim) inout
|
||||
in (dim[0] <= length && dim[1] <= length && dim[1] >= dim[0])
|
||||
{
|
||||
return (dim[0] == 0 && dim[1] == 1) ? this : this.init;
|
||||
}
|
||||
|
||||
auto opIndex() inout
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return NullableRange(this, isNull);
|
||||
}
|
||||
}
|
||||
|
||||
/// ditto
|
||||
|
@ -3774,6 +3836,34 @@ auto nullable(T)(T t)
|
|||
assert(hasLvalueElements!(Nullable!int));
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23640
|
||||
@safe pure nothrow unittest
|
||||
{
|
||||
import std.algorithm.comparison : equal;
|
||||
import std.range : only;
|
||||
import std.range.primitives : hasLength, hasSlicing,
|
||||
isRandomAccessRange;
|
||||
static immutable struct S { int[] array; }
|
||||
auto value = S([42]);
|
||||
alias ImmutableNullable = immutable Nullable!S;
|
||||
auto a = ImmutableNullable(value)[];
|
||||
alias Range = typeof(a);
|
||||
assert(isRandomAccessRange!Range);
|
||||
assert(hasLength!Range);
|
||||
assert(hasSlicing!Range);
|
||||
assert(!a.empty);
|
||||
assert(a.front == value);
|
||||
assert(a.back == value);
|
||||
assert(a[0] == value);
|
||||
assert(a.equal(only(value)));
|
||||
assert(a[0 .. $].equal(only(value)));
|
||||
Range b = a.save();
|
||||
assert(!b.empty);
|
||||
b.popFront();
|
||||
assert(!a.empty);
|
||||
assert(b.empty);
|
||||
}
|
||||
|
||||
/**
|
||||
Just like `Nullable!T`, except that the null state is defined as a
|
||||
particular value. For example, $(D Nullable!(uint, uint.max)) is an
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue