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 |
10 | // |
11 | // <functional> |
12 | // |
13 | // result_of<Fn(ArgTypes...)> |
14 | |
15 | // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS |
16 | // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS |
17 | |
18 | #include <type_traits> |
19 | #include <functional> |
20 | #include <memory> |
21 | #include <utility> |
22 | #include "test_macros.h" |
23 | |
24 | // Ignore warnings about volatile in parameters being deprecated. |
25 | // We know it is, but we still have to test it. |
26 | TEST_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-volatile" ) |
27 | TEST_GCC_DIAGNOSTIC_IGNORED("-Wvolatile" ) |
28 | // MSVC warning C5215: a function parameter with a volatile qualified type is deprecated in C++20 |
29 | TEST_MSVC_DIAGNOSTIC_IGNORED(5215) |
30 | |
31 | struct wat |
32 | { |
33 | wat& operator*() { return *this; } |
34 | void foo(); |
35 | }; |
36 | |
37 | struct F {}; |
38 | struct FD : public F {}; |
39 | |
40 | #if TEST_STD_VER > 14 |
41 | template <typename T, typename U> |
42 | struct test_invoke_result; |
43 | |
44 | template <typename Fn, typename ...Args, typename Ret> |
45 | struct test_invoke_result<Fn(Args...), Ret> |
46 | { |
47 | static void call() |
48 | { |
49 | static_assert(std::is_invocable<Fn, Args...>::value, "" ); |
50 | static_assert(std::is_invocable_r<Ret, Fn, Args...>::value, "" ); |
51 | ASSERT_SAME_TYPE(Ret, typename std::invoke_result<Fn, Args...>::type); |
52 | ASSERT_SAME_TYPE(Ret, std::invoke_result_t<Fn, Args...>); |
53 | } |
54 | }; |
55 | #endif |
56 | |
57 | template <class T, class U> |
58 | void test_result_of_imp() |
59 | { |
60 | ASSERT_SAME_TYPE(U, typename std::result_of<T>::type); |
61 | #if TEST_STD_VER > 11 |
62 | ASSERT_SAME_TYPE(U, std::result_of_t<T>); |
63 | #endif |
64 | #if TEST_STD_VER > 14 |
65 | test_invoke_result<T, U>::call(); |
66 | #endif |
67 | } |
68 | |
69 | int main(int, char**) |
70 | { |
71 | { |
72 | typedef char F::*PMD; |
73 | test_result_of_imp<PMD(F &), char &>(); |
74 | test_result_of_imp<PMD(F const &), char const &>(); |
75 | test_result_of_imp<PMD(F volatile &), char volatile &>(); |
76 | test_result_of_imp<PMD(F const volatile &), char const volatile &>(); |
77 | |
78 | test_result_of_imp<PMD(F &&), char &&>(); |
79 | test_result_of_imp<PMD(F const &&), char const &&>(); |
80 | test_result_of_imp<PMD(F volatile &&), char volatile &&>(); |
81 | test_result_of_imp<PMD(F const volatile &&), char const volatile &&>(); |
82 | |
83 | test_result_of_imp<PMD(F ), char &&>(); |
84 | test_result_of_imp<PMD(F const ), char &&>(); |
85 | test_result_of_imp<PMD(F volatile ), char &&>(); |
86 | test_result_of_imp<PMD(F const volatile ), char &&>(); |
87 | |
88 | test_result_of_imp<PMD(FD &), char &>(); |
89 | test_result_of_imp<PMD(FD const &), char const &>(); |
90 | test_result_of_imp<PMD(FD volatile &), char volatile &>(); |
91 | test_result_of_imp<PMD(FD const volatile &), char const volatile &>(); |
92 | |
93 | test_result_of_imp<PMD(FD &&), char &&>(); |
94 | test_result_of_imp<PMD(FD const &&), char const &&>(); |
95 | test_result_of_imp<PMD(FD volatile &&), char volatile &&>(); |
96 | test_result_of_imp<PMD(FD const volatile &&), char const volatile &&>(); |
97 | |
98 | test_result_of_imp<PMD(FD ), char &&>(); |
99 | test_result_of_imp<PMD(FD const ), char &&>(); |
100 | test_result_of_imp<PMD(FD volatile ), char &&>(); |
101 | test_result_of_imp<PMD(FD const volatile ), char &&>(); |
102 | |
103 | test_result_of_imp<PMD(std::unique_ptr<F>), char &>(); |
104 | test_result_of_imp<PMD(std::unique_ptr<F const>), const char &>(); |
105 | test_result_of_imp<PMD(std::unique_ptr<FD>), char &>(); |
106 | test_result_of_imp<PMD(std::unique_ptr<FD const>), const char &>(); |
107 | |
108 | test_result_of_imp<PMD(std::reference_wrapper<F>), char &>(); |
109 | test_result_of_imp<PMD(std::reference_wrapper<F const>), const char &>(); |
110 | test_result_of_imp<PMD(std::reference_wrapper<FD>), char &>(); |
111 | test_result_of_imp<PMD(std::reference_wrapper<FD const>), const char &>(); |
112 | } |
113 | { |
114 | test_result_of_imp<int (F::* (F &)) () &, int> (); |
115 | test_result_of_imp<int (F::* (F &)) () const &, int> (); |
116 | test_result_of_imp<int (F::* (F &)) () volatile &, int> (); |
117 | test_result_of_imp<int (F::* (F &)) () const volatile &, int> (); |
118 | test_result_of_imp<int (F::* (F const &)) () const &, int> (); |
119 | test_result_of_imp<int (F::* (F const &)) () const volatile &, int> (); |
120 | test_result_of_imp<int (F::* (F volatile &)) () volatile &, int> (); |
121 | test_result_of_imp<int (F::* (F volatile &)) () const volatile &, int> (); |
122 | test_result_of_imp<int (F::* (F const volatile &)) () const volatile &, int> (); |
123 | |
124 | test_result_of_imp<int (F::* (F &&)) () &&, int> (); |
125 | test_result_of_imp<int (F::* (F &&)) () const &&, int> (); |
126 | test_result_of_imp<int (F::* (F &&)) () volatile &&, int> (); |
127 | test_result_of_imp<int (F::* (F &&)) () const volatile &&, int> (); |
128 | test_result_of_imp<int (F::* (F const &&)) () const &&, int> (); |
129 | test_result_of_imp<int (F::* (F const &&)) () const volatile &&, int> (); |
130 | test_result_of_imp<int (F::* (F volatile &&)) () volatile &&, int> (); |
131 | test_result_of_imp<int (F::* (F volatile &&)) () const volatile &&, int> (); |
132 | test_result_of_imp<int (F::* (F const volatile &&)) () const volatile &&, int> (); |
133 | |
134 | test_result_of_imp<int (F::* (F )) () &&, int> (); |
135 | test_result_of_imp<int (F::* (F )) () const &&, int> (); |
136 | test_result_of_imp<int (F::* (F )) () volatile &&, int> (); |
137 | test_result_of_imp<int (F::* (F )) () const volatile &&, int> (); |
138 | test_result_of_imp<int (F::* (F const )) () const &&, int> (); |
139 | test_result_of_imp<int (F::* (F const )) () const volatile &&, int> (); |
140 | test_result_of_imp<int (F::* (F volatile )) () volatile &&, int> (); |
141 | test_result_of_imp<int (F::* (F volatile )) () const volatile &&, int> (); |
142 | test_result_of_imp<int (F::* (F const volatile )) () const volatile &&, int> (); |
143 | } |
144 | { |
145 | test_result_of_imp<int (F::* (FD &)) () &, int> (); |
146 | test_result_of_imp<int (F::* (FD &)) () const &, int> (); |
147 | test_result_of_imp<int (F::* (FD &)) () volatile &, int> (); |
148 | test_result_of_imp<int (F::* (FD &)) () const volatile &, int> (); |
149 | test_result_of_imp<int (F::* (FD const &)) () const &, int> (); |
150 | test_result_of_imp<int (F::* (FD const &)) () const volatile &, int> (); |
151 | test_result_of_imp<int (F::* (FD volatile &)) () volatile &, int> (); |
152 | test_result_of_imp<int (F::* (FD volatile &)) () const volatile &, int> (); |
153 | test_result_of_imp<int (F::* (FD const volatile &)) () const volatile &, int> (); |
154 | |
155 | test_result_of_imp<int (F::* (FD &&)) () &&, int> (); |
156 | test_result_of_imp<int (F::* (FD &&)) () const &&, int> (); |
157 | test_result_of_imp<int (F::* (FD &&)) () volatile &&, int> (); |
158 | test_result_of_imp<int (F::* (FD &&)) () const volatile &&, int> (); |
159 | test_result_of_imp<int (F::* (FD const &&)) () const &&, int> (); |
160 | test_result_of_imp<int (F::* (FD const &&)) () const volatile &&, int> (); |
161 | test_result_of_imp<int (F::* (FD volatile &&)) () volatile &&, int> (); |
162 | test_result_of_imp<int (F::* (FD volatile &&)) () const volatile &&, int> (); |
163 | test_result_of_imp<int (F::* (FD const volatile &&)) () const volatile &&, int> (); |
164 | |
165 | test_result_of_imp<int (F::* (FD )) () &&, int> (); |
166 | test_result_of_imp<int (F::* (FD )) () const &&, int> (); |
167 | test_result_of_imp<int (F::* (FD )) () volatile &&, int> (); |
168 | test_result_of_imp<int (F::* (FD )) () const volatile &&, int> (); |
169 | test_result_of_imp<int (F::* (FD const )) () const &&, int> (); |
170 | test_result_of_imp<int (F::* (FD const )) () const volatile &&, int> (); |
171 | test_result_of_imp<int (F::* (FD volatile )) () volatile &&, int> (); |
172 | test_result_of_imp<int (F::* (FD volatile )) () const volatile &&, int> (); |
173 | test_result_of_imp<int (F::* (FD const volatile )) () const volatile &&, int> (); |
174 | } |
175 | { |
176 | test_result_of_imp<int (F::* (std::reference_wrapper<F>)) (), int>(); |
177 | test_result_of_imp<int (F::* (std::reference_wrapper<const F>)) () const, int>(); |
178 | test_result_of_imp<int (F::* (std::unique_ptr<F> )) (), int>(); |
179 | test_result_of_imp<int (F::* (std::unique_ptr<const F> )) () const, int>(); |
180 | } |
181 | test_result_of_imp<decltype(&wat::foo)(wat), void>(); |
182 | |
183 | return 0; |
184 | } |
185 | |