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 }