MutableDStringN

Stack-allocated mutable dstring of maximum length of capacity.

@safe pure
alias MutableDStringN(uint capacity, bool borrowChecked = false) = FixedArray!(char, capacity, borrowChecked)

Examples

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

1 enum capacity = 15;
2 foreach (StrN; AliasSeq!(StringN// , WStringN, DStringN
3              ))
4 {
5     alias String15 = StrN!(capacity);
6 
7     typeof(String15.init[0])[] xs;
8     auto x = String15("alphas");
9 
10     assert(x[0] == 'a');
11     assert(x[$ - 1] == 's');
12 
13     assert(x[0 .. 2] == "al");
14     assert(x[] == "alphas");
15 
16     const y = String15("åäö_åäöå"); // fits in 15 chars
17 }

scope checked string

1 enum capacity = 15;
2 foreach (Str; AliasSeq!(StringN!capacity,
3                         WStringN!capacity,
4                         DStringN!capacity))
5 {
6     static assert(!mustAddGCRange!Str);
7     static if (isDIP1000)
8     {
9         static assert(!__traits(compiles, {
10                     auto f() @safe pure
11                     {
12                         auto x = Str("alphas");
13                         auto y = x[];
14                         return y;   // errors with -dip1000
15                     }
16                 }));
17     }
18 }
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
1 static void testAsSomeString(T)()
2 {
3     enum capacity = 15;
4     alias A = FixedArray!(immutable(T), capacity);
5     static assert(!mustAddGCRange!A);
6     auto a = A("abc");
7     assert(a[] == "abc");
8     assert(a[].equal("abc"));
9 
10     import std.conv : to;
11     const x = "a".to!(T[]);
12 }
13 
14 foreach (T; AliasSeq!(char// , wchar, dchar
15              ))
16 {
17     testAsSomeString!T();
18 }

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

1 enum capacity = 15;
2 alias S = FixedArray!(int, capacity);
3 
4 assert(S.fromValuesUnsafe([1, 2, 3].s) ==
5        S.fromValuesUnsafe([1, 2, 3].s));
6 
7 const ax = [1, 2, 3].s;
8 assert(S.fromValuesUnsafe([1, 2, 3].s) == ax);
9 assert(S.fromValuesUnsafe([1, 2, 3].s) == ax[]);
10 
11 const cx = [1, 2, 3].s;
12 assert(S.fromValuesUnsafe([1, 2, 3].s) == cx);
13 assert(S.fromValuesUnsafe([1, 2, 3].s) == cx[]);
14 
15 immutable ix = [1, 2, 3].s;
16 assert(S.fromValuesUnsafe([1, 2, 3].s) == ix);
17 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

1 enum capacity = 15;
2 alias String15 = StringN!(capacity, true);
3 static assert(String15.readBorrowCountMax == 7);
4 static assert(!mustAddGCRange!String15);
5 
6 auto x = String15("alpha");
7 
8 assert(x[].equal("alpha") &&
9        x[].equal("alpha"));
10 
11 {
12     auto xw1 = x[];
13     assert(x.isWriteBorrowed);
14     assert(x.isBorrowed);
15 }
16 
17 auto xr1 = (cast(const)x)[];
18 assert(x.readBorrowCount == 1);
19 
20 auto xr2 = (cast(const)x)[];
21 assert(x.readBorrowCount == 2);
22 
23 auto xr3 = (cast(const)x)[];
24 assert(x.readBorrowCount == 3);
25 
26 auto xr4 = (cast(const)x)[];
27 assert(x.readBorrowCount == 4);
28 
29 auto xr5 = (cast(const)x)[];
30 assert(x.readBorrowCount == 5);
31 
32 auto xr6 = (cast(const)x)[];
33 assert(x.readBorrowCount == 6);
34 
35 auto xr7 = (cast(const)x)[];
36 assert(x.readBorrowCount == 7);
37 
38 assertThrown!AssertError((cast(const)x)[]);

Meta