1 module nxt.array_traits;
2 
3 /// Is `true` iff `T` is a slice of `char`s.
4 enum isCharArray(T) = is(T : const(char)[]);
5 
6 ///
7 pure @safe unittest {
8 	static assert(isCharArray!(char[]));
9 	static assert(isCharArray!(const(char[])));
10 	static assert(isCharArray!(const char[]));
11 	static assert(isCharArray!(const const(char)[]));
12 
13 	static assert(!isCharArray!(wstring));
14 	static assert(!isCharArray!(dstring));
15 }
16 
17 /// Is `true` iff `T` is a slice of `char`s.
18 enum isArrayFast(T) = is(T : const(E)[], E);
19 
20 ///
21 pure @safe unittest {
22 	static assert(isArrayFast!(char[]));
23 	static assert(isArrayFast!(int[]));
24 	static assert(isArrayFast!(const(char[])));
25 	static assert(isArrayFast!(const char[]));
26 	static assert(isArrayFast!(const const(char)[]));
27 	static assert(isArrayFast!(string[]));
28 	static assert(isArrayFast!(immutable(int)[]));
29 	static assert(isArrayFast!(char[3]));
30 }
31 
32 /// Is `true` iff `T` is a slice of `char`s.
33 enum isDynamicArrayFast(T) = is(T : const(E)[], E) && !__traits(isStaticArray, T);
34 
35 ///
36 pure @safe unittest {
37 	static assert(isDynamicArrayFast!(char[]));
38 	static assert(isDynamicArrayFast!(int[]));
39 	static assert(isDynamicArrayFast!(const(char[])));
40 	static assert(isDynamicArrayFast!(const char[]));
41 	static assert(isDynamicArrayFast!(const const(char)[]));
42 	static assert(isDynamicArrayFast!(string[]));
43 	static assert(isDynamicArrayFast!(immutable(int)[]));
44 	static assert(!isDynamicArrayFast!(char[3]));
45 }
46 
47 /** Is `true` iff all `Ts` are slices with same unqualified matching element types.
48  *
49  * Used to define template-restrictions on template parameters of only arrays
50  * (slices) of the same unqualified element types.
51  */
52 template isSameSlices(Ts...)
53 if (Ts.length >= 2) {
54 	enum isSlice(T) = is(T : const(E)[], E);
55 	enum isSliceOf(T, E) = is(T : const(E)[]);
56 	static if (isSlice!(Ts[0])) {
57 		alias E = typeof(Ts[0].init[0]);
58 		static foreach (T; Ts[1 .. $]) {
59 			static if (is(typeof(isSameSlices) == void) && // not yet defined
60 					   !(isSliceOf!(T, E))) {
61 				enum isSameSlices = false;
62 			}
63 		}
64 		static if (is(typeof(isSameSlices) == void)) // if not yet defined
65 		{
66 			enum isSameSlices = true;
67 		}
68 	}
69 	else
70 	{
71 		enum isSameSlices = false;
72 	}
73 }
74 
75 ///
76 pure @safe unittest {
77 	static assert(isSameSlices!(int[], int[]));
78 	static assert(isSameSlices!(const(int)[], int[]));
79 	static assert(isSameSlices!(int[], const(int)[]));
80 	static assert(isSameSlices!(int[], immutable(int)[]));
81 
82 	static assert(isSameSlices!(int[], int[], int[]));
83 	static assert(isSameSlices!(int[], const(int)[], int[]));
84 	static assert(isSameSlices!(int[], const(int)[], immutable(int)[]));
85 	static assert(isSameSlices!(const(int)[], const(int)[], const(int)[]));
86 
87 	static assert(!isSameSlices!(int, char));
88 	static assert(!isSameSlices!(int, const(char)));
89 	static assert(!isSameSlices!(int, int));
90 
91 	static assert(!isSameSlices!(int[], char[]));
92 	static assert(!isSameSlices!(int[], char[], char[]));
93 	static assert(!isSameSlices!(char[], int[]));
94 
95 	static assert(!isSameSlices!(char[], dchar[]));
96 	static assert(!isSameSlices!(wchar[], dchar[]));
97 	static assert(!isSameSlices!(char[], wchar[]));
98 }