summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2017-03-19 06:54:59 +0100
committerEugen Wissner <belka@caraus.de>2017-03-19 06:54:59 +0100
commit85380ac3fc700817562042b659f8dfa4774e96cf (patch)
tree8ef40db661a37c38ff508f5ca1ab0640d1dbc2ee /source
parentb90c56395cb8a3c4cabde4acc7654dd9ceffc87e (diff)
downloadtanya-85380ac3fc700817562042b659f8dfa4774e96cf.tar.gz
Remove makeArray import
Diffstat (limited to 'source')
-rw-r--r--source/tanya/memory/allocator.d90
-rw-r--r--source/tanya/memory/package.d2
-rw-r--r--source/tanya/memory/types.d766
3 files changed, 429 insertions, 429 deletions
diff --git a/source/tanya/memory/allocator.d b/source/tanya/memory/allocator.d
index c942568..560d9a1 100644
--- a/source/tanya/memory/allocator.d
+++ b/source/tanya/memory/allocator.d
@@ -15,53 +15,53 @@ module tanya.memory.allocator;
*/
interface Allocator
{
- /**
- * Returns: Alignment offered.
- */
- @property uint alignment() const shared pure nothrow @safe @nogc;
+ /**
+ * Returns: Alignment offered.
+ */
+ @property uint alignment() const shared pure nothrow @safe @nogc;
- /**
- * Allocates $(D_PARAM size) bytes of memory.
- *
- * Params:
- * size = Amount of memory to allocate.
- *
- * Returns: Pointer to the new allocated memory.
- */
- void[] allocate(in size_t size) shared nothrow @nogc;
+ /**
+ * Allocates $(D_PARAM size) bytes of memory.
+ *
+ * Params:
+ * size = Amount of memory to allocate.
+ *
+ * Returns: Pointer to the new allocated memory.
+ */
+ void[] allocate(in size_t size) shared nothrow @nogc;
- /**
- * Deallocates a memory block.
- *
- * Params:
- * p = A pointer to the memory block to be freed.
- *
- * Returns: Whether the deallocation was successful.
- */
- bool deallocate(void[] p) shared nothrow @nogc;
+ /**
+ * Deallocates a memory block.
+ *
+ * Params:
+ * p = A pointer to the memory block to be freed.
+ *
+ * Returns: Whether the deallocation was successful.
+ */
+ bool deallocate(void[] p) shared nothrow @nogc;
- /**
- * Increases or decreases the size of a memory block.
- *
- * Params:
- * p = A pointer to the memory block.
- * size = Size of the reallocated block.
- *
- * Returns: Pointer to the allocated memory.
- */
- bool reallocate(ref void[] p, in size_t size) shared nothrow @nogc;
+ /**
+ * Increases or decreases the size of a memory block.
+ *
+ * Params:
+ * p = A pointer to the memory block.
+ * size = Size of the reallocated block.
+ *
+ * Returns: Pointer to the allocated memory.
+ */
+ bool reallocate(ref void[] p, in size_t size) shared nothrow @nogc;
- /**
- * Reallocates a memory block in place if possible or returns
- * $(D_KEYWORD false). This function cannot be used to allocate or
- * deallocate memory, so if $(D_PARAM p) is $(D_KEYWORD null) or
- * $(D_PARAM size) is `0`, it should return $(D_KEYWORD false).
- *
- * Params:
- * p = A pointer to the memory block.
- * size = Size of the reallocated block.
- *
- * Returns: $(D_KEYWORD true) if successful, $(D_KEYWORD false) otherwise.
- */
- bool reallocateInPlace(ref void[] p, in size_t size) shared nothrow @nogc;
+ /**
+ * Reallocates a memory block in place if possible or returns
+ * $(D_KEYWORD false). This function cannot be used to allocate or
+ * deallocate memory, so if $(D_PARAM p) is $(D_KEYWORD null) or
+ * $(D_PARAM size) is `0`, it should return $(D_KEYWORD false).
+ *
+ * Params:
+ * p = A pointer to the memory block.
+ * size = Size of the reallocated block.
+ *
+ * Returns: $(D_KEYWORD true) if successful, $(D_KEYWORD false) otherwise.
+ */
+ bool reallocateInPlace(ref void[] p, in size_t size) shared nothrow @nogc;
}
diff --git a/source/tanya/memory/package.d b/source/tanya/memory/package.d
index da53ecf..1959dbd 100644
--- a/source/tanya/memory/package.d
+++ b/source/tanya/memory/package.d
@@ -11,7 +11,7 @@
module tanya.memory;
import core.exception;
-public import std.experimental.allocator : make, makeArray;
+public import std.experimental.allocator : make;
import std.traits;
public import tanya.memory.allocator;
diff --git a/source/tanya/memory/types.d b/source/tanya/memory/types.d
index be9c8cd..1207d73 100644
--- a/source/tanya/memory/types.d
+++ b/source/tanya/memory/types.d
@@ -3,10 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
- * Copyright: Eugene Wissner 2016.
+ * Copyright: Eugene Wissner 2016-2017.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
- * Authors: $(LINK2 mailto:belka@caraus.de, Eugene Wissner)
+ * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
*/
module tanya.memory.types;
@@ -23,345 +23,345 @@ import tanya.memory;
* when the reference count goes down to zero, frees the underlying store.
*
* Params:
- * T = Type of the reference-counted value.
+ * T = Type of the reference-counted value.
*/
struct RefCounted(T)
{
- static if (is(T == class) || is(T == interface))
- {
- private alias Payload = T;
- }
- else
- {
- private alias Payload = T*;
- }
-
- private class Storage
- {
- private Payload payload;
- private size_t counter = 1;
-
- private final size_t opUnary(string op)() pure nothrow @safe @nogc
- if (op == "--" || op == "++")
- in
- {
- assert(counter > 0);
- }
- body
- {
- mixin("return " ~ op ~ "counter;");
- }
-
- private final int opCmp(size_t counter) const pure nothrow @safe @nogc
- {
- if (this.counter > counter)
- {
- return 1;
- }
- else if (this.counter < counter)
- {
- return -1;
- }
- else
- {
- return 0;
- }
- }
-
- private final int opEquals(size_t counter) const pure nothrow @safe @nogc
- {
- return this.counter == counter;
- }
- }
-
- private final class RefCountedStorage : Storage
- {
- private shared Allocator allocator;
-
- this(shared Allocator allocator) pure nothrow @safe @nogc
- in
- {
- assert(allocator !is null);
- }
- body
- {
- this.allocator = allocator;
- }
-
- ~this() nothrow @nogc
- {
- allocator.dispose(payload);
- }
- }
-
- private Storage storage;
-
- invariant
- {
- assert(storage is null || allocator_ !is null);
- }
-
- /**
- * Takes ownership over $(D_PARAM value), setting the counter to 1.
- * $(D_PARAM value) may be a pointer, an object or a dynamic array.
- *
- * Params:
- * value = Value whose ownership is taken over.
- * allocator = Allocator used to destroy the $(D_PARAM value) and to
- * allocate/deallocate internal storage.
- *
- * Precondition: $(D_INLINECODE allocator !is null)
- */
- this(Payload value, shared Allocator allocator = defaultAllocator)
- {
- this(allocator);
- storage = allocator.make!RefCountedStorage(allocator);
- move(value, storage.payload);
- }
-
- /// Ditto.
- this(shared Allocator allocator)
- in
- {
- assert(allocator !is null);
- }
- body
- {
- this.allocator_ = allocator;
- }
-
- /**
- * Increases the reference counter by one.
- */
- this(this)
- {
- if (count != 0)
- {
- ++storage;
- }
- }
-
- /**
- * Decreases the reference counter by one.
- *
- * If the counter reaches 0, destroys the owned object.
- */
- ~this()
- {
- if (storage !is null && !(storage.counter && --storage))
- {
- allocator_.dispose(storage);
- }
- }
-
- /**
- * Takes ownership over $(D_PARAM rhs). Initializes this
- * $(D_PSYMBOL RefCounted) if needed.
- *
- * If it is the last reference of the previously owned object,
- * it will be destroyed.
- *
- * To reset the $(D_PSYMBOL RefCounted) assign $(D_KEYWORD null).
- *
- * If the allocator wasn't set before, $(D_PSYMBOL defaultAllocator) will
- * be used. If you need a different allocator, create a new
- * $(D_PSYMBOL RefCounted) and assign it.
- *
- * Params:
- * rhs = $(D_KEYWORD this).
- */
- ref typeof(this) opAssign(Payload rhs)
- {
- if (storage is null)
- {
- storage = allocator.make!RefCountedStorage(allocator);
- }
- else if (storage > 1)
- {
- --storage;
- storage = allocator.make!RefCountedStorage(allocator);
- }
- else if (cast(RefCountedStorage) storage is null)
- {
- // Created with refCounted. Always destroyed togethter with the pointer.
- assert(storage.counter != 0);
- allocator.dispose(storage);
- storage = allocator.make!RefCountedStorage(allocator);
- }
- else
- {
- allocator.dispose(storage.payload);
- }
- move(rhs, storage.payload);
- return this;
- }
-
- /// Ditto.
- ref typeof(this) opAssign(typeof(null))
- {
- if (storage is null)
- {
- return this;
- }
- else if (storage > 1)
- {
- --storage;
- storage = null;
- }
- else if (cast(RefCountedStorage) storage is null)
- {
- // Created with refCounted. Always destroyed togethter with the pointer.
- assert(storage.counter != 0);
- allocator.dispose(storage);
- return this;
- }
- else
- {
- allocator.dispose(storage.payload);
- }
- return this;
- }
-
- /// Ditto.
- ref typeof(this) opAssign(typeof(this) rhs)
- {
- swap(allocator_, rhs.allocator_);
- swap(storage, rhs.storage);
- return this;
- }
-
- /**
- * Returns: Reference to the owned object.
- */
- inout(Payload) get() inout pure nothrow @safe @nogc
- in
- {
- assert(count > 0, "Attempted to access an uninitialized reference.");
- }
- body
- {
- return storage.payload;
- }
-
- static if (isPointer!Payload)
- {
- /**
- * Params:
- * op = Operation.
- *
- * Dereferences the pointer. It is defined only for pointers, not for
- * reference types like classes, that can be accessed directly.
- *
- * Returns: Reference to the pointed value.
- */
- ref T opUnary(string op)()
- if (op == "*")
- {
- return *storage.payload;
- }
- }
-
- /**
- * Returns: Whether this $(D_PSYMBOL RefCounted) already has an internal
- * storage.
- */
- @property bool isInitialized() const
- {
- return storage !is null;
- }
-
- /**
- * Returns: The number of $(D_PSYMBOL RefCounted) instances that share
- * ownership over the same pointer (including $(D_KEYWORD this)).
- * If this $(D_PSYMBOL RefCounted) isn't initialized, returns `0`.
- */
- @property size_t count() const
- {
- return storage is null ? 0 : storage.counter;
- }
-
- mixin DefaultAllocator;
- alias get this;
+ static if (is(T == class) || is(T == interface))
+ {
+ private alias Payload = T;
+ }
+ else
+ {
+ private alias Payload = T*;
+ }
+
+ private class Storage
+ {
+ private Payload payload;
+ private size_t counter = 1;
+
+ private final size_t opUnary(string op)() pure nothrow @safe @nogc
+ if (op == "--" || op == "++")
+ in
+ {
+ assert(counter > 0);
+ }
+ body
+ {
+ mixin("return " ~ op ~ "counter;");
+ }
+
+ private final int opCmp(size_t counter) const pure nothrow @safe @nogc
+ {
+ if (this.counter > counter)
+ {
+ return 1;
+ }
+ else if (this.counter < counter)
+ {
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ private final int opEquals(size_t counter) const pure nothrow @safe @nogc
+ {
+ return this.counter == counter;
+ }
+ }
+
+ private final class RefCountedStorage : Storage
+ {
+ private shared Allocator allocator;
+
+ this(shared Allocator allocator) pure nothrow @safe @nogc
+ in
+ {
+ assert(allocator !is null);
+ }
+ body
+ {
+ this.allocator = allocator;
+ }
+
+ ~this() nothrow @nogc
+ {
+ allocator.dispose(payload);
+ }
+ }
+
+ private Storage storage;
+
+ invariant
+ {
+ assert(storage is null || allocator_ !is null);
+ }
+
+ /**
+ * Takes ownership over $(D_PARAM value), setting the counter to 1.
+ * $(D_PARAM value) may be a pointer, an object or a dynamic array.
+ *
+ * Params:
+ * value = Value whose ownership is taken over.
+ * allocator = Allocator used to destroy the $(D_PARAM value) and to
+ * allocate/deallocate internal storage.
+ *
+ * Precondition: $(D_INLINECODE allocator !is null)
+ */
+ this(Payload value, shared Allocator allocator = defaultAllocator)
+ {
+ this(allocator);
+ storage = allocator.make!RefCountedStorage(allocator);
+ move(value, storage.payload);
+ }
+
+ /// Ditto.
+ this(shared Allocator allocator)
+ in
+ {
+ assert(allocator !is null);
+ }
+ body
+ {
+ this.allocator_ = allocator;
+ }
+
+ /**
+ * Increases the reference counter by one.
+ */
+ this(this)
+ {
+ if (count != 0)
+ {
+ ++storage;
+ }
+ }
+
+ /**
+ * Decreases the reference counter by one.
+ *
+ * If the counter reaches 0, destroys the owned object.
+ */
+ ~this()
+ {
+ if (storage !is null && !(storage.counter && --storage))
+ {
+ allocator_.dispose(storage);
+ }
+ }
+
+ /**
+ * Takes ownership over $(D_PARAM rhs). Initializes this
+ * $(D_PSYMBOL RefCounted) if needed.
+ *
+ * If it is the last reference of the previously owned object,
+ * it will be destroyed.
+ *
+ * To reset the $(D_PSYMBOL RefCounted) assign $(D_KEYWORD null).
+ *
+ * If the allocator wasn't set before, $(D_PSYMBOL defaultAllocator) will
+ * be used. If you need a different allocator, create a new
+ * $(D_PSYMBOL RefCounted) and assign it.
+ *
+ * Params:
+ * rhs = $(D_KEYWORD this).
+ */
+ ref typeof(this) opAssign(Payload rhs)
+ {
+ if (storage is null)
+ {
+ storage = allocator.make!RefCountedStorage(allocator);
+ }
+ else if (storage > 1)
+ {
+ --storage;
+ storage = allocator.make!RefCountedStorage(allocator);
+ }
+ else if (cast(RefCountedStorage) storage is null)
+ {
+ // Created with refCounted. Always destroyed togethter with the pointer.
+ assert(storage.counter != 0);
+ allocator.dispose(storage);
+ storage = allocator.make!RefCountedStorage(allocator);
+ }
+ else
+ {
+ allocator.dispose(storage.payload);
+ }
+ move(rhs, storage.payload);
+ return this;
+ }
+
+ /// Ditto.
+ ref typeof(this) opAssign(typeof(null))
+ {
+ if (storage is null)
+ {
+ return this;
+ }
+ else if (storage > 1)
+ {
+ --storage;
+ storage = null;
+ }
+ else if (cast(RefCountedStorage) storage is null)
+ {
+ // Created with refCounted. Always destroyed togethter with the pointer.
+ assert(storage.counter != 0);
+ allocator.dispose(storage);
+ return this;
+ }
+ else
+ {
+ allocator.dispose(storage.payload);
+ }
+ return this;
+ }
+
+ /// Ditto.
+ ref typeof(this) opAssign(typeof(this) rhs)
+ {
+ swap(allocator_, rhs.allocator_);
+ swap(storage, rhs.storage);
+ return this;
+ }
+
+ /**
+ * Returns: Reference to the owned object.
+ */
+ inout(Payload) get() inout pure nothrow @safe @nogc
+ in
+ {
+ assert(count > 0, "Attempted to access an uninitialized reference.");
+ }
+ body
+ {
+ return storage.payload;
+ }
+
+ static if (isPointer!Payload)
+ {
+ /**
+ * Params:
+ * op = Operation.
+ *
+ * Dereferences the pointer. It is defined only for pointers, not for
+ * reference types like classes, that can be accessed directly.
+ *
+ * Returns: Reference to the pointed value.
+ */
+ ref T opUnary(string op)()
+ if (op == "*")
+ {
+ return *storage.payload;
+ }
+ }
+
+ /**
+ * Returns: Whether this $(D_PSYMBOL RefCounted) already has an internal
+ * storage.
+ */
+ @property bool isInitialized() const
+ {
+ return storage !is null;
+ }
+
+ /**
+ * Returns: The number of $(D_PSYMBOL RefCounted) instances that share
+ * ownership over the same pointer (including $(D_KEYWORD this)).
+ * If this $(D_PSYMBOL RefCounted) isn't initialized, returns `0`.
+ */
+ @property size_t count() const
+ {
+ return storage is null ? 0 : storage.counter;
+ }
+
+ mixin DefaultAllocator;
+ alias get this;
}
///
unittest
{
- auto rc = RefCounted!int(defaultAllocator.make!int(5), defaultAllocator);
- auto val = rc.get;
+ auto rc = RefCounted!int(defaultAllocator.make!int(5), defaultAllocator);
+ auto val = rc.get;
- *val = 8;
- assert(*rc.storage.payload == 8);
+ *val = 8;
+ assert(*rc.storage.payload == 8);
- val = null;
- assert(rc.storage.payload !is null);
- assert(*rc.storage.payload == 8);
+ val = null;
+ assert(rc.storage.payload !is null);
+ assert(*rc.storage.payload == 8);
- *rc = 9;
- assert(*rc.storage.payload == 9);
+ *rc = 9;
+ assert(*rc.storage.payload == 9);
}
version (unittest)
{
- private class A
- {
- uint *destroyed;
-
- this(ref uint destroyed) @nogc
- {
- this.destroyed = &destroyed;
- }
-
- ~this() @nogc
- {
- ++(*destroyed);
- }
- }
-
- private struct B
- {
- int prop;
- @disable this();
- this(int param1) @nogc
- {
- prop = param1;
- }
- }
+ private class A
+ {
+ uint *destroyed;
+
+ this(ref uint destroyed) @nogc
+ {
+ this.destroyed = &destroyed;
+ }
+
+ ~this() @nogc
+ {
+ ++(*destroyed);
+ }
+ }
+
+ private struct B
+ {
+ int prop;
+ @disable this();
+ this(int param1) @nogc
+ {
+ prop = param1;
+ }
+ }
}
private unittest
{
- uint destroyed;
- auto a = defaultAllocator.make!A(destroyed);
-
- assert(destroyed == 0);
- {
- auto rc = RefCounted!A(a, defaultAllocator);
- assert(rc.count == 1);
-
- void func(RefCounted!A rc)
- {
- assert(rc.count == 2);
- }
- func(rc);
-
- assert(rc.count == 1);
- }
- assert(destroyed == 1);
-
- RefCounted!int rc;
- assert(rc.count == 0);
- rc = defaultAllocator.make!int(8);
- assert(rc.count == 1);
+ uint destroyed;
+ auto a = defaultAllocator.make!A(destroyed);
+
+ assert(destroyed == 0);
+ {
+ auto rc = RefCounted!A(a, defaultAllocator);
+ assert(rc.count == 1);
+
+ void func(RefCounted!A rc)
+ {
+ assert(rc.count == 2);
+ }
+ func(rc);
+
+ assert(rc.count == 1);
+ }
+ assert(destroyed == 1);
+
+ RefCounted!int rc;
+ assert(rc.count == 0);
+ rc = defaultAllocator.make!int(8);
+ assert(rc.count == 1);
}
private unittest
{
- static assert(is(typeof(RefCounted!int.storage.payload) == int*));
- static assert(is(typeof(RefCounted!A.storage.payload) == A));
+ static assert(is(typeof(RefCounted!int.storage.payload) == int*));
+ static assert(is(typeof(RefCounted!A.storage.payload) == A));
- static assert(is(RefCounted!B));
- static assert(is(RefCounted!A));
+ static assert(is(RefCounted!B));
+ static assert(is(RefCounted!A));
}
/**
@@ -374,85 +374,85 @@ private unittest
* object).
*
* Params:
- * T = Type of the constructed object.
- * A = Types of the arguments to the constructor of $(D_PARAM T).
- * allocator = Allocator.
- * args = Constructor arguments of $(D_PARAM T).
+ * T = Type of the constructed object.
+ * A = Types of the arguments to the constructor of $(D_PARAM T).
+ * allocator = Allocator.
+ * args = Constructor arguments of $(D_PARAM T).
*
* Returns: Newly created $(D_PSYMBOL RefCounted!T).
*/
RefCounted!T refCounted(T, A...)(shared Allocator allocator, auto ref A args)
- if (!is(T == interface) && !isAbstractClass!T
+ if (!is(T == interface) && !isAbstractClass!T
&& !isArray!T && !isAssociativeArray!T)
{
- auto rc = typeof(return)(allocator);
-
- immutable storageSize = alignedSize(stateSize!(RefCounted!T.Storage));
- immutable size = alignedSize(stateSize!T + storageSize);
-
- auto mem = (() @trusted => allocator.allocate(size))();
- if (mem is null)
- {
- onOutOfMemoryError();
- }
- scope (failure)
- {
- () @trusted { allocator.deallocate(mem); }();
- }
- rc.storage = emplace!(RefCounted!T.Storage)(mem[0 .. storageSize]);
-
- static if (is(T == class))
- {
- rc.storage.payload = emplace!T(mem[storageSize .. $], args);
- }
- else
- {
- auto ptr = (() @trusted => (cast(T*) mem[storageSize .. $].ptr))();
- rc.storage.payload = emplace!T(ptr, args);
- }
- return rc;
+ auto rc = typeof(return)(allocator);
+
+ immutable storageSize = alignedSize(stateSize!(RefCounted!T.Storage));
+ immutable size = alignedSize(stateSize!T + storageSize);
+
+ auto mem = (() @trusted => allocator.allocate(size))();
+ if (mem is null)
+ {
+ onOutOfMemoryError();
+ }
+ scope (failure)
+ {
+ () @trusted { allocator.deallocate(mem); }();
+ }
+ rc.storage = emplace!(RefCounted!T.Storage)(mem[0 .. storageSize]);
+
+ static if (is(T == class))
+ {
+ rc.storage.payload = emplace!T(mem[storageSize .. $], args);
+ }
+ else
+ {
+ auto ptr = (() @trusted => (cast(T*) mem[storageSize .. $].ptr))();
+ rc.storage.payload = emplace!T(ptr, args);
+ }
+ return rc;
}
///
unittest
{
- auto rc = defaultAllocator.refCounted!int(5);
- assert(rc.count == 1);
-
- void func(RefCounted!int param)
- {
- if (param.count == 2)
- {
- func(param);
- }
- else
- {
- assert(param.count == 3);
- }
- }
- func(rc);
-
- assert(rc.count == 1);
+ auto rc = defaultAllocator.refCounted!int(5);
+ assert(rc.count == 1);
+
+ void func(RefCounted!int param)
+ {
+ if (param.count == 2)
+ {
+ func(param);
+ }
+ else
+ {
+ assert(param.count == 3);
+ }
+ }
+ func(rc);
+
+ assert(rc.count == 1);
}
private @nogc unittest
{
- struct E
- {
- }
- auto b = defaultAllocator.refCounted!B(15);
- static assert(is(typeof(b.storage.payload) == B*));
- static assert(is(typeof(b.prop) == int));
- static assert(!is(typeof(defaultAllocator.refCounted!B())));
-
- static assert(is(typeof(defaultAllocator.refCounted!E())));
- static assert(!is(typeof(defaultAllocator.refCounted!E(5))));
- {
- auto rc = defaultAllocator.refCounted!B(3);
- assert(rc.get.prop == 3);
- }
- {
- auto rc = defaultAllocator.refCounted!E();
- assert(rc.count);
- }
+ struct E
+ {
+ }
+ auto b = defaultAllocator.refCounted!B(15);
+ static assert(is(typeof(b.storage.payload) == B*));
+ static assert(is(typeof(b.prop) == int));
+ static assert(!is(typeof(defaultAllocator.refCounted!B())));
+
+ static assert(is(typeof(defaultAllocator.refCounted!E())));
+ static assert(!is(typeof(defaultAllocator.refCounted!E(5))));
+ {
+ auto rc = defaultAllocator.refCounted!B(3);
+ assert(rc.get.prop == 3);
+ }
+ {
+ auto rc = defaultAllocator.refCounted!E();
+ assert(rc.count);
+ }
}