Skip to content

Conversation

@philnik777
Copy link
Contributor

This allows forwarding an object as a specific type. This is usually useful when using deducing this to avoid calling any functions in a deriving class.

@philnik777 philnik777 marked this pull request as ready for review December 12, 2024 16:15
@philnik777 philnik777 requested a review from a team as a code owner December 12, 2024 16:15
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Dec 12, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 12, 2024

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

Changes

This allows forwarding an object as a specific type. This is usually useful when using deducing this to avoid calling any functions in a deriving class.


Full diff: https://github.com/llvm/llvm-project/pull/118168.diff

2 Files Affected:

  • (modified) libcxx/include/__utility/forward_like.h (+8)
  • (modified) libcxx/include/variant (+2-4)
diff --git a/libcxx/include/__utility/forward_like.h b/libcxx/include/__utility/forward_like.h
index 0206ce23a56681..4a3bc240c3d9db 100644
--- a/libcxx/include/__utility/forward_like.h
+++ b/libcxx/include/__utility/forward_like.h
@@ -12,6 +12,7 @@
 
 #include <__config>
 #include <__type_traits/conditional.h>
+#include <__type_traits/is_base_of.h>
 #include <__type_traits/is_const.h>
 #include <__type_traits/is_reference.h>
 #include <__type_traits/remove_reference.h>
@@ -39,6 +40,13 @@ forward_like(_LIBCPP_LIFETIMEBOUND _Up&& __ux) noexcept -> _ForwardLike<_Tp, _Up
   return static_cast<_ForwardLike<_Tp, _Up>>(__ux);
 }
 
+template <class _Tp, class _As, class _Up>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _ForwardLike<_Tp, _As>
+__forward_as(_LIBCPP_LIFETIMEBOUND _Up&& __val) noexcept {
+  static_assert(is_base_of_v<_As, remove_reference_t<_Up>>);
+  return static_cast<_ForwardLike<_Tp, _As>>(__val);
+}
+
 #endif // _LIBCPP_STD_VER >= 23
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/variant b/libcxx/include/variant
index f604527cd22569..7e44ec54141c23 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -1309,14 +1309,12 @@ public:
 
   template <__variant_visit_barrier_tag = __variant_visit_barrier_tag{}, class _Self, class _Visitor>
   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) visit(this _Self&& __self, _Visitor&& __visitor) {
-    using _VariantT = _OverrideRef<_Self&&, _CopyConst<remove_reference_t<_Self>, variant>>;
-    return std::visit(std::forward<_Visitor>(__visitor), (_VariantT)__self);
+    return std::visit(std::forward<_Visitor>(__visitor), std::__forward_as<_Self, variant>(__self));
   }
 
   template <class _Rp, class _Self, class _Visitor>
   _LIBCPP_HIDE_FROM_ABI constexpr _Rp visit(this _Self&& __self, _Visitor&& __visitor) {
-    using _VariantT = _OverrideRef<_Self&&, _CopyConst<remove_reference_t<_Self>, variant>>;
-    return std::visit<_Rp>(std::forward<_Visitor>(__visitor), (_VariantT)__self);
+    return std::visit<_Rp>(std::forward<_Visitor>(__visitor), std::__forward_as<_Self, variant>(__self));
   }
 #  endif
 

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with comment request -- it took a while for it to click for me, so I presume others might benefit from a comment too.

@philnik777 philnik777 merged commit 6157dbe into llvm:main Dec 14, 2024
5 of 11 checks passed
@philnik777 philnik777 deleted the introduce_forward_as branch December 14, 2024 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants