1/*
2 * Copyright 2016-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
17#include <folly/futures/Future.h>
18#include <folly/portability/GTest.h>
19
20using namespace folly;
21
22TEST(NonCopyableLambda, basic) {
23 Promise<int> promise;
24 Future<int> future = promise.getFuture();
25
26 Future<Unit>().thenValue(std::bind(
27 [](Promise<int>& p2, folly::Unit) mutable { p2.setValue(123); },
28 std::move(promise),
29 std::placeholders::_1));
30
31 // The previous statement can be simplified in C++14:
32 // Future<Unit>().thenValue([promise = std::move(promise)](auto&&) mutable {
33 // promise.setValue(123);
34 // });
35
36 EXPECT_TRUE(future.isReady());
37 EXPECT_EQ(std::move(future).get(), 123);
38}
39
40TEST(NonCopyableLambda, unique_ptr) {
41 Promise<Unit> promise;
42 auto int_ptr = std::make_unique<int>(1);
43
44 EXPECT_EQ(*int_ptr, 1);
45
46 auto future = promise.getFuture().thenValue(std::bind(
47 [](std::unique_ptr<int>& p, folly::Unit) mutable {
48 ++*p;
49 return std::move(p);
50 },
51 std::move(int_ptr),
52 std::placeholders::_1));
53
54 // The previous statement can be simplified in C++14:
55 // auto future =
56 // promise.getFuture().thenValue([int_ptr = std::move(int_ptr)](
57 // auto&&) mutable {
58 // ++*int_ptr;
59 // return std::move(int_ptr);
60 // });
61
62 EXPECT_FALSE(future.isReady());
63 promise.setValue();
64 EXPECT_TRUE(future.isReady());
65 EXPECT_EQ(*std::move(future).get(), 2);
66}
67
68TEST(NonCopyableLambda, Function) {
69 Promise<int> promise;
70
71 Function<int(int)> callback = [](int x) { return x + 1; };
72
73 auto future = promise.getFuture().thenValue(std::move(callback));
74 EXPECT_THROW(callback(0), std::bad_function_call);
75
76 EXPECT_FALSE(future.isReady());
77 promise.setValue(100);
78 EXPECT_TRUE(future.isReady());
79 EXPECT_EQ(std::move(future).get(), 101);
80}
81
82TEST(NonCopyableLambda, FunctionConst) {
83 Promise<int> promise;
84
85 Function<int(int) const> callback = [](int x) { return x + 1; };
86
87 auto future = promise.getFuture().thenValue(std::move(callback));
88 EXPECT_THROW(callback(0), std::bad_function_call);
89
90 EXPECT_FALSE(future.isReady());
91 promise.setValue(100);
92 EXPECT_TRUE(future.isReady());
93 EXPECT_EQ(std::move(future).get(), 101);
94}
95