mirror of
https://github.com/dlang/phobos.git
synced 2025-04-30 15:10:46 +03:00
fix Issue 12024 - template instantiation for swap(SysTime, SysTime) fails
This commit is contained in:
parent
71f9550eac
commit
2d32c78af4
1 changed files with 60 additions and 21 deletions
|
@ -1995,7 +1995,7 @@ See_Also:
|
||||||
$(XREF exception, pointsTo)
|
$(XREF exception, pointsTo)
|
||||||
*/
|
*/
|
||||||
void swap(T)(ref T lhs, ref T rhs) @trusted pure nothrow
|
void swap(T)(ref T lhs, ref T rhs) @trusted pure nothrow
|
||||||
if (allMutableFields!T && !is(typeof(lhs.proxySwap(rhs))))
|
if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs))))
|
||||||
{
|
{
|
||||||
static if (hasElaborateAssign!T || !isAssignable!T)
|
static if (hasElaborateAssign!T || !isAssignable!T)
|
||||||
{
|
{
|
||||||
|
@ -2044,34 +2044,65 @@ void swap(T)(ref T lhs, ref T rhs) if (is(typeof(lhs.proxySwap(rhs))))
|
||||||
lhs.proxySwap(rhs);
|
lhs.proxySwap(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/+
|
// Equivalent with TypeStruct::isAssinable in compiler code.
|
||||||
Trait like isMutable. It also verifies that the fields inside a value
|
private template isBlitAssignable(T) if (!is(T == struct))
|
||||||
type aggregate are also mutable.
|
|
||||||
|
|
||||||
A "value type aggregate" is a struct or an union, but not a class nor
|
|
||||||
an interface.
|
|
||||||
+/
|
|
||||||
private template allMutableFields(T)
|
|
||||||
{
|
{
|
||||||
alias OT = OriginalType!T;
|
static if (is(T == U[n], U, size_t n))
|
||||||
static if (is(OT == struct) || is(OT == union))
|
enum isBlitAssignable = isBlitAssignable!U;
|
||||||
enum allMutableFields = isMutable!OT && allSatisfy!(.allMutableFields, FieldTypeTuple!OT);
|
|
||||||
else
|
else
|
||||||
enum allMutableFields = isMutable!OT;
|
enum isBlitAssignable = isMutable!T;
|
||||||
|
}
|
||||||
|
private template isBlitAssignable(T) if (is(T == struct))
|
||||||
|
{
|
||||||
|
enum isBlitAssignable =
|
||||||
|
isMutable!T &&
|
||||||
|
{
|
||||||
|
size_t offset = 0;
|
||||||
|
bool assignable = true;
|
||||||
|
foreach (i, F; FieldTypeTuple!T)
|
||||||
|
{
|
||||||
|
static if (i == 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (T.tupleof[i].offsetof == offset)
|
||||||
|
{
|
||||||
|
if (assignable)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!assignable)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
assignable = isBlitAssignable!(typeof(T.tupleof[i]));
|
||||||
|
offset = T.tupleof[i].offsetof;
|
||||||
|
}
|
||||||
|
return assignable;
|
||||||
|
}();
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
static assert( allMutableFields!int);
|
static assert( isBlitAssignable!int);
|
||||||
static assert(!allMutableFields!(const int));
|
static assert(!isBlitAssignable!(const int));
|
||||||
|
|
||||||
class C{ const int i; }
|
class C{ const int i; }
|
||||||
static assert( allMutableFields!C);
|
static assert( isBlitAssignable!C);
|
||||||
|
|
||||||
struct S1{ int i; }
|
struct S1{ int i; }
|
||||||
struct S2{ const int i; }
|
struct S2{ const int i; }
|
||||||
static assert( allMutableFields!S1);
|
static assert( isBlitAssignable!S1);
|
||||||
static assert(!allMutableFields!S2);
|
static assert(!isBlitAssignable!S2);
|
||||||
|
|
||||||
|
struct S3X { union { int x; int y; } }
|
||||||
|
struct S3Y { union { int x; const int y; } }
|
||||||
|
struct S3Z { union { const int x; const int y; } }
|
||||||
|
static assert( isBlitAssignable!(S3X));
|
||||||
|
static assert( isBlitAssignable!(S3Y));
|
||||||
|
static assert(!isBlitAssignable!(S3Z));
|
||||||
|
static assert( isBlitAssignable!(S3X[3]));
|
||||||
|
static assert( isBlitAssignable!(S3Y[3]));
|
||||||
|
static assert(!isBlitAssignable!(S3Z[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
|
@ -2175,6 +2206,14 @@ unittest
|
||||||
static assert(isAssignable!T);
|
static assert(isAssignable!T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
// 12024
|
||||||
|
import std.datetime;
|
||||||
|
SysTime a, b;
|
||||||
|
swap(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
void swapFront(R1, R2)(R1 r1, R2 r2)
|
void swapFront(R1, R2)(R1 r1, R2 r2)
|
||||||
if (isInputRange!R1 && isInputRange!R2)
|
if (isInputRange!R1 && isInputRange!R2)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue