Search code examples
arraystemplatesdtype-traits

determine whether the template arguments are arrays holding the same unqualified type


I am trying to make a template that determines whether the arguments are arrays holding the same unqualified type.

template sameUnqualArrays(A, B) {
  enum bool sameUnqualArrays = isArray!A && isArray!B &&
      is(Unqual!(ForeachType!A) == Unqual!(ForeachType!B));
}

unittest {
  static assert(sameUnqualArrays!(ubyte[], immutable(ubyte[])));
  static assert(!sameUnqualArrays!(ubyte[], immutable(byte[])));
  static assert(!sameUnqualArrays!(ubyte[], ubyte));
}

Unfortunately the last assert doesn't pass but gives the error: /usr/include/dmd/phobos/std/traits.d(6062,9): Error: invalid foreach aggregate cast(ubyte)0u

Is this a bug? How to fix this? Is there an easier way to achieve this?


Solution

  • Hmm, it looks like short circuit evaluation is not working here? It might be a bug, but the workaround is easy enough:

    import std.traits;
    
    template sameUnqualArrays(A, B) {
      static if (isArray!A && isArray!B)
        enum bool sameUnqualArrays =
          is(Unqual!(ForeachType!A) == Unqual!(ForeachType!B));
      else
        enum bool sameUnqualArrays = false;
    }
    
    unittest {
      static assert(sameUnqualArrays!(ubyte[], immutable(ubyte[])));
      static assert(!sameUnqualArrays!(ubyte[], immutable(byte[])));
      static assert(!sameUnqualArrays!(ubyte[], ubyte));
    }