Skip to content

[libc++] Introduce __forward_as #118168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 14, 2024
Merged

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