From 097e59ba9a0986998dc867ae83a742d8f7615ff7 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 6 Aug 2022 07:33:51 +0800 Subject: [PATCH] ``: Make `visit` correctly handle conversions to non-movable types (#2971) Co-authored-by: Stephan T. Lavavej Co-authored-by: Casey Carter --- stl/inc/variant | 4 ++-- tests/std/tests/P0088R3_variant/test.cpp | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/stl/inc/variant b/stl/inc/variant index fe298f290..34cfca08e 100644 --- a/stl/inc/variant +++ b/stl/inc/variant @@ -35,8 +35,8 @@ template struct _All_same<_First, _Rest...> : bool_constant...>> {}; // variadic is_same template -struct _Convertible_from_all : bool_constant...>> { - // variadic is_convertible +struct _Convertible_from_all : bool_constant...>> { + // variadic _Invoke_convertible }; template diff --git a/tests/std/tests/P0088R3_variant/test.cpp b/tests/std/tests/P0088R3_variant/test.cpp index decca647d..090ebdd3f 100644 --- a/tests/std/tests/P0088R3_variant/test.cpp +++ b/tests/std/tests/P0088R3_variant/test.cpp @@ -6971,6 +6971,28 @@ namespace msvc { using R = immobile_data; assert(std::visit(std::identity{}, std::variant{13}).x == 13); assert(std::visit(std::identity{}, std::variant{short{42}}).x == 42); + + // Verify that conversions to an object that can't be copied/moved are correctly handled + struct convertible_to_immobile_one { + operator immobile_data() const { + return immobile_data{1729}; + } + }; + + struct convertible_to_immobile_other { + operator immobile_data() const { + return immobile_data{1138}; + } + }; + + using VarTestConv = std::variant; +#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10112408 + assert(std::visit(std::identity{}, VarTestConv{convertible_to_immobile_one{}}).x == 1729); + assert(std::visit(std::identity{}, VarTestConv{convertible_to_immobile_other{}}).x == 1138); +#endif // TRANSITION, DevCom-10112408 + auto immobile_converter = [](auto src) -> immobile_data { return src; }; + assert(std::visit(immobile_converter, VarTestConv{convertible_to_immobile_one{}}).x == 1729); + assert(std::visit(immobile_converter, VarTestConv{convertible_to_immobile_other{}}).x == 1138); } { // Verify that a returned object is not copied/moved/modified