proxygen
InvokeTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
20 
21 class InvokeTest : public testing::Test {};
22 
23 namespace {
24 
25 struct from_any {
26  template <typename T>
27  /* implicit */ from_any(T&&) {}
28 };
29 
30 struct Fn {
31  char operator()(int, int) noexcept {
32  return 'a';
33  }
34  int volatile&& operator()(int, char const*) {
35  return std::move(x_);
36  }
37  float operator()(float, float) {
38  return 3.14;
39  }
40  int volatile x_ = 17;
41 };
42 
43 FOLLY_CREATE_MEMBER_INVOKE_TRAITS(test_invoke_traits, test);
44 
45 struct Obj {
46  char test(int, int) noexcept {
47  return 'a';
48  }
49  int volatile&& test(int, char const*) {
50  return std::move(x_);
51  }
52  float test(float, float) {
53  return 3.14;
54  }
55  int volatile x_ = 17;
56 };
57 
58 namespace x {
59 struct Obj {};
60 int go(Obj const&, int) noexcept {
61  return 3;
62 }
63 } // namespace x
64 
65 namespace y {
66 struct Obj {};
67 char go(Obj const&, char const*) {
68  return 'a';
69 }
70 } // namespace y
71 
72 namespace z {
73 struct Obj {};
74 } // namespace z
75 float go(z::Obj const&, int) {
76  return 9;
77 }
78 
79 namespace swappable {
80 struct Obj {
81  int x_;
82 };
83 void swap(Obj&, Obj&) noexcept {} // no-op
84 } // namespace swappable
85 
86 FOLLY_CREATE_FREE_INVOKE_TRAITS(go_invoke_traits, go);
87 FOLLY_CREATE_FREE_INVOKE_TRAITS(swap_invoke_traits, swap, std);
88 FOLLY_CREATE_FREE_INVOKE_TRAITS(unused_invoke_traits, definitely_unused_name_);
89 
90 } // namespace
91 
93  Fn fn;
94 
96  EXPECT_FALSE(noexcept(folly::invoke(fn, 1, "2")));
97 
98  EXPECT_EQ('a', folly::invoke(fn, 1, 2));
99  EXPECT_EQ(17, folly::invoke(fn, 1, "2"));
100 
101  using FnA = char (Fn::*)(int, int);
102  using FnB = int volatile && (Fn::*)(int, char const*);
103  EXPECT_EQ('a', folly::invoke(static_cast<FnA>(&Fn::operator()), fn, 1, 2));
104  EXPECT_EQ(17, folly::invoke(static_cast<FnB>(&Fn::operator()), fn, 1, "2"));
105 }
106 
107 TEST_F(InvokeTest, invoke_result) {
108  EXPECT_TRUE(
109  (std::is_same<char, folly::invoke_result_t<Fn, int, char>>::value));
110  EXPECT_TRUE(
111  (std::is_same<int volatile&&, folly::invoke_result_t<Fn, int, char*>>::
112  value));
113 }
114 
115 TEST_F(InvokeTest, is_invocable) {
119 }
120 
121 TEST_F(InvokeTest, is_invocable_r) {
125 }
126 
127 TEST_F(InvokeTest, is_nothrow_invocable) {
131 }
132 
133 TEST_F(InvokeTest, is_nothrow_invocable_r) {
137 }
138 
139 TEST_F(InvokeTest, free_invoke) {
140  using traits = go_invoke_traits;
141 
142  x::Obj x_;
143  y::Obj y_;
144 
146  EXPECT_FALSE(noexcept(traits::invoke(y_, "hello")));
147 
148  EXPECT_EQ(3, traits::invoke(x_, 3));
149  EXPECT_EQ('a', traits::invoke(y_, "hello"));
150 }
151 
152 TEST_F(InvokeTest, free_invoke_result) {
153  using traits = go_invoke_traits;
154 
155  EXPECT_TRUE((std::is_same<int, traits::invoke_result_t<x::Obj, int>>::value));
156  EXPECT_TRUE((
157  std::is_same<char, traits::invoke_result_t<y::Obj, char const*>>::value));
158 }
159 
160 TEST_F(InvokeTest, free_is_invocable) {
161  using traits = go_invoke_traits;
162 
167 }
168 
169 TEST_F(InvokeTest, free_is_invocable_r) {
170  using traits = go_invoke_traits;
171 
176 }
177 
178 TEST_F(InvokeTest, free_is_nothrow_invocable) {
179  using traits = go_invoke_traits;
180 
185 }
186 
187 TEST_F(InvokeTest, free_is_nothrow_invocable_r) {
188  using traits = go_invoke_traits;
189 
191  EXPECT_FALSE(
195 }
196 
197 TEST_F(InvokeTest, free_invoke_swap) {
198  using traits = swap_invoke_traits;
199 
200  int a = 3;
201  int b = 4;
202 
203  traits::invoke(a, b);
204  EXPECT_EQ(4, a);
205  EXPECT_EQ(3, b);
206 
207  swappable::Obj x{3};
208  swappable::Obj y{4};
209 
210  traits::invoke(x, y);
211  EXPECT_EQ(3, x.x_);
212  EXPECT_EQ(4, y.x_);
213 
214  std::swap(x, y);
215  EXPECT_EQ(4, x.x_);
216  EXPECT_EQ(3, y.x_);
217 }
218 
219 TEST_F(InvokeTest, member_invoke) {
220  using traits = test_invoke_traits;
221 
222  Obj fn;
223 
224  EXPECT_TRUE(noexcept(traits::invoke(fn, 1, 2)));
225  EXPECT_FALSE(noexcept(traits::invoke(fn, 1, "2")));
226 
227  EXPECT_EQ('a', traits::invoke(fn, 1, 2));
228  EXPECT_EQ(17, traits::invoke(fn, 1, "2"));
229 }
230 
231 TEST_F(InvokeTest, member_invoke_result) {
232  using traits = test_invoke_traits;
233 
234  EXPECT_TRUE(
235  (std::is_same<char, traits::invoke_result_t<Obj, int, char>>::value));
236  EXPECT_TRUE(
237  (std::is_same<int volatile&&, traits::invoke_result_t<Obj, int, char*>>::
238  value));
239 }
240 
241 TEST_F(InvokeTest, member_is_invocable) {
242  using traits = test_invoke_traits;
243 
247 }
248 
249 TEST_F(InvokeTest, member_is_invocable_r) {
250  using traits = test_invoke_traits;
251 
255 }
256 
257 TEST_F(InvokeTest, member_is_nothrow_invocable) {
258  using traits = test_invoke_traits;
259 
263 }
264 
265 TEST_F(InvokeTest, member_is_nothrow_invocable_r) {
266  using traits = test_invoke_traits;
267 
271 }
Definition: InvokeTest.cpp:58
#define T(v)
Definition: http_parser.c:233
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::invoke_fn invoke
typename invoke_result< F, Args... >::type invoke_result_t
Definition: Invoke.h:142
char b
#define FOLLY_CREATE_FREE_INVOKE_TRAITS(classname, funcname,...)
Definition: Invoke.h:283
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static uint64_t test(std::string name, bool fc_, bool dedicated_, bool tc_, bool syncops_, uint64_t base)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
requires E e noexcept(noexcept(s.error(std::move(e))))
constexpr auto invoke(F &&f, Args &&...args) noexcept(noexcept(static_cast< F && >(f)(static_cast< Args && >(args)...))) -> decltype(static_cast< F && >(f)(static_cast< Args && >(args)...))
Definition: Invoke.h:49
Definition: InvokeTest.cpp:72
char a
static const char *const value
Definition: Conv.cpp:50
TEST_F(InvokeTest, invoke)
Definition: InvokeTest.cpp:92
int y_
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define FOLLY_CREATE_MEMBER_INVOKE_TRAITS(classname, membername)
Definition: Invoke.h:402
Definition: InvokeTest.cpp:65
void swap(SwapTrackingAlloc< T > &, SwapTrackingAlloc< T > &)
Definition: F14TestUtil.h:414
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
int x_