Skip to content

Commit 0e85573

Browse files
committed
[libc++] Introduce __forward_as
1 parent d648eed commit 0e85573

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

libcxx/include/__utility/forward_like.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <__config>
1414
#include <__type_traits/conditional.h>
15+
#include <__type_traits/is_base_of.h>
1516
#include <__type_traits/is_const.h>
1617
#include <__type_traits/is_reference.h>
1718
#include <__type_traits/remove_reference.h>
@@ -39,6 +40,22 @@ forward_like(_LIBCPP_LIFETIMEBOUND _Up&& __ux) noexcept -> _ForwardLike<_Tp, _Up
3940
return static_cast<_ForwardLike<_Tp, _Up>>(__ux);
4041
}
4142

43+
// This function is used for `deducing this` cases where you want to make sure the operation is performed on the class
44+
// itself and not on a derived class. For example
45+
// struct S {
46+
// template <class Self>
47+
// void func(Self&& self) {
48+
// // This will always call `do_something` of S instead of any class derived from S.
49+
// std::__forward_as<Self, S>(self).do_something();
50+
// }
51+
// };
52+
template <class _Tp, class _As, class _Up>
53+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _ForwardLike<_Tp, _As>
54+
__forward_as(_LIBCPP_LIFETIMEBOUND _Up&& __val) noexcept {
55+
static_assert(is_base_of_v<_As, remove_reference_t<_Up>>);
56+
return static_cast<_ForwardLike<_Tp, _As>>(__val);
57+
}
58+
4259
#endif // _LIBCPP_STD_VER >= 23
4360

4461
_LIBCPP_END_NAMESPACE_STD

libcxx/include/variant

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,14 +1309,12 @@ public:
13091309

13101310
template <__variant_visit_barrier_tag = __variant_visit_barrier_tag{}, class _Self, class _Visitor>
13111311
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) visit(this _Self&& __self, _Visitor&& __visitor) {
1312-
using _VariantT = _OverrideRef<_Self&&, _CopyConst<remove_reference_t<_Self>, variant>>;
1313-
return std::visit(std::forward<_Visitor>(__visitor), (_VariantT)__self);
1312+
return std::visit(std::forward<_Visitor>(__visitor), std::__forward_as<_Self, variant>(__self));
13141313
}
13151314

13161315
template <class _Rp, class _Self, class _Visitor>
13171316
_LIBCPP_HIDE_FROM_ABI constexpr _Rp visit(this _Self&& __self, _Visitor&& __visitor) {
1318-
using _VariantT = _OverrideRef<_Self&&, _CopyConst<remove_reference_t<_Self>, variant>>;
1319-
return std::visit<_Rp>(std::forward<_Visitor>(__visitor), (_VariantT)__self);
1317+
return std::visit<_Rp>(std::forward<_Visitor>(__visitor), std::__forward_as<_Self, variant>(__self));
13201318
}
13211319
# endif
13221320

0 commit comments

Comments
 (0)