Otherwise, if T is an array type ([basic.compound]) and
remove_all_extents_t<T> is an incomplete type,
ranges::end(E) is ill-formed with no diagnostic required.
Otherwise, if decay-copy(t.end())
is a valid expression whose type models
sentinel_for<iterator_t<T>>
then ranges::end(E) is expression-equivalent to
decay-copy(t.end()).
Otherwise, if T is a class or enumeration type and
decay-copy(end(t))
is a valid expression whose type models
sentinel_for<iterator_t<T>>
with overload resolution performed in a context in which
unqualified lookup for end finds only the declarations