module nxt.flatten_trait; /** Is `true` iff a list of types, which are composed of ranges and non ranges, * share a common type after flattening the ranges (i.e. `ElementType`) * * This basically answers the question: $(I Can I combine these ranges and * values into a single range of a common type?). * * See_Also: `meta_ex.FlattenedRanges` */ template areFlatteninglyCombinable(Values...) { import std.traits : CommonType; import nxt.meta_ex : FlattenedRanges; enum areFlatteninglyCombinable = !is(CommonType!(FlattenedRanges!Values) == void); } /// unittest { static assert(areFlatteninglyCombinable!(int, int, int)); static assert(areFlatteninglyCombinable!(float[], int, char[])); static assert(areFlatteninglyCombinable!(string, int, int)); // Works with string because: import std.traits : CommonType; import std.range.primitives : ElementType; static assert(is(CommonType!(ElementType!string, int) == uint)); struct A { } static assert(!areFlatteninglyCombinable!(A, int, int)); static assert(!areFlatteninglyCombinable!(A[], int[])); static assert( areFlatteninglyCombinable!(A[], A[])); static assert( areFlatteninglyCombinable!(A[], A[], A)); static assert(!areFlatteninglyCombinable!(int[], A)); }