How to detect a string literal with type_traits?

'decltype("some string")' of a string literal returns "const char (&)[n]" type. Thus, it seems there is more succinct, in comparison with the following answer, way to detect it:

template<typename T>
struct IsStringLiteral :
    std::is_same<
        T,
        std::add_lvalue_reference_t<const char[std::extent_v<std::remove_reference_t<T>>]>
    >
{};

(online demo)

Note: it is possible to create a variable of const char (&)[n] type which will fool this implementation:

const auto &msg1 = "some string";

const char c[4]{};
auto& msg2 = c;

// msg1 and msg2 is recognized by IsStringLiteral as string literals
static_assert(is_string_literal<decltype(msg1)>::value, "");
static_assert(is_string_literal<decltype(msg2)>::value, "");

Here is the best I could get, which appears to reject anything I throw at it, but still accepts literal strings:

#define my_assert(test, message)\
    static_assert(\
        (\
             std::is_convertible      <decltype(message), const char *>::value &&\
            !std::is_rvalue_reference <decltype(message)>::value &&\
            !std::is_pointer          <decltype(message)>::value &&\
            !std::is_array            <decltype(message)>::value &&\
            !std::is_class            <decltype(message)>::value\
        ),\
        "string literal required"\
    );\
    assert((message, (test)))

I'd be very interested to know if this actually is exhaustively correct, and/or if there is a simpler way to do this detection.