construct from array may throw
enum capacity = 3; alias T = int; alias A = FixedArray!(T, capacity); static assert(!mustAddGCRange!A); auto a = A([1, 2, 3].s[]); assert(a[] == [1, 2, 3].s);
unsafe construct from array
enum capacity = 3; alias T = int; alias A = FixedArray!(T, capacity); static assert(!mustAddGCRange!A); auto a = A.fromValuesUnsafe([1, 2, 3].s); assert(a[] == [1, 2, 3].s);
construct from scalars is nothrow
enum capacity = 3; alias T = int; alias A = FixedArray!(T, capacity); static assert(!mustAddGCRange!A); auto a = A(1, 2, 3); assert(a[] == [1, 2, 3].s); static assert(!__traits(compiles, { auto _ = A(1, 2, 3, 4); }));
scope checked string
enum capacity = 15; foreach (StrN; AliasSeq!(StringN// , WStringN, DStringN )) { alias String15 = StrN!(capacity); typeof(String15.init[0])[] xs; assert(xs.length == 0); auto x = String15("alphas"); assert(x[0] == 'a'); assert(x[$ - 1] == 's'); assert(x[0 .. 2] == "al"); assert(x[] == "alphas"); const y = String15("åäö_åäöå"); // fits in 15 chars assert(y.length == capacity); }
scope checked string
enum capacity = 15; foreach (Str; AliasSeq!(StringN!capacity, WStringN!capacity, DStringN!capacity)) { static assert(!mustAddGCRange!Str); static if (isDIP1000) { static assert(!__traits(compiles, { auto f() @safe pure { auto x = Str("alphas"); auto y = x[]; return y; // errors with -dip1000 } })); } }
1 import std.exception : assertNotThrown; 2 3 alias T = char; 4 enum capacity = 3; 5 6 alias A = FixedArray!(T, capacity, true); 7 static assert(!mustAddGCRange!A); 8 static assert(A.sizeof == T.sizeof*capacity + 1); 9 10 import std.range.primitives : isOutputRange; 11 static assert(isOutputRange!(A, T)); 12 13 auto ab = A("ab"); 14 assert(!ab.empty); 15 assert(ab[0] == 'a'); 16 assert(ab.front == 'a'); 17 assert(ab.back == 'b'); 18 assert(ab.length == 2); 19 assert(ab[] == "ab"); 20 assert(ab[0 .. 1] == "a"); 21 assertNotThrown(ab.insertBack('_')); 22 assert(ab[] == "ab_"); 23 ab.popBack(); 24 assert(ab[] == "ab"); 25 assert(ab.toString == "ab"); 26 27 ab.popBackN(2); 28 assert(ab.empty); 29 assertNotThrown(ab.insertBack('a', 'b')); 30 31 const abc = A("abc"); 32 assert(!abc.empty); 33 assert(abc.front == 'a'); 34 assert(abc.back == 'c'); 35 assert(abc.length == 3); 36 assert(abc[] == "abc"); 37 assert(ab[0 .. 2] == "ab"); 38 assert(abc.full); 39 static assert(!__traits(compiles, { const abcd = A('a', 'b', 'c', 'd'); })); // too many elements 40 41 assert(ab[] == "ab"); 42 ab.popFront(); 43 assert(ab[] == "b"); 44 45 const xy = A("xy"); 46 assert(!xy.empty); 47 assert(xy[0] == 'x'); 48 assert(xy.front == 'x'); 49 assert(xy.back == 'y'); 50 assert(xy.length == 2); 51 assert(xy[] == "xy"); 52 assert(xy[0 .. 1] == "x"); 53 54 const xyz = A("xyz"); 55 assert(!xyz.empty); 56 assert(xyz.front == 'x'); 57 assert(xyz.back == 'z'); 58 assert(xyz.length == 3); 59 assert(xyz[] == "xyz"); 60 assert(xyz.full); 61 static assert(!__traits(compiles, { const xyzw = A('x', 'y', 'z', 'w'); })); // too many elements
static void testAsSomeString(T)() { enum capacity = 15; alias A = FixedArray!(immutable(T), capacity); static assert(!mustAddGCRange!A); auto a = A("abc"); assert(a[] == "abc"); import std.conv : to; const x = "a".to!(T[]); } foreach (T; AliasSeq!(char// , wchar, dchar )) { testAsSomeString!T(); }
equality
enum capacity = 15; alias S = FixedArray!(int, capacity); static assert(!mustAddGCRange!S); assert(S([1, 2, 3].s[]) == S([1, 2, 3].s[])); assert(S([1, 2, 3].s[]) == [1, 2, 3]);
insertBackMaybe is nothrow @nogc.
alias S = FixedArray!(int, 2); S s; assert(s.insertBackMaybe(42)); assert(s.insertBackMaybe(43)); assert(!s.insertBackMaybe(0)); assert(s.length == 2);
equality
enum capacity = 15; alias S = FixedArray!(int, capacity); assert(S.fromValuesUnsafe([1, 2, 3].s) == S.fromValuesUnsafe([1, 2, 3].s)); const ax = [1, 2, 3].s; assert(S.fromValuesUnsafe([1, 2, 3].s) == ax); assert(S.fromValuesUnsafe([1, 2, 3].s) == ax[]); const cx = [1, 2, 3].s; assert(S.fromValuesUnsafe([1, 2, 3].s) == cx); assert(S.fromValuesUnsafe([1, 2, 3].s) == cx[]); immutable ix = [1, 2, 3].s; assert(S.fromValuesUnsafe([1, 2, 3].s) == ix); assert(S.fromValuesUnsafe([1, 2, 3].s) == ix[]);
assignment from const to immutable element type
enum capacity = 15; alias String15 = StringN!(capacity); static assert(!mustAddGCRange!String15); const char[4] _ = ['a', 'b', 'c', 'd']; auto x = String15(_[]); assert(x.length == 4); assert(x[] == "abcd");
borrow checking
enum capacity = 15; alias String15 = StringN!(capacity, true); static assert(String15.readBorrowCountMax == 7); static assert(!mustAddGCRange!String15); auto x = String15("alpha"); assert(x[] == "alpha"); { auto xw1 = x[]; assert(x.isWriteBorrowed); assert(x.isBorrowed); } auto xr1 = (cast(const)x)[]; assert(x.readBorrowCount == 1); auto xr2 = (cast(const)x)[]; assert(x.readBorrowCount == 2); auto xr3 = (cast(const)x)[]; assert(x.readBorrowCount == 3); auto xr4 = (cast(const)x)[]; assert(x.readBorrowCount == 4); auto xr5 = (cast(const)x)[]; assert(x.readBorrowCount == 5); auto xr6 = (cast(const)x)[]; assert(x.readBorrowCount == 6); auto xr7 = (cast(const)x)[]; assert(x.readBorrowCount == 7); assertThrown!AssertError((cast(const)x)[]);
Stack-allocated mutable dstring of maximum length of capacity.