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
17struct U {}; // class type so const-qualification is not stripped from a prvalue
18using CU = const U;
19using T = int;
20using CT = const T;
21
22U u{};
23const U& cu = u;
24
25static_assert(std::is_same_v<decltype(std::forward_like<T>(U{})), U&&>);
26static_assert(std::is_same_v<decltype(std::forward_like<T>(CU{})), CU&&>);
27static_assert(std::is_same_v<decltype(std::forward_like<T>(u)), U&&>);
28static_assert(std::is_same_v<decltype(std::forward_like<T>(cu)), CU&&>);
29static_assert(std::is_same_v<decltype(std::forward_like<T>(std::move(u))), U&&>);
30static_assert(std::is_same_v<decltype(std::forward_like<T>(std::move(cu))), CU&&>);
31
32static_assert(std::is_same_v<decltype(std::forward_like<CT>(U{})), CU&&>);
33static_assert(std::is_same_v<decltype(std::forward_like<CT>(CU{})), CU&&>);
34static_assert(std::is_same_v<decltype(std::forward_like<CT>(u)), CU&&>);
35static_assert(std::is_same_v<decltype(std::forward_like<CT>(cu)), CU&&>);
36static_assert(std::is_same_v<decltype(std::forward_like<CT>(std::move(u))), CU&&>);
37static_assert(std::is_same_v<decltype(std::forward_like<CT>(std::move(cu))), CU&&>);
38
39static_assert(std::is_same_v<decltype(std::forward_like<T&>(U{})), U&>);
40static_assert(std::is_same_v<decltype(std::forward_like<T&>(CU{})), CU&>);
41static_assert(std::is_same_v<decltype(std::forward_like<T&>(u)), U&>);
42static_assert(std::is_same_v<decltype(std::forward_like<T&>(cu)), CU&>);
43static_assert(std::is_same_v<decltype(std::forward_like<T&>(std::move(u))), U&>);
44static_assert(std::is_same_v<decltype(std::forward_like<T&>(std::move(cu))), CU&>);
45
46static_assert(std::is_same_v<decltype(std::forward_like<CT&>(U{})), CU&>);
47static_assert(std::is_same_v<decltype(std::forward_like<CT&>(CU{})), CU&>);
48static_assert(std::is_same_v<decltype(std::forward_like<CT&>(u)), CU&>);
49static_assert(std::is_same_v<decltype(std::forward_like<CT&>(cu)), CU&>);
50static_assert(std::is_same_v<decltype(std::forward_like<CT&>(std::move(u))), CU&>);
51static_assert(std::is_same_v<decltype(std::forward_like<CT&>(std::move(cu))), CU&>);
52
53static_assert(std::is_same_v<decltype(std::forward_like<T&&>(U{})), U&&>);
54static_assert(std::is_same_v<decltype(std::forward_like<T&&>(CU{})), CU&&>);
55static_assert(std::is_same_v<decltype(std::forward_like<T&&>(u)), U&&>);
56static_assert(std::is_same_v<decltype(std::forward_like<T&&>(cu)), CU&&>);
57static_assert(std::is_same_v<decltype(std::forward_like<T&&>(std::move(u))), U&&>);
58static_assert(std::is_same_v<decltype(std::forward_like<T&&>(std::move(cu))), CU&&>);
59
60static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(U{})), CU&&>);
61static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(CU{})), CU&&>);
62static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(u)), CU&&>);
63static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(cu)), CU&&>);
64static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(std::move(u))), CU&&>);
65static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(std::move(cu))), CU&&>);
66
67static_assert(noexcept(std::forward_like<T>(u)));
68
69static_assert(std::is_same_v<decltype(std::forward_like<U&>(u)), U&>);
70static_assert(std::is_same_v<decltype(std::forward_like<CU&>(cu)), CU&>);
71static_assert(std::is_same_v<decltype(std::forward_like<U&&>(std::move(u))), U&&>);
72static_assert(std::is_same_v<decltype(std::forward_like<CU&&>(std::move(cu))), CU&&>);
73
74struct NoCtorCopyMove {
75 NoCtorCopyMove() = delete;
76 NoCtorCopyMove(const NoCtorCopyMove&) = delete;
77 NoCtorCopyMove(NoCtorCopyMove&&) = delete;
78};
79
80static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(std::declval<NoCtorCopyMove>())), const NoCtorCopyMove&&>);
81static_assert(std::is_same_v<decltype(std::forward_like<CT&>(std::declval<NoCtorCopyMove>())), const NoCtorCopyMove&>);
82static_assert(std::is_same_v<decltype(std::forward_like<T&&>(std::declval<NoCtorCopyMove>())), NoCtorCopyMove&&>);
83static_assert(std::is_same_v<decltype(std::forward_like<T&>(std::declval<NoCtorCopyMove>())), NoCtorCopyMove&>);
84
85static_assert(noexcept(std::forward_like<T>(std::declval<NoCtorCopyMove>())));
86
87constexpr 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
115int main(int, char**) {
116 test();
117 static_assert(test());
118
119 return 0;
120}
121

source code of libcxx/test/std/utilities/utility/forward/forward_like.pass.cpp