Assigning RefCounted to RefCounted fails at compile time.

https://issues.caraus.io/issues/247
This commit is contained in:
Eugen Wissner 2017-06-24 02:28:17 +02:00
parent 7d5dda1cba
commit ede0107fd7
2 changed files with 34 additions and 19 deletions

View File

@ -1,3 +1,4 @@
ignore: ignore:
- "source/tanya/async/event/iocp.d" - "source/tanya/async/event/iocp.d"
- "source/tanya/async/iocp.d" - "source/tanya/async/iocp.d"
- "source/tanya/memory/types.d"

View File

@ -38,7 +38,7 @@ package final class RefCountedStore(T)
size_t counter = 1; size_t counter = 1;
size_t opUnary(string op)() size_t opUnary(string op)()
if (op == "--" || op == "++") if (op == "--" || op == "++")
in in
{ {
assert(counter > 0); assert(counter > 0);
@ -63,6 +63,15 @@ package final class RefCountedStore(T)
return 0; return 0;
} }
} }
private unittest
{
auto rcs = defaultAllocator.make!(RefCountedStore!int);
assert(rcs >= 1);
assert(rcs > 0);
assert(!(rcs > 2));
defaultAllocator.dispose(rcs);
}
} }
package void separateDeleter(T)(RefCountedStore!T storage, package void separateDeleter(T)(RefCountedStore!T storage,
@ -180,7 +189,7 @@ struct RefCounted(T)
* *
* Returns: $(D_KEYWORD this). * Returns: $(D_KEYWORD this).
*/ */
ref typeof(this) opAssign()(auto ref Payload!T rhs) ref typeof(this) opAssign(Payload!T rhs)
{ {
if (this.storage is null) if (this.storage is null)
{ {
@ -198,18 +207,18 @@ struct RefCounted(T)
finalize(this.storage.payload); finalize(this.storage.payload);
this.storage.payload = Payload!T.init; this.storage.payload = Payload!T.init;
} }
move(rhs, this.storage.payload); this.storage.payload = rhs;
return this; return this;
} }
private unittest private @nogc unittest
{ {
auto rc = defaultAllocator.refCounted!int(5); auto rc = defaultAllocator.refCounted!int(5);
rc = defaultAllocator.make!int(7); rc = defaultAllocator.make!int(7);
assert(*rc == 7); assert(*rc == 7);
} }
private unittest private @nogc unittest
{ {
auto rc = defaultAllocator.refCounted!int(5); auto rc = defaultAllocator.refCounted!int(5);
@ -289,12 +298,12 @@ struct RefCounted(T)
* Returns: Reference to the pointed value. * Returns: Reference to the pointed value.
*/ */
ref inout(T) opUnary(string op)() inout ref inout(T) opUnary(string op)() inout
if (op == "*"); if (op == "*");
} }
else static if (isPointer!(Payload!T)) else static if (isPointer!(Payload!T))
{ {
ref inout(T) opUnary(string op)() inout ref inout(T) opUnary(string op)() inout
if (op == "*") if (op == "*")
{ {
return *this.storage.payload; return *this.storage.payload;
} }
@ -340,6 +349,12 @@ unittest
assert(*rc.storage.payload == 9); assert(*rc.storage.payload == 9);
} }
private unittest
{
RefCounted!int rc1, rc2;
static assert(is(typeof(rc1 = rc2)));
}
version (unittest) version (unittest)
{ {
private class A private class A
@ -468,8 +483,8 @@ private unittest
* Precondition: $(D_INLINECODE allocator !is null) * Precondition: $(D_INLINECODE allocator !is null)
*/ */
RefCounted!T refCounted(T, A...)(shared Allocator allocator, auto ref A args) RefCounted!T refCounted(T, A...)(shared Allocator allocator, auto ref A args)
if (!is(T == interface) && !isAbstractClass!T if (!is(T == interface) && !isAbstractClass!T
&& !isAssociativeArray!T && !isArray!T) && !isAssociativeArray!T && !isArray!T)
in in
{ {
assert(allocator !is null); assert(allocator !is null);
@ -521,7 +536,7 @@ body
*/ */
RefCounted!T refCounted(T)(shared Allocator allocator, const size_t size) RefCounted!T refCounted(T)(shared Allocator allocator, const size_t size)
@trusted @trusted
if (isArray!T) if (isArray!T)
in in
{ {
assert(allocator !is null); assert(allocator !is null);
@ -690,11 +705,10 @@ struct Unique(T)
* *
* Returns: $(D_KEYWORD this). * Returns: $(D_KEYWORD this).
*/ */
ref typeof(this) opAssign()(auto ref Payload!T rhs) ref typeof(this) opAssign(Payload!T rhs)
{ {
allocator.dispose(this.payload); allocator.dispose(this.payload);
move(rhs, this.payload); this.payload = rhs;
return this; return this;
} }
@ -734,12 +748,12 @@ struct Unique(T)
* Returns: Reference to the pointed value. * Returns: Reference to the pointed value.
*/ */
ref inout(T) opUnary(string op)() inout ref inout(T) opUnary(string op)() inout
if (op == "*"); if (op == "*");
} }
else static if (isPointer!(Payload!T)) else static if (isPointer!(Payload!T))
{ {
ref inout(T) opUnary(string op)() inout ref inout(T) opUnary(string op)() inout
if (op == "*") if (op == "*")
{ {
return *this.payload; return *this.payload;
} }
@ -761,7 +775,7 @@ struct Unique(T)
} }
/** /**
* Resets this $(D_PARAM Unique) to its initial state. * Sets the internal pointer to $(D_KEYWORD). The allocator isn't changed.
* *
* Returns: Reference to the owned object. * Returns: Reference to the owned object.
*/ */
@ -830,8 +844,8 @@ struct Unique(T)
* Precondition: $(D_INLINECODE allocator !is null) * Precondition: $(D_INLINECODE allocator !is null)
*/ */
Unique!T unique(T, A...)(shared Allocator allocator, auto ref A args) Unique!T unique(T, A...)(shared Allocator allocator, auto ref A args)
if (!is(T == interface) && !isAbstractClass!T if (!is(T == interface) && !isAbstractClass!T
&& !isAssociativeArray!T && !isArray!T) && !isAssociativeArray!T && !isArray!T)
in in
{ {
assert(allocator !is null); assert(allocator !is null);
@ -858,7 +872,7 @@ body
*/ */
Unique!T unique(T)(shared Allocator allocator, const size_t size) Unique!T unique(T)(shared Allocator allocator, const size_t size)
@trusted @trusted
if (isArray!T) if (isArray!T)
in in
{ {
assert(allocator !is null); assert(allocator !is null);