Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions stl/inc/utility
Original file line number Diff line number Diff line change
Expand Up @@ -820,9 +820,8 @@ _NODISCARD constexpr underlying_type_t<_Ty> to_underlying(_Ty _Value) noexcept {
}

template <class _Ty, class _Uty>
constexpr auto&& forward_like(_Uty&& _Ux) noexcept {
static_assert(
_Can_reference<_Ty>, "The first template parameter of std::forward_like must be a referenceable type.");
_NODISCARD constexpr auto&& forward_like(_Uty&& _Ux) noexcept {
static_assert(_Can_reference<_Ty>, "std::forward_like's first template argument must be a referenceable type.");

using _UnrefU = remove_reference_t<_Uty>;
if constexpr (is_lvalue_reference_v<_Ty>) {
Expand Down
136 changes: 89 additions & 47 deletions tests/std/tests/P2445R1_forward_like/test.compile.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,52 +27,94 @@ constexpr owner_type owner_c{};
constexpr const owner_type& owner_clref = owner_c;
constexpr const owner_type&& owner_crref = move(owner_c);

static_assert(is_same_v<decltype(forward_like<decltype(owner)>(owner.m_mutobj)), int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner)>(owner.m_mutlref)), int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner)>(owner.m_mutrref)), int&&>);

static_assert(is_same_v<decltype(forward_like<decltype(owner)>(owner.m_cobj)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner)>(owner.m_clref)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner)>(owner.m_crref)), const int&&>);

static_assert(is_same_v<decltype(forward_like<decltype(owner_lref)>(owner_lref.m_mutobj)), int&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_lref)>(owner_lref.m_mutlref)), int&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_lref)>(owner_lref.m_mutrref)), int&>);

static_assert(is_same_v<decltype(forward_like<decltype(owner_lref)>(owner_lref.m_cobj)), const int&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_lref)>(owner_lref.m_clref)), const int&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_lref)>(owner_lref.m_crref)), const int&>);

static_assert(is_same_v<decltype(forward_like<decltype(owner_rref)>(owner_rref.m_mutobj)), int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_rref)>(owner_rref.m_mutlref)), int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_rref)>(owner_rref.m_mutrref)), int&&>);

static_assert(is_same_v<decltype(forward_like<decltype(owner_rref)>(owner_rref.m_cobj)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_rref)>(owner_rref.m_clref)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_rref)>(owner_rref.m_crref)), const int&&>);

static_assert(is_same_v<decltype(forward_like<decltype(owner_c)>(owner_c.m_mutobj)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_c)>(owner_c.m_mutlref)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_c)>(owner_c.m_mutrref)), const int&&>);

static_assert(is_same_v<decltype(forward_like<decltype(owner_c)>(owner_c.m_cobj)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_c)>(owner_c.m_clref)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_c)>(owner_c.m_crref)), const int&&>);

static_assert(is_same_v<decltype(forward_like<decltype(owner_clref)>(owner_clref.m_mutobj)), const int&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_clref)>(owner_clref.m_mutlref)), const int&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_clref)>(owner_clref.m_mutrref)), const int&>);

static_assert(is_same_v<decltype(forward_like<decltype(owner_clref)>(owner_clref.m_cobj)), const int&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_clref)>(owner_clref.m_clref)), const int&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_clref)>(owner_clref.m_crref)), const int&>);

static_assert(is_same_v<decltype(forward_like<decltype(owner_crref)>(owner_crref.m_mutobj)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_crref)>(owner_crref.m_mutlref)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_crref)>(owner_crref.m_mutrref)), const int&&>);

static_assert(is_same_v<decltype(forward_like<decltype(owner_crref)>(owner_crref.m_cobj)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_crref)>(owner_crref.m_clref)), const int&&>);
static_assert(is_same_v<decltype(forward_like<decltype(owner_crref)>(owner_crref.m_crref)), const int&&>);
using owner_t = decltype(owner);
using mutobj_from_owner_t = decltype(forward_like<owner_t>(owner.m_mutobj));
using mutlref_from_owner_t = decltype(forward_like<owner_t>(owner.m_mutlref));
using mutrref_from_owner_t = decltype(forward_like<owner_t>(owner.m_mutrref));
using cobj_from_owner_t = decltype(forward_like<owner_t>(owner.m_cobj));
using clref_from_owner_t = decltype(forward_like<owner_t>(owner.m_clref));
using crref_from_owner_t = decltype(forward_like<owner_t>(owner.m_crref));

static_assert(is_same_v<mutobj_from_owner_t, int&&>);
static_assert(is_same_v<mutlref_from_owner_t, int&&>);
static_assert(is_same_v<mutrref_from_owner_t, int&&>);
static_assert(is_same_v<cobj_from_owner_t, const int&&>);
static_assert(is_same_v<clref_from_owner_t, const int&&>);
static_assert(is_same_v<crref_from_owner_t, const int&&>);

using owner_lref_t = decltype(owner_lref);
using mutobj_from_owner_lref_t = decltype(forward_like<owner_lref_t>(owner_lref.m_mutobj));
using mutlref_from_owner_lref_t = decltype(forward_like<owner_lref_t>(owner_lref.m_mutlref));
using mutrref_from_owner_lref_t = decltype(forward_like<owner_lref_t>(owner_lref.m_mutrref));
using cobj_from_owner_lref_t = decltype(forward_like<owner_lref_t>(owner_lref.m_cobj));
using clref_from_owner_lref_t = decltype(forward_like<owner_lref_t>(owner_lref.m_clref));
using crref_from_owner_lref_t = decltype(forward_like<owner_lref_t>(owner_lref.m_crref));

static_assert(is_same_v<mutobj_from_owner_lref_t, int&>);
static_assert(is_same_v<mutlref_from_owner_lref_t, int&>);
static_assert(is_same_v<mutrref_from_owner_lref_t, int&>);
static_assert(is_same_v<cobj_from_owner_lref_t, const int&>);
static_assert(is_same_v<clref_from_owner_lref_t, const int&>);
static_assert(is_same_v<crref_from_owner_lref_t, const int&>);

using owner_rref_t = decltype(owner_rref);
using mutobj_from_owner_rref_t = decltype(forward_like<owner_rref_t>(owner_rref.m_mutobj));
using mutlref_from_owner_rref_t = decltype(forward_like<owner_rref_t>(owner_rref.m_mutlref));
using mutrref_from_owner_rref_t = decltype(forward_like<owner_rref_t>(owner_rref.m_mutrref));
using cobj_from_owner_rref_t = decltype(forward_like<owner_rref_t>(owner_rref.m_cobj));
using clref_from_owner_rref_t = decltype(forward_like<owner_rref_t>(owner_rref.m_clref));
using crref_from_owner_rref_t = decltype(forward_like<owner_rref_t>(owner_rref.m_crref));

static_assert(is_same_v<mutobj_from_owner_rref_t, int&&>);
static_assert(is_same_v<mutlref_from_owner_rref_t, int&&>);
static_assert(is_same_v<mutrref_from_owner_rref_t, int&&>);
static_assert(is_same_v<cobj_from_owner_rref_t, const int&&>);
static_assert(is_same_v<clref_from_owner_rref_t, const int&&>);
static_assert(is_same_v<crref_from_owner_rref_t, const int&&>);

using owner_c_t = decltype(owner_c);
using mutobj_from_owner_c_t = decltype(forward_like<owner_c_t>(owner_c.m_mutobj));
using mutlref_from_owner_c_t = decltype(forward_like<owner_c_t>(owner_c.m_mutlref));
using mutrref_from_owner_c_t = decltype(forward_like<owner_c_t>(owner_c.m_mutrref));
using cobj_from_owner_c_t = decltype(forward_like<owner_c_t>(owner_c.m_cobj));
using clref_from_owner_c_t = decltype(forward_like<owner_c_t>(owner_c.m_clref));
using crref_from_owner_c_t = decltype(forward_like<owner_c_t>(owner_c.m_crref));

static_assert(is_same_v<mutobj_from_owner_c_t, const int&&>);
static_assert(is_same_v<mutlref_from_owner_c_t, const int&&>);
static_assert(is_same_v<mutrref_from_owner_c_t, const int&&>);
static_assert(is_same_v<cobj_from_owner_c_t, const int&&>);
static_assert(is_same_v<clref_from_owner_c_t, const int&&>);
static_assert(is_same_v<crref_from_owner_c_t, const int&&>);

using owner_clref_t = decltype(owner_clref);
using mutobj_from_owner_clref_t = decltype(forward_like<owner_clref_t>(owner_clref.m_mutobj));
using mutlref_from_owner_clref_t = decltype(forward_like<owner_clref_t>(owner_clref.m_mutlref));
using mutrref_from_owner_clref_t = decltype(forward_like<owner_clref_t>(owner_clref.m_mutrref));
using cobj_from_owner_clref_t = decltype(forward_like<owner_clref_t>(owner_clref.m_cobj));
using clref_from_owner_clref_t = decltype(forward_like<owner_clref_t>(owner_clref.m_clref));
using crref_from_owner_clref_t = decltype(forward_like<owner_clref_t>(owner_clref.m_crref));

static_assert(is_same_v<mutobj_from_owner_clref_t, const int&>);
static_assert(is_same_v<mutlref_from_owner_clref_t, const int&>);
static_assert(is_same_v<mutrref_from_owner_clref_t, const int&>);
static_assert(is_same_v<cobj_from_owner_clref_t, const int&>);
static_assert(is_same_v<clref_from_owner_clref_t, const int&>);
static_assert(is_same_v<crref_from_owner_clref_t, const int&>);

using owner_crref_t = decltype(owner_crref);
using mutobj_from_owner_crref_t = decltype(forward_like<owner_crref_t>(owner_crref.m_mutobj));
using mutlref_from_owner_crref_t = decltype(forward_like<owner_crref_t>(owner_crref.m_mutlref));
using mutrref_from_owner_crref_t = decltype(forward_like<owner_crref_t>(owner_crref.m_mutrref));
using cobj_from_owner_crref_t = decltype(forward_like<owner_crref_t>(owner_crref.m_cobj));
using clref_from_owner_crref_t = decltype(forward_like<owner_crref_t>(owner_crref.m_clref));
using crref_from_owner_crref_t = decltype(forward_like<owner_crref_t>(owner_crref.m_crref));

static_assert(is_same_v<mutobj_from_owner_crref_t, const int&&>);
static_assert(is_same_v<mutlref_from_owner_crref_t, const int&&>);
static_assert(is_same_v<mutrref_from_owner_crref_t, const int&&>);
static_assert(is_same_v<cobj_from_owner_crref_t, const int&&>);
static_assert(is_same_v<clref_from_owner_crref_t, const int&&>);
static_assert(is_same_v<crref_from_owner_crref_t, const int&&>);

int main() {} // COMPILE-ONLY