I personally would use if(is(typeof(T.init != E.init) == bool)) to make sure it is of type vars
(and then when you want T to be a range (and lose array notation, it will be if(isInputRange(T) && is(typeof(T.init.front != E.init) == bool)) )
edit: the best way to test things like extending a test case, for example:
if you take another function:
int binarySearch(T,E)(T[] haystack, E needle) if(is(typeof(haystack[0] < needle) == bool)) {
this compiles and works as you expected (prohibition of implementation details ...)
but
int binarySearch(T,E)(T[] haystack, E needle) if(is(typeof(T < E) == bool)) {
no (calling binarySearch([1,2,3],0); does not compile on it)
however, as my original answer:
int binarySearch(T,E)(T[] haystack, E needle) if(is(typeof(T.init > E.init) == bool)) {
it works as expected
source share