Report a bug
If you spot a problem with this page, click here to create a Github issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

mir.rc.array

Thread-safe reference-counted arrays and iterators

.
struct mir_rcarray(T);

alias RCArray = mir_rcarray(T);
Thread safe reference counting array.
__xdtor if any is used to destruct objects.
The implementation never adds roots into the GC.
Examples:
auto a = RCArray!double(10);
foreach(i, ref e; a)
    e = i;
auto b = a;
assert(b[$ - 1] == 9);
foreach(i, ref e; b)
    assert(e == i);
b[4] = 100;
assert(a[4] == 100);

import mir.ndslice.slice;

auto s = a.asSlice; // as RC random access range (ndslice)
static assert(is(typeof(s) == Slice!(RCI!double)));
static assert(is(typeof(s) == mir_slice!(mir_rci!double)));

auto r = a[]; // scope array
static assert(is(typeof(r) == double[]));

auto fs = r.sliced; // scope fast random access range (ndslice)
static assert(is(typeof(fs) == Slice!(double*)));
Examples:
RCArray!double a = rcarray!double(1.0, 2, 5, 3);
assert(a[0] == 1);
assert(a[$ - 1] == 3);

auto s = rcarray!char("hello!");
assert(s[0] == 'h');
assert(s[$ - 1] == '!');

alias rcstring = rcarray!(immutable char);
auto r = rcstring("string");
assert(r[0] == 's');
assert(r[$ - 1] == 'g');
pure nothrow @nogc @safe void proxySwap(ref typeof(this) rhs);
const pure nothrow @nogc @property scope @trusted size_t length();
inout scope @system inout(T)* ptr();
inout ref scope @trusted auto opIndex(size_t i);
inout scope @trusted inout(T)[] opIndex();
const pure nothrow @nogc scope @trusted size_t opDollar(size_t pos : 0)();
@property auto asSlice();
@nogc @trusted this(size_t length, bool initialize = true, bool deallocate = true);
Parameters:
size_t length array length
bool initialize Flag, don't initialize memory with default value if false.
bool deallocate Flag, never deallocates memory if false.
auto rcarray(T = void, Range)(ref Range range)
if (is(T == void) && hasLength!Range && !is(Range == LightScopeOf!Range));

auto rcarray(T = void, Range)(Range range)
if (is(T == void) && hasLength!Range && isIterable!Range && is(Range == LightScopeOf!Range) && !isArray!Range);

RCArray!V rcarray(T = void, V)(V[] values...)
if (is(T == void) && hasIndirections!V);

RCArray!V rcarray(T = void, V)(scope V[] values...)
if (is(T == void) && !hasIndirections!V);

RCArray!V rcarray(T = void, V)(V[] values, bool deallocate)
if (is(T == void) && hasIndirections!V);

RCArray!V rcarray(T = void, V)(scope V[] values, bool deallocate)
if (is(T == void) && !hasIndirections!V);
template rcarray(T) if (!is(T == E[], E) && !is(T == void))
auto rcarray(Range)(ref Range range)
if (hasLength!Range && !is(Range == LightScopeOf!Range));

auto rcarray(Range)(Range range)
if (hasLength!Range && isIterable!Range && is(Range == LightScopeOf!Range) && !isArray!Range);

RCArray!T rcarray(V)(V[] values...)
if (hasIndirections!V);

RCArray!T rcarray(V)(scope V[] values...)
if (!hasIndirections!V);

RCArray!T rcarray(V)(V[] values, bool deallocate)
if (hasIndirections!V);

RCArray!T rcarray(V)(scope V[] values, bool deallocate)
if (!hasIndirections!V);
RCArray!T mininitRcarray(T)(size_t length, bool deallocate = true);
Parameters:
size_t length array length
bool deallocate Flag, never deallocates memory if false.
Returns:
minimally initialized rcarray.
Examples:
auto a = mininitRcarray!double(5);
assert(a.length == 5);
assert(a._counter == 1);
a[][] = 0; // a.opIndex()[] = 0;
struct mir_rci(T);

alias RCI = mir_rci(T);
Thread safe reference counting iterator.
Examples:
import mir.ndslice.traits: isIterator;
import mir.ndslice.slice;
import mir.rc.array;
auto array = mir_rcarray!double(10);
auto slice = array.asSlice;
static assert(isIterator!(RCI!double));
static assert(is(typeof(slice) == Slice!(RCI!double)));
auto matrix = slice.sliced(2, 5);
static assert(is(typeof(matrix) == Slice!(RCI!double, 2)));
array[7] = 44;
assert(matrix[1, 2] == 44);
Examples:
import mir.ndslice.slice;
import mir.rc.array;

alias rcvec = Slice!(RCI!double);

RCI!double a, b;
a = b;

RCI!(const double) ca, cb;
ca = cb;
ca = cast(const) cb;

void foo(scope ref rcvec x, scope ref rcvec y)
{
    x[] = y[];
    x[1] = y[1];
    x[1 .. $] += y[1 .. $];
    x = x.save;
}
T* _iterator;
RCArray!T _array;
this(RCArray!T array);
this(T* _iterator, RCArray!T array);
inout @property scope @trusted inout(T)* lightScope()() return;
nothrow ref scope auto opAssign(typeof(null)) return;
ref scope @trusted auto opAssign(return typeof(this) rhs) return;
nothrow ref scope auto opAssign(Q)(return mir_rci!Q rhs) return
if (isImplicitlyConvertible!(Q*, T*));
const nothrow @property scope mir_rci!(const(T)) lightConst()() return;
immutable nothrow @property scope mir_rci!(immutable(T)) lightImmutable()() return;
inout ref scope inout(T) opUnary(string op : "*")() return;
inout ref scope @trusted inout(T) opIndex(ptrdiff_t index) return;
scope void opUnary(string op)()
if (op == "--" || op == "++");
scope void opOpAssign(string op)(ptrdiff_t index)
if (op == "-" || op == "+");
mir_rci!T opBinary(string op)(ptrdiff_t index)
if (op == "+" || op == "-");
const mir_rci!(const(T)) opBinary(string op)(ptrdiff_t index)
if (op == "+" || op == "-");
immutable mir_rci!(immutable(T)) opBinary(string op)(ptrdiff_t index)
if (op == "+" || op == "-");
const scope ptrdiff_t opBinary(string op : "-")(ref scope const typeof(this) right);
const scope bool opEquals()(ref scope const typeof(this) right);
const scope ptrdiff_t opCmp()(ref scope const typeof(this) right);