mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 14:40:30 +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)
|
||||
*/
|
||||
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)
|
||||
{
|
||||
|
@ -2044,34 +2044,65 @@ void swap(T)(ref T lhs, ref T rhs) if (is(typeof(lhs.proxySwap(rhs))))
|
|||
lhs.proxySwap(rhs);
|
||||
}
|
||||
|
||||
/+
|
||||
Trait like isMutable. It also verifies that the fields inside a value
|
||||
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)
|
||||
// Equivalent with TypeStruct::isAssinable in compiler code.
|
||||
private template isBlitAssignable(T) if (!is(T == struct))
|
||||
{
|
||||
alias OT = OriginalType!T;
|
||||
static if (is(OT == struct) || is(OT == union))
|
||||
enum allMutableFields = isMutable!OT && allSatisfy!(.allMutableFields, FieldTypeTuple!OT);
|
||||
static if (is(T == U[n], U, size_t n))
|
||||
enum isBlitAssignable = isBlitAssignable!U;
|
||||
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
|
||||
{
|
||||
static assert( allMutableFields!int);
|
||||
static assert(!allMutableFields!(const int));
|
||||
static assert( isBlitAssignable!int);
|
||||
static assert(!isBlitAssignable!(const int));
|
||||
|
||||
class C{const int i;}
|
||||
static assert( allMutableFields!C);
|
||||
class C{ const int i; }
|
||||
static assert( isBlitAssignable!C);
|
||||
|
||||
struct S1{int i;}
|
||||
struct S2{const int i;}
|
||||
static assert( allMutableFields!S1);
|
||||
static assert(!allMutableFields!S2);
|
||||
struct S1{ int i; }
|
||||
struct S2{ const int i; }
|
||||
static assert( isBlitAssignable!S1);
|
||||
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
|
||||
|
@ -2175,6 +2206,14 @@ unittest
|
|||
static assert(isAssignable!T);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
// 12024
|
||||
import std.datetime;
|
||||
SysTime a, b;
|
||||
swap(a, b);
|
||||
}
|
||||
|
||||
void swapFront(R1, R2)(R1 r1, R2 r2)
|
||||
if (isInputRange!R1 && isInputRange!R2)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue