1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
14 #include <type_traits>
17 struct U
{}; // class type so const-qualification is not stripped from a prvalue
25 static_assert(std::is_same_v
<decltype(std::forward_like
<T
>(U
{})), U
&&>);
26 static_assert(std::is_same_v
<decltype(std::forward_like
<T
>(CU
{})), CU
&&>);
27 static_assert(std::is_same_v
<decltype(std::forward_like
<T
>(u
)), U
&&>);
28 static_assert(std::is_same_v
<decltype(std::forward_like
<T
>(cu
)), CU
&&>);
29 static_assert(std::is_same_v
<decltype(std::forward_like
<T
>(std::move(u
))), U
&&>);
30 static_assert(std::is_same_v
<decltype(std::forward_like
<T
>(std::move(cu
))), CU
&&>);
32 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
>(U
{})), CU
&&>);
33 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
>(CU
{})), CU
&&>);
34 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
>(u
)), CU
&&>);
35 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
>(cu
)), CU
&&>);
36 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
>(std::move(u
))), CU
&&>);
37 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
>(std::move(cu
))), CU
&&>);
39 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&>(U
{})), U
&>);
40 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&>(CU
{})), CU
&>);
41 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&>(u
)), U
&>);
42 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&>(cu
)), CU
&>);
43 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&>(std::move(u
))), U
&>);
44 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&>(std::move(cu
))), CU
&>);
46 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&>(U
{})), CU
&>);
47 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&>(CU
{})), CU
&>);
48 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&>(u
)), CU
&>);
49 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&>(cu
)), CU
&>);
50 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&>(std::move(u
))), CU
&>);
51 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&>(std::move(cu
))), CU
&>);
53 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&&>(U
{})), U
&&>);
54 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&&>(CU
{})), CU
&&>);
55 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&&>(u
)), U
&&>);
56 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&&>(cu
)), CU
&&>);
57 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&&>(std::move(u
))), U
&&>);
58 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&&>(std::move(cu
))), CU
&&>);
60 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&&>(U
{})), CU
&&>);
61 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&&>(CU
{})), CU
&&>);
62 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&&>(u
)), CU
&&>);
63 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&&>(cu
)), CU
&&>);
64 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&&>(std::move(u
))), CU
&&>);
65 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&&>(std::move(cu
))), CU
&&>);
67 static_assert(noexcept(std::forward_like
<T
>(u
)));
69 static_assert(std::is_same_v
<decltype(std::forward_like
<U
&>(u
)), U
&>);
70 static_assert(std::is_same_v
<decltype(std::forward_like
<CU
&>(cu
)), CU
&>);
71 static_assert(std::is_same_v
<decltype(std::forward_like
<U
&&>(std::move(u
))), U
&&>);
72 static_assert(std::is_same_v
<decltype(std::forward_like
<CU
&&>(std::move(cu
))), CU
&&>);
74 struct NoCtorCopyMove
{
75 NoCtorCopyMove() = delete;
76 NoCtorCopyMove(const NoCtorCopyMove
&) = delete;
77 NoCtorCopyMove(NoCtorCopyMove
&&) = delete;
80 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&&>(std::declval
<NoCtorCopyMove
>())), const NoCtorCopyMove
&&>);
81 static_assert(std::is_same_v
<decltype(std::forward_like
<CT
&>(std::declval
<NoCtorCopyMove
>())), const NoCtorCopyMove
&>);
82 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&&>(std::declval
<NoCtorCopyMove
>())), NoCtorCopyMove
&&>);
83 static_assert(std::is_same_v
<decltype(std::forward_like
<T
&>(std::declval
<NoCtorCopyMove
>())), NoCtorCopyMove
&>);
85 static_assert(noexcept(std::forward_like
<T
>(std::declval
<NoCtorCopyMove
>())));
87 constexpr bool test() {
90 auto&& result
= std::forward_like
<const double&>(val
);
91 static_assert(std::is_same_v
<decltype(result
), const int&>);
92 assert(&result
== &val
);
96 auto&& result
= std::forward_like
<double&>(val
);
97 static_assert(std::is_same_v
<decltype(result
), int&>);
98 assert(&result
== &val
);
102 auto&& result
= std::forward_like
<const double&&>(val
);
103 static_assert(std::is_same_v
<decltype(result
), const int&&>);
104 assert(&result
== &val
);
108 auto&& result
= std::forward_like
<double&&>(val
);
109 static_assert(std::is_same_v
<decltype(result
), int&&>);
110 assert(&result
== &val
);
115 int main(int, char**) {
117 static_assert(test());