diff options
author | Pedro Alves <pedro@palves.net> | 2020-09-14 21:16:57 +0100 |
---|---|---|
committer | Pedro Alves <pedro@palves.net> | 2020-09-14 22:19:31 +0100 |
commit | 1945192cb9a6184fb805d514ce4ca1bc8999b587 (patch) | |
tree | fecbaf2f67a187989992cf5673b93854f19c1e45 /gdbsupport/valid-expr.h | |
parent | 69896a2cd12e7819a81823430b3ece5a7c9a6973 (diff) | |
download | binutils-gdb-1945192cb9a6184fb805d514ce4ca1bc8999b587.tar.gz |
Rewrite valid-expr.h's internals in terms of the detection idiom (C++17/N4502)
An earlier attempt at doing this had failed (wouldn't work in GCCs
around 4.8, IIRC), but now that I try again, it works. I suspect that
my previous attempt did not use the pre C++14-safe void_t (in
traits.h).
I want to switch to this model because:
- It's the standard detection idiom that folks will learn starting
with C++17.
- In the enum_flags unit tests, I have a static_assert that triggers
a warning (resulting in build error), which GCC does not suppress
because the warning is not being triggered in the SFINAE context.
Switching to the detection idiom fixes that. Alternatively,
switching to the C++03-style expression-validity checking with a
varargs overload would allow addressing that, but I think that
would be going backwards idiomatically speaking.
- While this patch shows a net increase of lines of code, the magic
being added to traits.h can be removed in a few years when we start
requiring C++17.
gdbsupport/ChangeLog:
* traits.h (struct nonesuch, struct detector, detected_or)
(detected_or_t, is_detected, detected_t, detected_or)
(detected_or_t, is_detected_exact, is_detected_convertible): New.
* valid-expr.h (CHECK_VALID_EXPR_INT): Use gdb::is_detected_exact.
Diffstat (limited to 'gdbsupport/valid-expr.h')
-rw-r--r-- | gdbsupport/valid-expr.h | 20 |
1 files changed, 3 insertions, 17 deletions
diff --git a/gdbsupport/valid-expr.h b/gdbsupport/valid-expr.h index b1c84468147..a22fa61134f 100644 --- a/gdbsupport/valid-expr.h +++ b/gdbsupport/valid-expr.h @@ -58,26 +58,12 @@ #define CHECK_VALID_EXPR_INT(TYPENAMES, TYPES, VALID, EXPR_TYPE, EXPR) \ namespace CONCAT (check_valid_expr, __LINE__) { \ \ - template<typename, typename, typename = void> \ - struct is_valid_expression \ - : std::false_type {}; \ - \ template <TYPENAMES> \ - struct is_valid_expression<TYPES, gdb::void_t<decltype (EXPR)>> \ - : std::true_type {}; \ + using archetype = decltype (EXPR); \ \ - static_assert (is_valid_expression<TYPES>::value == VALID, \ + static_assert (gdb::is_detected_exact<EXPR_TYPE, \ + archetype, TYPES>::value == VALID, \ ""); \ - \ - template<TYPENAMES, typename = void> \ - struct is_same_type \ - : std::is_same<EXPR_TYPE, void> {}; \ - \ - template <TYPENAMES> \ - struct is_same_type<TYPES, gdb::void_t<decltype (EXPR)>> \ - : std::is_same<EXPR_TYPE, decltype (EXPR)> {}; \ - \ - static_assert (is_same_type<TYPES>::value, ""); \ } /* namespace */ /* A few convenience macros that support expressions involving a |