mirror of
https://github.com/dlang/phobos.git
synced 2025-04-28 22:21:09 +03:00
Change struct Rebindable to just use cast()
if this is sufficient.
This works better at compiletime.
This commit is contained in:
parent
b818901e63
commit
2f6b2efaf7
2 changed files with 86 additions and 21 deletions
|
@ -1498,6 +1498,10 @@ if (isInputRange!Range && !isInfinite!Range &&
|
|||
assert(d.extremum!`a > b` == 10);
|
||||
assert(d.extremum!(a => a, `a > b`) == 10);
|
||||
}
|
||||
|
||||
// compiletime
|
||||
enum ctExtremum = iota(1, 5).extremum;
|
||||
assert(ctExtremum == 1);
|
||||
}
|
||||
|
||||
@nogc @safe nothrow pure unittest
|
||||
|
|
103
std/typecons.d
103
std/typecons.d
|
@ -2400,20 +2400,31 @@ struct Rebindable(T)
|
|||
if (!is(T == class) && !is(T == interface) && !isDynamicArray!T && !isAssociativeArray!T)
|
||||
{
|
||||
private:
|
||||
align(T.alignof)
|
||||
static struct Payload
|
||||
static if (isAssignable!(typeof(cast() T.init)))
|
||||
{
|
||||
static if (hasIndirections!T)
|
||||
{
|
||||
void[T.sizeof] data;
|
||||
}
|
||||
else
|
||||
{
|
||||
ubyte[T.sizeof] data;
|
||||
}
|
||||
}
|
||||
enum useQualifierCast = true;
|
||||
|
||||
Payload data;
|
||||
typeof(cast() T.init) data;
|
||||
}
|
||||
else
|
||||
{
|
||||
enum useQualifierCast = false;
|
||||
|
||||
align(T.alignof)
|
||||
static struct Payload
|
||||
{
|
||||
static if (hasIndirections!T)
|
||||
{
|
||||
void[T.sizeof] data;
|
||||
}
|
||||
else
|
||||
{
|
||||
ubyte[T.sizeof] data;
|
||||
}
|
||||
}
|
||||
|
||||
Payload data;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
@ -2427,7 +2438,14 @@ public:
|
|||
*/
|
||||
this(T value) @trusted
|
||||
{
|
||||
set(value);
|
||||
static if (useQualifierCast)
|
||||
{
|
||||
this.data = cast() value;
|
||||
}
|
||||
else
|
||||
{
|
||||
set(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2444,12 +2462,22 @@ public:
|
|||
*/
|
||||
T get(this This)() @property @trusted
|
||||
{
|
||||
return *cast(T*) &this.data;
|
||||
static if (useQualifierCast)
|
||||
{
|
||||
return cast(T) this.data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return *cast(T*) &this.data;
|
||||
}
|
||||
}
|
||||
|
||||
~this() @trusted
|
||||
static if (!useQualifierCast)
|
||||
{
|
||||
clear;
|
||||
~this() @trusted
|
||||
{
|
||||
clear;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -2459,13 +2487,20 @@ private:
|
|||
|
||||
void set(this This)(T value)
|
||||
{
|
||||
// As we're escaping a copy of `value`, deliberately leak a copy:
|
||||
static union DontCallDestructor
|
||||
static if (useQualifierCast)
|
||||
{
|
||||
T value;
|
||||
this.data = cast() value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// As we're escaping a copy of `value`, deliberately leak a copy:
|
||||
static union DontCallDestructor
|
||||
{
|
||||
T value;
|
||||
}
|
||||
DontCallDestructor copy = DontCallDestructor(value);
|
||||
this.data = *cast(Payload*) ©
|
||||
}
|
||||
DontCallDestructor copy = DontCallDestructor(value);
|
||||
this.data = *cast(Payload*) ©
|
||||
}
|
||||
|
||||
void clear(this This)()
|
||||
|
@ -2713,6 +2748,32 @@ private:
|
|||
assert(post == del - 1);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
int del;
|
||||
int post;
|
||||
struct S
|
||||
{
|
||||
immutable int x;
|
||||
int level;
|
||||
this(this)
|
||||
{
|
||||
post++;
|
||||
level++;
|
||||
}
|
||||
~this()
|
||||
{
|
||||
del++;
|
||||
}
|
||||
}
|
||||
|
||||
// test ref count
|
||||
{
|
||||
Rebindable!S rc = S(0);
|
||||
}
|
||||
assert(post == del - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
Convenience function for creating a `Rebindable` using automatic type
|
||||
inference.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue