https://bugs.llvm.org/show_bug.cgi?id=45198
The following:
template< typename T, enable_if_t<is_move_assignable<T>::value> = true, enable_if_t<is_move_constructible<T>::value> = true> constexpr void swap(T &lhs, T &rhs) noexcept( is_nothrow_move_constructible<T>::value && is_nothrow_move_assignable<T>::value)
Results in this:
template< typename T, enable_if_t<is_move_assignable<T>::value> = true, enable_if_t<is_move_constructible<T>::value> = true> constexpr void swap(T &lhs, T &rhs) noexcept( is_nothrow_move_constructible<T>::value &&is_nothrow_move_assignable<T>::value)
This is because the && in is_nothrow_move_constructible<T>::value &&is_nothrow_move_assignable<T>::value gets incorrectly determined to be a TT_PointerOrReference
This revision attempts to detect determine a cases where this cannot be true especially in a noexcept context where the result is expected to be boolean
Doesn't this not handle nested templates? For example, noexcept(Foo<Bar<T>>::value && Baz) would not work here. Ditto on expressions like Foo<T1, T2>.
I'm having trouble thinking of a clean generic solution, but the most robust thing I can think of is to search the current line for the previous opening parens and check if noexcept is before it (if they use multiple sets of parens, the other heuristics seem to cover it).