diff --git a/libcxx/include/variant b/libcxx/include/variant --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -1062,21 +1062,28 @@ _VSTD::swap(__lhs, __rhs); } __impl __tmp(_VSTD::move(*__rhs)); -#ifndef _LIBCPP_NO_EXCEPTIONS - // EXTENSION: When the move construction of `__lhs` into `__rhs` throws - // and `__tmp` is nothrow move constructible then we move `__tmp` back - // into `__rhs` and provide the strong exception safety guarantee. - try { + static constexpr bool __is_noexcept = +#ifdef _LIBCPP_NO_EXCEPTIONS + true; +#else + __all<(is_nothrow_move_constructible_v<_Types> && + is_nothrow_swappable_v<_Types>)...>::value; +#endif + if constexpr (__is_noexcept) { this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); - } catch (...) { - if (__tmp.__move_nothrow()) { - this->__generic_construct(*__rhs, _VSTD::move(__tmp)); + } else { + // EXTENSION: When the move construction of `__lhs` into `__rhs` throws + // and `__tmp` is nothrow move constructible then we move `__tmp` back + // into `__rhs` and provide the strong exception safety guarantee. + try { + this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); + } catch (...) { + if (__tmp.__move_nothrow()) { + this->__generic_construct(*__rhs, _VSTD::move(__tmp)); + } + throw; } - throw; } -#else - this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); -#endif this->__generic_construct(*__lhs, _VSTD::move(__tmp)); } }