xref: /llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp (revision 64addd65210db59c8cb3794f792720e03e25b5af)
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 {
operator *wat33     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 {
calltest_invoke_result47     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>
test_result_of_imp()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 
main(int,char **)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