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.
26TEST_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-volatile")
27TEST_GCC_DIAGNOSTIC_IGNORED("-Wvolatile")
28// MSVC warning C5215: a function parameter with a volatile qualified type is deprecated in C++20
29TEST_MSVC_DIAGNOSTIC_IGNORED(5215)
30
31struct wat
32{
33 wat& operator*() { return *this; }
34 void foo();
35};
36
37struct F {};
38struct FD : public F {};
39
40#if TEST_STD_VER > 14
41template <typename T, typename U>
42struct test_invoke_result;
43
44template <typename Fn, typename ...Args, typename Ret>
45struct 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
57template <class T, class U>
58void 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
69int 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

source code of libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp