1 enum m = 3;
2 int[m] x = [11, 22, 33];
3 auto y = x.strictlyIndexed;
4
5 alias Y = typeof(y);
6
7 static assert(is(typeof(y.findIndex(11).index) == Y.Index));
8
9 assert(y.findIndex(11).exists);
10 assert(y.findIndex(22).exists);
11 assert(y.findIndex(33).exists);
12
13 if (auto hit = y.findIndex(11)) { assert(hit.index == 0); } else { assert(false); }
14 if (auto hit = y.findIndex(22)) { assert(hit.index == 1); } else { assert(false); }
15 if (auto hit = y.findIndex(33)) { assert(hit.index == 2); } else { assert(false); }
16
17 assert(!y.findIndex(44));
18 assert(!y.findIndex(55));
19
20 assert(!y.findIndex(44).exists);
21 assert(!y.findIndex(55).exists);
enum N = 7;
alias T = TypesafelyIndexed!(size_t[N]); // static array
static assert(T.sizeof == N*size_t.sizeof);
import nxt.modulo : Mod, mod;
T x;
x[Mod!N(1)] = 11;
x[1.mod!N] = 11;
assert(x[1.mod!N] == 11);
x.at!1 = 12;
static assert(!__traits(compiles, { x.at!N; }));
assert(x.at!1 == 12);
1 int[3] x = [1, 2, 3];
2
3 // sample index
4 struct Index(T = size_t)
5 if (isUnsigned!T)
6 {
7 this(T i) { this._i = i; }
8 T opCast(U : T)() const { return _i; }
9 private T _i = 0;
10 }
11 alias J = Index!size_t;
12
13 enum E { e0, e1, e2 }
14
15 with (E)
16 {
17 auto xb = x.indexedBy!ubyte;
18 auto xi = x.indexedBy!uint;
19 auto xj = x.indexedBy!J;
20 auto xe = x.indexedBy!E;
21 auto xf = x.strictlyIndexed;
22
23 auto xs = x.indexedBy!"I";
24 alias XS = typeof(xs);
25 XS xs_;
26
27 // indexing with correct type
28 xb[ 0 ] = 11; assert(xb[ 0 ] == 11);
29 xi[ 0 ] = 11; assert(xi[ 0 ] == 11);
30 xj[J(0)] = 11; assert(xj[J(0)] == 11);
31 xe[ e0 ] = 11; assert(xe[ e0 ] == 11);
32
33 // indexing with wrong type
34 static assert(!__traits(compiles, { xb[J(0)] = 11; }));
35 static assert(!__traits(compiles, { xi[J(0)] = 11; }));
36 static assert(!__traits(compiles, { xj[ 0 ] = 11; }));
37 static assert(!__traits(compiles, { xe[ 0 ] = 11; }));
38 static assert(!__traits(compiles, { xs[ 0 ] = 11; }));
39 static assert(!__traits(compiles, { xs_[ 0 ] = 11; }));
40
41 import std.algorithm.comparison : equal;
42 import std.algorithm.iteration : filter;
43
44 assert(equal(xb[].filter!(a => a < 11), [2, 3]));
45 assert(equal(xi[].filter!(a => a < 11), [2, 3]));
46 assert(equal(xj[].filter!(a => a < 11), [2, 3]));
47 assert(equal(xe[].filter!(a => a < 11), [2, 3]));
48 // assert(equal(xs[].filter!(a => a < 11), [2, 3]));
49 }
1 auto x = [1, 2, 3];
2
3 // sample index
4 struct Index(T = size_t)
5 if (isUnsigned!T)
6 {
7 this(T ix) { this._ix = ix; }
8 T opCast(U : T)() const { return _ix; }
9 private T _ix = 0;
10 }
11 alias J = Index!size_t;
12
13 enum E { e0, e1, e2 }
14
15 with (E)
16 {
17 auto xb = x.indexedBy!ubyte;
18 auto xi = x.indexedBy!uint;
19 auto xj = x.indexedBy!J;
20 auto xe = x.indexedBy!E;
21
22 // indexing with correct type
23 xb[ 0 ] = 11; assert(xb[ 0 ] == 11);
24 xi[ 0 ] = 11; assert(xi[ 0 ] == 11);
25 xj[J(0)] = 11; assert(xj[J(0)] == 11);
26 xe[ e0 ] = 11; assert(xe[ e0 ] == 11);
27
28 // slicing with correct type
29 xb[ 0 .. 1 ] = 12; assert(xb[ 0 .. 1 ] == [12]);
30 xi[ 0 .. 1 ] = 12; assert(xi[ 0 .. 1 ] == [12]);
31 xj[J(0) .. J(1)] = 12; assert(xj[J(0) .. J(1)] == [12]);
32 xe[ e0 .. e1 ] = 12; assert(xe[ e0 .. e1 ] == [12]);
33
34 // indexing with wrong type
35 static assert(!__traits(compiles, { xb[J(0)] = 11; }));
36 static assert(!__traits(compiles, { xi[J(0)] = 11; }));
37 static assert(!__traits(compiles, { xj[ 0 ] = 11; }));
38 static assert(!__traits(compiles, { xe[ 0 ] = 11; }));
39
40 // slicing with wrong type
41 static assert(!__traits(compiles, { xb[J(0) .. J(0)] = 11; }));
42 static assert(!__traits(compiles, { xi[J(0) .. J(0)] = 11; }));
43 static assert(!__traits(compiles, { xj[ 0 .. 0 ] = 11; }));
44 static assert(!__traits(compiles, { xe[ 0 .. 0 ] = 11; }));
45
46 import std.algorithm.comparison : equal;
47 import std.algorithm.iteration : filter;
48
49 assert(equal(xb.filter!(a => a < 11), [2, 3]));
50 assert(equal(xi.filter!(a => a < 11), [2, 3]));
51 assert(equal(xj.filter!(a => a < 11), [2, 3]));
52 assert(equal(xe.filter!(a => a < 11), [2, 3]));
53 }
auto x = [1, 2, 3];
struct I(T = size_t)
{
this(T ix) { this._ix = ix; }
T opCast(U : T)() const { return _ix; }
private T _ix = 0;
}
alias J = I!size_t;
auto xj = x.indexedBy!J;
auto x = [1, 2, 3];
struct I(T = size_t)
{
private T _ix = 0;
}
alias J = I!size_t;
static assert(!__traits(compiles, { auto xj = x.indexedBy!J; }));
auto x = [1, 2, 3];
import nxt.bound : Bound;
alias B = Bound!(ubyte, 0, 2);
B b;
auto c = cast(size_t)b;
auto y = x.indexedBy!B;
1 import nxt.dynamic_array : Array = DynamicArray;
2
3 enum Lang { en, sv, fr }
4
5 alias Ixs = Array!int;
6
7 struct S
8 {
9 Lang lang;
10 string data;
11 Ixs ixs;
12 }
13
14 alias A = Array!S;
15
16 struct I
17 {
18 size_t opCast(U : size_t)() const @safe pure nothrow @nogc { return _ix; }
19 uint _ix;
20 alias _ix this;
21 }
22
23 I i;
24 static assert(isCastableTo!(I, size_t));
25 static assert(isIndexableBy!(A, I));
26
27 alias IA = IndexedBy!(A, I);
28 IA ia;
29 ia ~= S.init;
30 assert(ia.length == 1);
31 auto s = S(Lang.en, "alpha", Ixs.withLength(42));
32
33 import core.lifetime : move;
34
35 ia ~= move(s);
36 assert(ia.length == 2);
Instantiator for TypesafelyIndexed.