mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 06:30:28 +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 > b` == 10);
|
||||||
assert(d.extremum!(a => a, `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
|
@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)
|
if (!is(T == class) && !is(T == interface) && !isDynamicArray!T && !isAssociativeArray!T)
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
align(T.alignof)
|
static if (isAssignable!(typeof(cast() T.init)))
|
||||||
static struct Payload
|
|
||||||
{
|
{
|
||||||
static if (hasIndirections!T)
|
enum useQualifierCast = true;
|
||||||
{
|
|
||||||
void[T.sizeof] data;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ubyte[T.sizeof] data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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:
|
public:
|
||||||
|
|
||||||
|
@ -2427,7 +2438,14 @@ public:
|
||||||
*/
|
*/
|
||||||
this(T value) @trusted
|
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
|
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)
|
void set(this This)(T value)
|
||||||
{
|
{
|
||||||
// As we're escaping a copy of `value`, deliberately leak a copy:
|
static if (useQualifierCast)
|
||||||
static union DontCallDestructor
|
|
||||||
{
|
{
|
||||||
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)()
|
void clear(this This)()
|
||||||
|
@ -2713,6 +2748,32 @@ private:
|
||||||
assert(post == del - 1);
|
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
|
Convenience function for creating a `Rebindable` using automatic type
|
||||||
inference.
|
inference.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue