[Bug libstdc++/87431] valueless_by_exception() should unconditionally return false if all the constructors are noexcept
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Jan 4 18:02:00 GMT 2019
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87431
--- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Maybe like this:
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -439,7 +439,7 @@ namespace __variant
constexpr bool
_M_valid() const noexcept
{
- if constexpr ((is_scalar_v<_Types> && ...))
+ if constexpr ((is_trivially_copyable_v<_Types> && ...))
return true;
return this->_M_index != __index_type(variant_npos);
}
@@ -1185,6 +1185,23 @@ namespace __variant
{
static_assert(_Np < sizeof...(_Types),
"The index should be in [0, number of alternatives)");
+
+ using type = variant_alternative_t<_Np, variant>;
+ // If constructing the value can throw but move assigning it can't,
+ // construct in a temporary and then move assign from it. This gives
+ // the strong exception safety guarantee, ensuring we never become
+ // valueless.
+ if constexpr (is_trivially_copyable_v<type>
+ && !is_nothrow_constructible_v<type, _Args...>)
+ {
+ // If move assignment cannot throw then we can provide the
+ // strong exception safety guarantee, and never become valueless.
+ variant __tmp(in_place_index<_Np>,
+ std::forward<_Args>(__args)...);
+ *this = std::move(__tmp);
+ return std::get<_Np>(*this);
+ }
+
this->~variant();
__try
{
@@ -1208,6 +1225,20 @@ namespace __variant
{
static_assert(_Np < sizeof...(_Types),
"The index should be in [0, number of alternatives)");
+
+ using type = variant_alternative_t<_Np, variant>;
+ if constexpr (is_trivially_copyable_v<type>
+ && !is_nothrow_constructible_v<type, initializer_list<_Up>,
+ _Args...>)
+ {
+ // If move assignment cannot throw then we can provide the
+ // strong exception safety guarantee, and never become valueless.
+ variant __tmp(in_place_index<_Np>, __il,
+ std::forward<_Args>(__args)...);
+ *this = std::move(__tmp);
+ return std::get<_Np>(*this);
+ }
+
this->~variant();
__try
{
More information about the Gcc-bugs
mailing list