1 module nxt.flatten_trait;
2 
3 /** Is `true` iff a list of types, which are composed of ranges and non ranges,
4  * share a common type after flattening the ranges (i.e. `ElementType`)
5  *
6  * This basically answers the question: $(I Can I combine these ranges and
7  * values into a single range of a common type?).
8  *
9  * See_Also: `meta_ex.FlattenedRanges`
10  */
11 template areFlatteninglyCombinable(Values...)
12 {
13     import std.traits : CommonType;
14     import nxt.meta_ex : FlattenedRanges;
15     enum areFlatteninglyCombinable = !is(CommonType!(FlattenedRanges!Values) == void);
16 }
17 
18 ///
19 unittest
20 {
21     static assert(areFlatteninglyCombinable!(int, int, int));
22     static assert(areFlatteninglyCombinable!(float[], int, char[]));
23     static assert(areFlatteninglyCombinable!(string, int, int));
24 
25     // Works with string because:
26     import std.traits : CommonType;
27     import std.range.primitives : ElementType;
28 
29     static assert(is(CommonType!(ElementType!string, int) == uint));
30 
31     struct A
32     {
33     }
34 
35     static assert(!areFlatteninglyCombinable!(A, int, int));
36     static assert(!areFlatteninglyCombinable!(A[], int[]));
37     static assert( areFlatteninglyCombinable!(A[], A[]));
38     static assert( areFlatteninglyCombinable!(A[], A[], A));
39     static assert(!areFlatteninglyCombinable!(int[], A));
40 }