xref: /llvm-project/libcxx/test/std/utilities/utility/forward/forward_like.pass.cpp (revision ee8dd43c2407f15c6e757d929f62aee92c9d30a7)
1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10 
11 // test forward_like
12 
13 #include <cassert>
14 #include <type_traits>
15 #include <utility>
16 
17 struct U {}; // class type so const-qualification is not stripped from a prvalue
18 using CU = const U;
19 using T  = int;
20 using CT = const T;
21 
22 U u{};
23 const U& cu = u;
24 
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&&>);
31 
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&&>);
38 
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&>);
45 
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&>);
52 
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&&>);
59 
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&&>);
66 
67 static_assert(noexcept(std::forward_like<T>(u)));
68 
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&&>);
73 
74 struct NoCtorCopyMove {
75   NoCtorCopyMove() = delete;
76   NoCtorCopyMove(const NoCtorCopyMove&) = delete;
77   NoCtorCopyMove(NoCtorCopyMove&&) = delete;
78 };
79 
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&>);
84 
85 static_assert(noexcept(std::forward_like<T>(std::declval<NoCtorCopyMove>())));
86 
test()87 constexpr bool test() {
88   {
89     int val       = 1729;
90     auto&& result = std::forward_like<const double&>(val);
91     static_assert(std::is_same_v<decltype(result), const int&>);
92     assert(&result == &val);
93   }
94   {
95     int val       = 1729;
96     auto&& result = std::forward_like<double&>(val);
97     static_assert(std::is_same_v<decltype(result), int&>);
98     assert(&result == &val);
99   }
100   {
101     int val       = 1729;
102     auto&& result = std::forward_like<const double&&>(val);
103     static_assert(std::is_same_v<decltype(result), const int&&>);
104     assert(&result == &val);
105   }
106   {
107     int val       = 1729;
108     auto&& result = std::forward_like<double&&>(val);
109     static_assert(std::is_same_v<decltype(result), int&&>);
110     assert(&result == &val);
111   }
112   return true;
113 }
114 
main(int,char **)115 int main(int, char**) {
116   test();
117   static_assert(test());
118 
119   return 0;
120 }
121