[compiler-rt] [flang] [clang-tools-extra] [llvm] [libc] [lldb] [libcxx] [clang] [libc++][variant] P2637R3: Member `visit` (PR #76447)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 27 08:31:24 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Hristo Hristov (H-G-Hristov)
<details>
<summary>Changes</summary>
Implements parts of: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2637r3.html (https://eel.is/c++draft/variant.visit)
Adds member `visit` tests and (NFC) refactors + reformats the non-member `visit` tests to accomodate the member `visit` additions for consistency.
---
Patch is 70.62 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/76447.diff
7 Files Affected:
- (modified) libcxx/docs/Status/Cxx2c.rst (+2)
- (modified) libcxx/docs/Status/Cxx2cPapers.csv (+1-1)
- (modified) libcxx/include/variant (+34)
- (modified) libcxx/test/std/utilities/variant/variant.visit/robust_against_adl.pass.cpp (+37-16)
- (modified) libcxx/test/std/utilities/variant/variant.visit/visit.pass.cpp (+428-178)
- (modified) libcxx/test/std/utilities/variant/variant.visit/visit_return_type.pass.cpp (+545-223)
- (modified) libcxx/utils/generate_feature_test_macro_components.py (+5-1)
``````````diff
diff --git a/libcxx/docs/Status/Cxx2c.rst b/libcxx/docs/Status/Cxx2c.rst
index a7ebc4662f517c..5c700d2cb0d6d3 100644
--- a/libcxx/docs/Status/Cxx2c.rst
+++ b/libcxx/docs/Status/Cxx2c.rst
@@ -40,6 +40,8 @@ Paper Status
.. note::
.. [#note-P2510R3] This paper is applied as DR against C++20. (MSVC STL and libstdc++ will do the same.)
+ .. [#note-P2637R3] P2637R3: Implemented `variant` member `visit`
+
.. _issues-status-cxx2c:
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index ff83648aa76830..a3214ab2bfe75c 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -17,7 +17,7 @@
"`P0792R14 <https://wg21.link/P0792R14>`__","LWG","``function_ref``: a type-erased callable reference","Varna June 2023","","",""
"`P2874R2 <https://wg21.link/P2874R2>`__","LWG","Mandating Annex D Require No More","Varna June 2023","","",""
"`P2757R3 <https://wg21.link/P2757R3>`__","LWG","Type-checking format args","Varna June 2023","","","|format|"
-"`P2637R3 <https://wg21.link/P2637R3>`__","LWG","Member ``visit``","Varna June 2023","","","|format|"
+"`P2637R3 <https://wg21.link/P2637R3>`__","LWG","Member ``visit``","Varna June 2023","|Partial| [#note-P2637R3]","18.0",""
"`P2641R4 <https://wg21.link/P2641R4>`__","CWG, LWG","Checking if a ``union`` alternative is active","Varna June 2023","","",""
"`P1759R6 <https://wg21.link/P1759R6>`__","LWG","Native handles and file streams","Varna June 2023","","",""
"`P2697R1 <https://wg21.link/P2697R1>`__","LWG","Interfacing ``bitset`` with ``string_view``","Varna June 2023","|Complete|","18.0",""
diff --git a/libcxx/include/variant b/libcxx/include/variant
index 6179b2a1a0ab61..4c9b04942f2779 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -69,6 +69,12 @@ namespace std {
// 20.7.2.6, swap
void swap(variant&) noexcept(see below);
+
+ // [variant.visit], visitation
+ template<class Self, class Visitor>
+ constexpr decltype(auto) visit(this Self&&, Visitor&&);
+ template<class R, class Self, class Visitor>
+ constexpr R visit(this Self&&, Visitor&&);
};
// 20.7.3, variant helper classes
@@ -235,6 +241,7 @@ namespace std {
#include <__type_traits/void_t.h>
#include <__utility/declval.h>
#include <__utility/forward.h>
+#include <__utility/forward_like.h>
#include <__utility/in_place.h>
#include <__utility/move.h>
#include <__utility/swap.h>
@@ -1273,6 +1280,15 @@ public:
__impl_.__swap(__that.__impl_);
}
+# if _LIBCPP_STD_VER >= 26
+ // [variant.visit], visitation
+ template <int=0, class _Self, class _Visitor>
+ constexpr decltype(auto) visit(this _Self&& __self, _Visitor&& __visitor);
+
+ template <class _R, class _Self, class _Visitor>
+ constexpr _R visit(this _Self&& __self, _Visitor&& __visitor);
+# endif
+
private:
__variant_detail::__impl<_Types...> __impl_;
@@ -1532,6 +1548,24 @@ visit(_Visitor&& __visitor, _Vs&&... __vs) {
}
# endif
+# if _LIBCPP_STD_VER >= 26
+// [variant.visit], visitation
+
+template <class... _Types>
+template <int, class _Self, class _Visitor>
+constexpr decltype(auto) variant<_Types...>::visit(this _Self&& __self, _Visitor&& __visitor) {
+ using _V = _OverrideRef<_Self&&, _CopyConst<remove_reference_t<_Self>, variant>>;
+ return std::visit(std::forward<_Visitor>(__visitor), (_V)__self);
+}
+
+template <class... _Types>
+template <class _Rp, class _Self, class _Visitor>
+constexpr _Rp variant<_Types...>::visit(this _Self&& __self, _Visitor&& __visitor) {
+ using _V = _OverrideRef<_Self&&, _CopyConst<remove_reference_t<_Self>, variant>>;
+ return std::visit<_Rp>(std::forward<_Visitor>(__visitor), (_V)__self);
+}
+# endif
+
template <class... _Types>
_LIBCPP_HIDE_FROM_ABI auto
swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs)))
diff --git a/libcxx/test/std/utilities/variant/variant.visit/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/variant/variant.visit/robust_against_adl.pass.cpp
index 6f17fa32648d41..3bd305a7c62c17 100644
--- a/libcxx/test/std/utilities/variant/variant.visit/robust_against_adl.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.visit/robust_against_adl.pass.cpp
@@ -9,6 +9,13 @@
// UNSUPPORTED: c++03, c++11, c++14
// <variant>
+
+// class variant;
+// template<class Self, class Visitor>
+// constexpr decltype(auto) visit(this Self&&, Visitor&&); // since C++26
+// template<class R, class Self, class Visitor>
+// constexpr R visit(this Self&&, Visitor&&); // since C++26
+
// template <class Visitor, class... Variants>
// constexpr see below visit(Visitor&& vis, Variants&&... vars);
@@ -17,27 +24,41 @@
#include "test_macros.h"
struct Incomplete;
-template<class T> struct Holder { T t; };
-
-constexpr bool test(bool do_it)
-{
- if (do_it) {
- std::variant<Holder<Incomplete>*, int> v = nullptr;
- std::visit([](auto){}, v);
- std::visit([](auto) -> Holder<Incomplete>* { return nullptr; }, v);
+template <class T>
+struct Holder {
+ T t;
+};
+
+constexpr bool test(bool do_it) {
+ if (do_it) {
+ std::variant<Holder<Incomplete>*, int> v = nullptr;
+
+#if _LIBCPP_STD_VER >= 26
+ // member
+ {
+ v.visit([](auto) {});
+ v.visit([](auto) -> Holder<Incomplete>* { return nullptr; });
+ v.visit<void>([](auto) {});
+ v.visit<void*>([](auto) -> Holder<Incomplete>* { return nullptr; });
+ }
+#endif
+ // non-member
+ {
+ std::visit([](auto) {}, v);
+ std::visit([](auto) -> Holder<Incomplete>* { return nullptr; }, v);
#if TEST_STD_VER > 17
- std::visit<void>([](auto){}, v);
- std::visit<void*>([](auto) -> Holder<Incomplete>* { return nullptr; }, v);
+ std::visit<void>([](auto) {}, v);
+ std::visit<void*>([](auto) -> Holder<Incomplete>* { return nullptr; }, v);
#endif
}
- return true;
+ }
+ return true;
}
-int main(int, char**)
-{
- test(true);
+int main(int, char**) {
+ test(true);
#if TEST_STD_VER > 17
- static_assert(test(true));
+ static_assert(test(true));
#endif
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/utilities/variant/variant.visit/visit.pass.cpp b/libcxx/test/std/utilities/variant/variant.visit/visit.pass.cpp
index 097b784f2bf2ce..8781174ff7d669 100644
--- a/libcxx/test/std/utilities/variant/variant.visit/visit.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.visit/visit.pass.cpp
@@ -9,6 +9,11 @@
// UNSUPPORTED: c++03, c++11, c++14
// <variant>
+
+// class variant;
+// template<class Self, class Visitor>
+// constexpr decltype(auto) visit(this Self&&, Visitor&&); // since C++26
+
// template <class Visitor, class... Variants>
// constexpr see below visit(Visitor&& vis, Variants&&... vars);
@@ -25,299 +30,503 @@
void test_call_operator_forwarding() {
using Fn = ForwardingCallObject;
Fn obj{};
- const Fn &cobj = obj;
+ const Fn& cobj = obj;
+
{ // test call operator forwarding - no variant
- std::visit(obj);
- assert(Fn::check_call<>(CT_NonConst | CT_LValue));
- std::visit(cobj);
- assert(Fn::check_call<>(CT_Const | CT_LValue));
- std::visit(std::move(obj));
- assert(Fn::check_call<>(CT_NonConst | CT_RValue));
- std::visit(std::move(cobj));
- assert(Fn::check_call<>(CT_Const | CT_RValue));
+ // non-member
+ {
+ std::visit(obj);
+ assert(Fn::check_call<>(CT_NonConst | CT_LValue));
+ std::visit(cobj);
+ assert(Fn::check_call<>(CT_Const | CT_LValue));
+ std::visit(std::move(obj));
+ assert(Fn::check_call<>(CT_NonConst | CT_RValue));
+ std::visit(std::move(cobj));
+ assert(Fn::check_call<>(CT_Const | CT_RValue));
+ }
}
{ // test call operator forwarding - single variant, single arg
using V = std::variant<int>;
V v(42);
- std::visit(obj, v);
- assert(Fn::check_call<int &>(CT_NonConst | CT_LValue));
- std::visit(cobj, v);
- assert(Fn::check_call<int &>(CT_Const | CT_LValue));
- std::visit(std::move(obj), v);
- assert(Fn::check_call<int &>(CT_NonConst | CT_RValue));
- std::visit(std::move(cobj), v);
- assert(Fn::check_call<int &>(CT_Const | CT_RValue));
+
+#if _LIBCPP_STD_VER >= 26
+ // member
+ {
+ v.visit(obj);
+ assert(Fn::check_call<int&>(CT_NonConst | CT_LValue));
+ v.visit(cobj);
+ assert(Fn::check_call<int&>(CT_Const | CT_LValue));
+ v.visit(std::move(obj));
+ assert(Fn::check_call<int&>(CT_NonConst | CT_RValue));
+ v.visit(std::move(cobj));
+ assert(Fn::check_call<int&>(CT_Const | CT_RValue));
+ }
+#endif
+ // non-member
+ {
+ std::visit(obj, v);
+ assert(Fn::check_call<int&>(CT_NonConst | CT_LValue));
+ std::visit(cobj, v);
+ assert(Fn::check_call<int&>(CT_Const | CT_LValue));
+ std::visit(std::move(obj), v);
+ assert(Fn::check_call<int&>(CT_NonConst | CT_RValue));
+ std::visit(std::move(cobj), v);
+ assert(Fn::check_call<int&>(CT_Const | CT_RValue));
+ }
}
{ // test call operator forwarding - single variant, multi arg
using V = std::variant<int, long, double>;
- V v(42l);
- std::visit(obj, v);
- assert(Fn::check_call<long &>(CT_NonConst | CT_LValue));
- std::visit(cobj, v);
- assert(Fn::check_call<long &>(CT_Const | CT_LValue));
- std::visit(std::move(obj), v);
- assert(Fn::check_call<long &>(CT_NonConst | CT_RValue));
- std::visit(std::move(cobj), v);
- assert(Fn::check_call<long &>(CT_Const | CT_RValue));
+ V v(42L);
+
+#if _LIBCPP_STD_VER >= 26
+ // member
+ {
+ v.visit(obj);
+ assert(Fn::check_call<long&>(CT_NonConst | CT_LValue));
+ v.visit(cobj);
+ assert(Fn::check_call<long&>(CT_Const | CT_LValue));
+ v.visit(std::move(obj));
+ assert(Fn::check_call<long&>(CT_NonConst | CT_RValue));
+ v.visit(std::move(cobj));
+ assert(Fn::check_call<long&>(CT_Const | CT_RValue));
+ }
+#endif
+ // non-member
+ {
+ std::visit(obj, v);
+ assert(Fn::check_call<long&>(CT_NonConst | CT_LValue));
+ std::visit(cobj, v);
+ assert(Fn::check_call<long&>(CT_Const | CT_LValue));
+ std::visit(std::move(obj), v);
+ assert(Fn::check_call<long&>(CT_NonConst | CT_RValue));
+ std::visit(std::move(cobj), v);
+ assert(Fn::check_call<long&>(CT_Const | CT_RValue));
+ }
}
{ // test call operator forwarding - multi variant, multi arg
- using V = std::variant<int, long, double>;
- using V2 = std::variant<int *, std::string>;
- V v(42l);
+ using V = std::variant<int, long, double>;
+ using V2 = std::variant<int*, std::string>;
+ V v(42L);
V2 v2("hello");
- std::visit(obj, v, v2);
- assert((Fn::check_call<long &, std::string &>(CT_NonConst | CT_LValue)));
- std::visit(cobj, v, v2);
- assert((Fn::check_call<long &, std::string &>(CT_Const | CT_LValue)));
- std::visit(std::move(obj), v, v2);
- assert((Fn::check_call<long &, std::string &>(CT_NonConst | CT_RValue)));
- std::visit(std::move(cobj), v, v2);
- assert((Fn::check_call<long &, std::string &>(CT_Const | CT_RValue)));
+
+ // non-member
+ {
+ std::visit(obj, v, v2);
+ assert((Fn::check_call<long&, std::string&>(CT_NonConst | CT_LValue)));
+ std::visit(cobj, v, v2);
+ assert((Fn::check_call<long&, std::string&>(CT_Const | CT_LValue)));
+ std::visit(std::move(obj), v, v2);
+ assert((Fn::check_call<long&, std::string&>(CT_NonConst | CT_RValue)));
+ std::visit(std::move(cobj), v, v2);
+ assert((Fn::check_call<long&, std::string&>(CT_Const | CT_RValue)));
+ }
}
{
using V = std::variant<int, long, double, std::string>;
- V v1(42l), v2("hello"), v3(101), v4(1.1);
- std::visit(obj, v1, v2, v3, v4);
- assert((Fn::check_call<long &, std::string &, int &, double &>(CT_NonConst | CT_LValue)));
- std::visit(cobj, v1, v2, v3, v4);
- assert((Fn::check_call<long &, std::string &, int &, double &>(CT_Const | CT_LValue)));
- std::visit(std::move(obj), v1, v2, v3, v4);
- assert((Fn::check_call<long &, std::string &, int &, double &>(CT_NonConst | CT_RValue)));
- std::visit(std::move(cobj), v1, v2, v3, v4);
- assert((Fn::check_call<long &, std::string &, int &, double &>(CT_Const | CT_RValue)));
+ V v1(42L), v2("hello"), v3(101), v4(1.1);
+
+ // non-member
+ {
+ std::visit(obj, v1, v2, v3, v4);
+ assert((Fn::check_call<long&, std::string&, int&, double&>(CT_NonConst | CT_LValue)));
+ std::visit(cobj, v1, v2, v3, v4);
+ assert((Fn::check_call<long&, std::string&, int&, double&>(CT_Const | CT_LValue)));
+ std::visit(std::move(obj), v1, v2, v3, v4);
+ assert((Fn::check_call<long&, std::string&, int&, double&>(CT_NonConst | CT_RValue)));
+ std::visit(std::move(cobj), v1, v2, v3, v4);
+ assert((Fn::check_call<long&, std::string&, int&, double&>(CT_Const | CT_RValue)));
+ }
}
{
using V = std::variant<int, long, double, int*, std::string>;
- V v1(42l), v2("hello"), v3(nullptr), v4(1.1);
- std::visit(obj, v1, v2, v3, v4);
- assert((Fn::check_call<long &, std::string &, int *&, double &>(CT_NonConst | CT_LValue)));
- std::visit(cobj, v1, v2, v3, v4);
- assert((Fn::check_call<long &, std::string &, int *&, double &>(CT_Const | CT_LValue)));
- std::visit(std::move(obj), v1, v2, v3, v4);
- assert((Fn::check_call<long &, std::string &, int *&, double &>(CT_NonConst | CT_RValue)));
- std::visit(std::move(cobj), v1, v2, v3, v4);
- assert((Fn::check_call<long &, std::string &, int *&, double &>(CT_Const | CT_RValue)));
+ V v1(42L), v2("hello"), v3(nullptr), v4(1.1);
+
+ // non-member
+ {
+ std::visit(obj, v1, v2, v3, v4);
+ assert((Fn::check_call<long&, std::string&, int*&, double&>(CT_NonConst | CT_LValue)));
+ std::visit(cobj, v1, v2, v3, v4);
+ assert((Fn::check_call<long&, std::string&, int*&, double&>(CT_Const | CT_LValue)));
+ std::visit(std::move(obj), v1, v2, v3, v4);
+ assert((Fn::check_call<long&, std::string&, int*&, double&>(CT_NonConst | CT_RValue)));
+ std::visit(std::move(cobj), v1, v2, v3, v4);
+ assert((Fn::check_call<long&, std::string&, int*&, double&>(CT_Const | CT_RValue)));
+ }
}
}
+// Applies to non-member `std::visit` only.
void test_argument_forwarding() {
using Fn = ForwardingCallObject;
Fn obj{};
- const auto Val = CT_LValue | CT_NonConst;
+ const auto val = CT_LValue | CT_NonConst;
+
{ // single argument - value type
using V = std::variant<int>;
V v(42);
- const V &cv = v;
- std::visit(obj, v);
- assert(Fn::check_call<int &>(Val));
- std::visit(obj, cv);
- assert(Fn::check_call<const int &>(Val));
- std::visit(obj, std::move(v));
- assert(Fn::check_call<int &&>(Val));
- std::visit(obj, std::move(cv));
- assert(Fn::check_call<const int &&>(Val));
+ const V& cv = v;
+
+#if _LIBCPP_STD_VER >= 26
+ // member
+ {
+ v.visit(obj);
+ assert(Fn::check_call<int&>(val));
+ cv.visit(obj);
+ assert(Fn::check_call<const int&>(val));
+ std::move(v).visit(obj);
+ assert(Fn::check_call<int&&>(val));
+ std::move(cv).visit(obj);
+ assert(Fn::check_call<const int&&>(val));
+ }
+#endif
+ // non-member
+ {
+ std::visit(obj, v);
+ assert(Fn::check_call<int&>(val));
+ std::visit(obj, cv);
+ assert(Fn::check_call<const int&>(val));
+ std::visit(obj, std::move(v));
+ assert(Fn::check_call<int&&>(val));
+ std::visit(obj, std::move(cv));
+ assert(Fn::check_call<const int&&>(val));
+ }
}
#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
{ // single argument - lvalue reference
- using V = std::variant<int &>;
- int x = 42;
+ using V = std::variant<int&>;
+ int x = 42;
V v(x);
- const V &cv = v;
- std::visit(obj, v);
- assert(Fn::check_call<int &>(Val));
- std::visit(obj, cv);
- assert(Fn::check_call<int &>(Val));
- std::visit(obj, std::move(v));
- assert(Fn::check_call<int &>(Val));
- std::visit(obj, std::move(cv));
- assert(Fn::check_call<int &>(Val));
+ const V& cv = v;
+
+# if _LIBCPP_STD_VER >= 26
+ // member
+ {
+ v.visit(obj);
+ assert(Fn::check_call<int&>(val));
+ cv.visit(obj);
+ assert(Fn::check_call<int&>(val));
+ std::move(v).visit(obj);
+ assert(Fn::check_call<int&>(val));
+ std::move(cv).visit(obj);
+ assert(Fn::check_call<int&>(val));
+ assert(false);
+ }
+# endif
+ // non-member
+ {
+ std::visit(obj, v);
+ assert(Fn::check_call<int&>(val));
+ std::visit(obj, cv);
+ assert(Fn::check_call<int&>(val));
+ std::visit(obj, std::move(v));
+ assert(Fn::check_call<int&>(val));
+ std::visit(obj, std::move(cv));
+ assert(Fn::check_call<int&>(val));
+ }
}
{ // single argument - rvalue reference
- using V = std::variant<int &&>;
- int x = 42;
+ using V = std::variant<int&&>;
+ int x = 42;
V v(std::move(x));
- const V &cv = v;
- std::visit(obj, v);
- assert(Fn::check_call<int &>(Val));
- std::visit(obj, cv);
- assert(Fn::check_call<int &>(Val));
- std::visit(obj, std::move(v));
- assert(Fn::check_call<int &&>(Val));
- std::visit(obj, std::move(cv));
- assert(Fn::check_call<int &&>(Val));
+ const V& cv = v;
+
+# if _LIBCPP_STD_VER >= 26
+ // member
+ {
+ v.visit(obj);
+ assert(Fn::check_call<int&>(val));
+ cvstd::visit(obj);
+ assert(Fn::check_call<int&>(val));
+ std::move(v).visit(obj);
+ assert(Fn::check_call<int&&>(val));
+ std::move(cv).visit(obj);
+ assert(Fn::check_call<int&&>(val));
+ }
+# endif
+ // non-member
+ {
+ std::visit(obj, v);
+ assert(Fn::check_call<int&>(val));
+ std::visit(obj, cv);
+ assert(Fn::check_call<int&>(val));
+ std::visit(obj, std::move(v));
+ assert(Fn::check_call<int&&>(val));
+ std::visit(obj, std::move(cv));
+ assert(Fn::check_call<int&&>(val));
+ }
}
#endif
{ // multi argument - multi variant
using V = std::variant<int, std::string, long>;
- V v1(42), v2("hello"), v3(43l);
- std::visit(obj, v1, v2, v3);
- assert((Fn::check_call<int &, std::string &, long &>(Val)));
- std::visit(obj, std::as_const(v1), std::as_const(v2), std::move(v3));
- assert((Fn::check_call<const int &, const std::string &, long &&>(Val)));
+ V v1(42), v2("hello"), v3(43L);
+
+ // non-member
+ {
+ std::visit(obj, v1, v2, v3);
+ assert((Fn::check_call<int&, std::string&, long&>(val)));
+ std::visit(obj, std::as_const(v1), std::as_const(v2), std::move(v3));
+ assert((Fn::check_call<const int&, const std::string&, long&&>(val)));
+ }
}
{
using V = std::variant<int, long, double, std::string>;
- V v1(42l), v2("hello"), v3(101), v4(1.1);
- std::visit(obj, v1, v2, v3, v4);
- assert((Fn::check_call<long &, std::string &, int &, double &>(Val)));
- std::visit(obj, std::as_const(v1), std::as_const(v2), std::move(v3), std::move(v4));
- assert((Fn::check_call<const long &, const std::string &, int &&, double &&>(Val)));
+ V v1(42L), v2("hello"), v3(101), v4(1.1);
+
+ // non-member
+ {
+ std::visit(obj, v1, v2, v3, v4);
+ assert((Fn::check_call<long&, std::string&, int&, double&>(val)));
+ std::visit(obj, std::as_const(v1), std::as_const(v2), std::move(v3), std::move(v4));
+ assert((Fn::check_call<const long&, const std::string&, int&&, double&&>(val)));
+ }
}
{
using V = std::variant<int, long, double, int*, std::string>;
- V v1(42l), v2("hello"), v3(nullptr), v4(1.1);
- std::visit(obj, v1, v2, v3, v4);
- assert((Fn::check_call<long &, std::string &, int *&, double &>(Val)));
- std::visit(obj, std::as_const(v1), std::as_const(v2), std::move(v3), std::move(v4));
- assert((Fn::check_call<const long &, const std::string &, int *&&, double &&>(Val)));
+ V v1(42L), v2("hello"), v3(nullptr), v4(1.1);
+
+ // non-member
+ {
+ std::visit(obj, v1, v2, v3, v4);
+ assert((Fn::check_call<long&, std::string&, int*&, double&>(val)));
+ std::visit(obj, std::as_const(v1), std::as_const(v2), std::move(v3), std::move(v4));
+ assert((Fn::check_call<const long&, const std::string&, int*&&, double&&>(val)));
+ }
}
}
void test_return_type() {
using Fn = ForwardingCallObject;
Fn o...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/76447
More information about the cfe-commits
mailing list