1 /++ 2 $(H2 Multidimensional traits) 3 4 This is a submodule of $(MREF mir,ndslice). 5 6 $(BOOKTABLE $(H2 Function), 7 $(TR $(TH Function Name) $(TH Description)) 8 9 $(T2 isVector, Test if type is a one-dimensional slice.) 10 $(T2 isMatrix, Test if type is a two-dimensional slice.) 11 $(T2 isContiguousSlice, Test if type is a contiguous slice.) 12 $(T2 isCanonicalSlice, Test if type is a canonical slice.) 13 $(T2 isUniversalSlice, Test if type is a universal slice.) 14 $(T2 isContiguousVector, Test if type is a contiguous one-dimensional slice.) 15 $(T2 isUniversalVector, Test if type is a universal one-dimensional slice.) 16 $(T2 isContiguousMatrix, Test if type is a contiguous two-dimensional slice.) 17 $(T2 isCanonicalMatrix, Test if type is a canonical two-dimensional slice.) 18 $(T2 isUniversalMatrix, Test if type is a universal two-dimensional slice.) 19 $(T2 isIterator, Test if type is a random access iterator.) 20 ) 21 22 License: $(HTTP www.apache.org/licenses/LICENSE-2.0, Apache-2.0) 23 Copyright: 2020 Ilya Yaroshenko, Kaleidic Associates Advisory Limited, Symmetry Investments 24 Authors: John Hall 25 26 27 Macros: 28 SUBREF = $(REF_ALTTEXT $(TT $2), $2, mir, ndslice, $1)$(NBSP) 29 T2=$(TR $(TDNW $(LREF $1)) $(TD $+)) 30 +/ 31 32 module mir.ndslice.traits; 33 34 import mir.ndslice.slice : Slice, SliceKind, Contiguous, Universal, Canonical; 35 36 /// Test if type is a one-dimensional slice. 37 enum bool isVector(T) = is(T : Slice!(Iterator, 1, kind), SliceKind kind, Iterator); 38 39 /// Test if type is a two-dimensional slice. 40 enum bool isMatrix(T) = is(T : Slice!(Iterator, 2, kind), SliceKind kind, Iterator); 41 42 /// Test if type is a contiguous slice. 43 enum bool isContiguousSlice(T) = is(T : Slice!(Iterator, N, Contiguous), Iterator, size_t N); 44 45 /// Test if type is a canonical slice. 46 enum bool isCanonicalSlice(T) = is(T : Slice!(Iterator, N, Canonical), Iterator, size_t N); 47 48 /// Test if type is a universal slice. 49 enum bool isUniversalSlice(T) = is(T : Slice!(Iterator, N, Universal), Iterator, size_t N); 50 51 /// Test if type is a contiguous one-dimensional slice. 52 enum bool isContiguousVector(T) = is(T : Slice!(Iterator, 1, Contiguous), Iterator); 53 54 /// Test if type is a universal one-dimensional slice. 55 enum bool isUniversalVector(T) = is(T : Slice!(Iterator, 1, Universal), Iterator); 56 57 /// Test if type is a contiguous two-dimensional slice. 58 enum bool isContiguousMatrix(T) = is(T : Slice!(Iterator, 2, Contiguous), Iterator); 59 60 /// Test if type is a canonical two-dimensional slice. 61 enum bool isCanonicalMatrix(T) = is(T : Slice!(Iterator, 2, Canonical), Iterator); 62 63 /// Test if type is a universal two-dimensional slice. 64 enum bool isUniversalMatrix(T) = is(T : Slice!(Iterator, 2, Universal), Iterator); 65 66 /// 67 @safe pure nothrow @nogc 68 version(mir_test) unittest 69 { 70 import mir.ndslice.slice : Slice; 71 72 alias S1 = Slice!(int*); 73 static assert(isContiguousVector!S1); 74 static assert(!isUniversalVector!S1); 75 76 static assert(!isContiguousMatrix!S1); 77 static assert(!isCanonicalMatrix!S1); 78 static assert(!isUniversalMatrix!S1); 79 80 static assert(isVector!S1); 81 static assert(!isMatrix!S1); 82 83 static assert(isContiguousSlice!S1); 84 static assert(!isCanonicalSlice!S1); 85 static assert(!isUniversalSlice!S1); 86 } 87 88 @safe pure nothrow @nogc 89 version(mir_test) unittest 90 { 91 alias S2 = Slice!(float*, 1, Universal); 92 static assert(!isContiguousVector!S2); 93 static assert(isUniversalVector!S2); 94 95 static assert(!isContiguousMatrix!S2); 96 static assert(!isCanonicalMatrix!S2); 97 static assert(!isUniversalMatrix!S2); 98 99 static assert(isVector!S2); 100 static assert(!isMatrix!S2); 101 102 static assert(!isContiguousSlice!S2); 103 static assert(!isCanonicalSlice!S2); 104 static assert(isUniversalSlice!S2); 105 } 106 107 @safe pure nothrow @nogc 108 version(mir_test) unittest 109 { 110 alias S3 = Slice!(byte*, 2); 111 static assert(!isContiguousVector!S3); 112 static assert(!isUniversalVector!S3); 113 114 static assert(isContiguousMatrix!S3); 115 static assert(!isCanonicalMatrix!S3); 116 static assert(!isUniversalMatrix!S3); 117 118 static assert(!isVector!S3); 119 static assert(isMatrix!S3); 120 121 static assert(isContiguousSlice!S3); 122 static assert(!isCanonicalSlice!S3); 123 static assert(!isUniversalSlice!S3); 124 } 125 126 @safe pure nothrow @nogc 127 version(mir_test) unittest 128 { 129 alias S4 = Slice!(int*, 2, Canonical); 130 static assert(!isContiguousVector!S4); 131 static assert(!isUniversalVector!S4); 132 133 static assert(!isContiguousMatrix!S4); 134 static assert(isCanonicalMatrix!S4); 135 static assert(!isUniversalMatrix!S4); 136 137 static assert(!isVector!S4); 138 static assert(isMatrix!S4); 139 140 static assert(!isContiguousSlice!S4); 141 static assert(isCanonicalSlice!S4); 142 static assert(!isUniversalSlice!S4); 143 } 144 145 @safe pure nothrow @nogc 146 version(mir_test) unittest 147 { 148 alias S5 = Slice!(int*, 2, Universal); 149 static assert(!isContiguousVector!S5); 150 static assert(!isUniversalVector!S5); 151 152 static assert(!isContiguousMatrix!S5); 153 static assert(!isCanonicalMatrix!S5); 154 static assert(isUniversalMatrix!S5); 155 156 static assert(!isVector!S5); 157 static assert(isMatrix!S5); 158 159 static assert(!isContiguousSlice!S5); 160 static assert(!isCanonicalSlice!S5); 161 static assert(isUniversalSlice!S5); 162 } 163 164 @safe pure nothrow @nogc 165 version(mir_test) unittest 166 { 167 alias S6 = Slice!(int*, 3); 168 169 static assert(!isContiguousVector!S6); 170 static assert(!isUniversalVector!S6); 171 172 static assert(!isContiguousMatrix!S6); 173 static assert(!isCanonicalMatrix!S6); 174 static assert(!isUniversalMatrix!S6); 175 176 static assert(!isVector!S6); 177 static assert(!isMatrix!S6); 178 179 static assert(isContiguousSlice!S6); 180 static assert(!isCanonicalSlice!S6); 181 static assert(!isUniversalSlice!S6); 182 } 183 184 @safe pure nothrow @nogc 185 version(mir_test) unittest 186 { 187 alias S7 = Slice!(int*, 3, Canonical); 188 189 static assert(!isContiguousVector!S7); 190 static assert(!isUniversalVector!S7); 191 192 static assert(!isContiguousMatrix!S7); 193 static assert(!isCanonicalMatrix!S7); 194 static assert(!isUniversalMatrix!S7); 195 196 static assert(!isVector!S7); 197 static assert(!isMatrix!S7); 198 199 static assert(!isContiguousSlice!S7); 200 static assert(isCanonicalSlice!S7); 201 static assert(!isUniversalSlice!S7); 202 } 203 204 @safe pure nothrow @nogc 205 version(mir_test) unittest 206 { 207 alias S8 = Slice!(int*, 3, Universal); 208 209 static assert(!isContiguousVector!S8); 210 static assert(!isUniversalVector!S8); 211 212 static assert(!isContiguousMatrix!S8); 213 static assert(!isCanonicalMatrix!S8); 214 static assert(!isUniversalMatrix!S8); 215 216 static assert(!isVector!S8); 217 static assert(!isMatrix!S8); 218 219 static assert(!isContiguousSlice!S8); 220 static assert(!isCanonicalSlice!S8); 221 static assert(isUniversalSlice!S8); 222 } 223 224 /// 225 template isIterator(T) 226 { 227 enum isIterator = __traits(compiles, (T a, T b) 228 { 229 sizediff_t diff = a - b; 230 ++a; 231 ++b; 232 --a; 233 --b; 234 void foo(V)(auto ref V v) 235 { 236 237 } 238 foo(a[sizediff_t(3)]); 239 auto c = a + sizediff_t(3); 240 auto d = a - sizediff_t(3); 241 a += sizediff_t(3); 242 a -= sizediff_t(3); 243 foo(*a); 244 }); 245 }