forked from DlangScience/scid
/
assertmessages.d
120 lines (99 loc) · 3.63 KB
/
assertmessages.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/** Common error messages to use with assertions.
Authors: Cristian Cobzarenco
Copyright: Copyright (c) 2011, Cristian Cobzarenco. All rights reserved.
License: Boost License 1.0
*/
module scid.internal.assertmessages;
import std.string : format;
import std.range, std.conv;
/** Error messages for array-like structs. */
mixin template ArrayErrorMessages() {
/** Prefix for all error messages. */
private enum msgPrefix_ = typeof(this).stringof ~ ": ";
/** Out of bounds error message. */
string boundsMsg_( size_t i ) const {
return format( msgPrefix_ ~ "Out of bounds %d vs. %d.", i, length );
}
/** Invalid slice indices error message. */
string sliceMsg_( size_t s, size_t e ) const {
return format( msgPrefix_ ~ "Invalid slice indices [%d .. %d] vs. %d.", s, e, length );
}
/** Invalid slice indices in slice assignment error message. */
string sliceAssignMsg_( size_t s, size_t e, size_t rl ) const {
return format( msgPrefix_ ~ "Slice assignment length mismatch [%d .. %d] with length %d vs %d.", s, e, e-s, rl );
}
/** (pop)front/back called on empty array. */
string emptyMsg_( string func ) const pure {
return msgPrefix_ ~ func ~ " called on empty.";
}
/** Length mismatch in vector operation. */
string lengthMismatch_( size_t len, string op = "" ) const {
return format("%sLength mismatch in vector operation '%s': %d vs. %d.", msgPrefix_, op, length, len );
}
/** Constructed with length = 0. */
enum zeroDimMsg_ = msgPrefix_ ~ "Zero length in constructor.";
}
/** Error messages for array-like structs (matrix literal, storages and containers). */
mixin template MatrixErrorMessages() {
/** Prefix for all error messages. */
enum msgPrefix_ = typeof(this).stringof ~ ": ";
/** Out of bounds error message. */
string boundsMsg_( size_t i, size_t j ) const {
return format( msgPrefix_ ~ "Out of bounds [%d, %d] vs. [%d, %d].", i, j, rows, columns );
}
/** Invalid slice indices error message. */
string sliceMsg_( size_t a, size_t b, size_t c, size_t d ) const {
return format( msgPrefix_ ~ "Invalid slice indices [%d .. %d][%d .. %d] vs. [%d, %d] .", a,c,b,d, rows, columns );
}
/** Invalid initializer error message. */
string initMsg_( size_t r, ElementType[] i ) const {
return format( msgPrefix_ ~ "Invalid initializer (%d, %s).", r, i );
}
/** Dimension mismatch in matrix operation. */
string dimMismatch_( size_t r, size_t c, string op="" ) const {
return format("%sDimension mismatch in matrix operation '%s': (%d,%d) vs. (%d,%d).", msgPrefix_, op, rows, columns, r, c );
}
/** Zero dimension eror message */
string zeroDimMsg_( size_t r, size_t c ) const {
return format( msgPrefix_ ~ "Zero dimension in [%d, %d].", r, c );
}
}
string stridedToString( S )( const(S)* ptr, size_t len, size_t stride ) {
if( len == 0 )
return "[]";
auto app = appender!string("[");
app.put( to!string(*ptr) );
auto e = ptr + len * stride;
for( ptr += stride; ptr < e ; ptr += stride ) {
app.put( ", " );
app.put( to!string( *ptr ) );
}
app.put(']');
return app.data();
}
string matrixToString( S )( char trans, size_t m, size_t n, const(S)* a, size_t lda )
in {
assert( a );
} body {
if( m == 0 || n == 0 )
return "[]";
auto app = appender!string("[");
if( trans == 'n' ) {
app.put( stridedToString( a, n, lda ) );
auto e = a + m;
for( ++ a; a < e ; ++a ) {
app.put( ", " );
app.put( stridedToString( a, n, lda ) );
}
app.put(']');
} else {
app.put( stridedToString(a, m, 1) );
auto e = a + n * lda;
for( a += lda ; a < e ; a += lda ) {
app.put( ", " );
app.put( stridedToString( a, m, 1 ) );
}
app.put(']');
}
return app.data();
}