Use signed arithmetic in enumeration helper
With a signed enum and the unsigned step, implicit conversion to unsigned
could change the value in the subtraction operator. Note that errors could
also occur with negative results in pure unsigned operations.
A negative result isn't expected for increasing enumerators, but the boost
iterator implementation does an == comparison that invokes the diff operator
and compares it to 0, and this error actually occurs there in unit tests,
and is caught by UBSAN.
Added some SFINAE to disable accidental instantiation of non-enum
types - before C++ 20 std::underlying_type on a non-enum is undefined.