@@ -47,27 +47,50 @@ string _d_assert_fail(string comp, A, B)(auto ref const scope A a, auto ref cons
47
47
* Returns:
48
48
* A string such as "$a != true" or "$a == true".
49
49
*/
50
+ string _d_assert_fail2 (A)(string op, auto ref const scope A a)
51
+ {
52
+ string [2 ] vals = [ miniFormatFakeAttributes(a), " true" ];
53
+ immutable token = op == " !" ? " ==" : " !=" ;
54
+ return combine (vals[0 .. 1 ], token, vals[1 .. $]);
55
+ }
56
+
57
+ // / Ditto
50
58
string _d_assert_fail (A)(const scope string op, auto ref const scope A a)
51
59
{
52
- string val = miniFormatFakeAttributes(a);
60
+ string [ 2 ] vals = [ miniFormatFakeAttributes(a), " true " ] ;
53
61
immutable token = op == " !" ? " ==" : " !=" ;
54
- return combine (val , token, " true " );
62
+ return combine (vals[ 0 .. 1 ] , token, vals[ 1 .. $] );
55
63
}
56
64
57
65
/**
58
66
* Generates rich assert error messages for binary expressions
59
67
*
60
68
* The binary expression `assert(x == y)` will be turned into
61
- * `assert(x == y, _d_assert_fail("==", x, y))`.
69
+ * `assert(x == y, _d_assert_fail!(typeof(x)) ("==", x, y))`.
62
70
*
63
71
* Params:
64
72
* comp = Comparison operator that was used in the expression.
65
- * a = Left hand side operand.
66
- * b = Right hand side operand.
73
+ * a = Left hand side operand (can be a tuple) .
74
+ * b = Right hand side operand (can be a tuple) .
67
75
*
68
76
* Returns:
69
77
* A string such as "$a $comp $b".
70
78
*/
79
+ template _d_assert_fail2 (A... ) {
80
+ string _d_assert_fail2 (B... )(
81
+ string comp, auto ref const scope A a, auto ref const scope B b)
82
+ {
83
+ string [A.length + B.length] vals;
84
+ static foreach (idx; 0 .. A.length)
85
+ vals[idx] = miniFormatFakeAttributes(a[idx]);
86
+ static foreach (idx; 0 .. B.length)
87
+ vals[A.length + idx] = miniFormatFakeAttributes(b[idx]);
88
+ immutable token = invertCompToken(comp);
89
+ return combine (vals[0 .. A.length], token, vals[A.length .. $]);
90
+ }
91
+ }
92
+
93
+ // / Ditto
71
94
string _d_assert_fail (A, B)(const scope string comp, auto ref const scope A a, auto ref const scope B b)
72
95
{
73
96
/*
@@ -77,26 +100,44 @@ string _d_assert_fail(A, B)(const scope string comp, auto ref const scope A a, a
77
100
Hence, we can fake purity and @nogc-ness here.
78
101
*/
79
102
80
- string valA = miniFormatFakeAttributes(a);
81
- string valB = miniFormatFakeAttributes(b);
103
+ string [ 1 ] valA = miniFormatFakeAttributes(a);
104
+ string [ 1 ] valB = miniFormatFakeAttributes(b);
82
105
immutable token = invertCompToken(comp);
83
- return combine (valA, token, valB);
106
+ return combine (valA[] , token, valB[] );
84
107
}
85
108
86
109
// / Combines the supplied arguments into one string "valA token valB"
87
- private string combine (const scope string valA, const scope string token,
88
- const scope string valB) pure nothrow @nogc @safe
110
+ private string combine (const scope string [] valA, const scope string token,
111
+ const scope string [] valB) pure nothrow @nogc @safe
89
112
{
90
- const totalLen = valA.length + token.length + valB.length + 2 ;
113
+ // Each separator is 2 chars (", "), plus the two spaces around the token.
114
+ size_t totalLen = (valA.length - 1 ) * 2 +
115
+ (valB.length - 1 ) * 2 + 2 + token.length;
116
+ foreach (v; valA) totalLen += v.length;
117
+ foreach (v; valB) totalLen += v.length;
91
118
char [] buffer = cast (char []) pureAlloc(totalLen)[0 .. totalLen];
92
119
// @nogc-concat of "<valA> <comp> <valB>"
93
- auto n = valA.length;
94
- buffer[0 .. n] = valA;
120
+ static void formatTuple (scope char [] buffer, ref size_t n, in string [] vals)
121
+ {
122
+ foreach (idx, v; vals)
123
+ {
124
+ if (idx)
125
+ {
126
+ buffer[n++ ] = ' ,' ;
127
+ buffer[n++ ] = ' ' ;
128
+ }
129
+ buffer[n .. n + v.length] = v;
130
+ n += v.length;
131
+ }
132
+ }
133
+
134
+ size_t n;
135
+ formatTuple(buffer, n, valA);
95
136
buffer[n++ ] = ' ' ;
96
137
buffer[n .. n + token.length] = token;
97
138
n += token.length;
98
139
buffer[n++ ] = ' ' ;
99
- buffer[n .. n + valB.length] = valB ;
140
+ formatTuple( buffer, n, valB) ;
100
141
return (() @trusted => cast (string ) buffer)();
101
142
}
102
143
@@ -371,7 +412,7 @@ private string invertCompToken(string comp) pure nothrow @nogc @safe
371
412
case " !in" :
372
413
return " in" ;
373
414
default :
374
- assert (0 , combine(" Invalid comparison operator" , " -" , comp));
415
+ assert (0 , combine([ " Invalid comparison operator" ] , " -" , [ comp] ));
375
416
}
376
417
}
377
418
0 commit comments