1 //===- FunctionExtrasTest.cpp - Unit tests for function type erasure ------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/FunctionExtras.h"
10 #include "gtest/gtest.h"
13 #include <type_traits>
19 TEST(UniqueFunctionTest
, Basic
) {
20 unique_function
<int(int, int)> Sum
= [](int A
, int B
) { return A
+ B
; };
21 EXPECT_EQ(Sum(1, 2), 3);
23 unique_function
<int(int, int)> Sum2
= std::move(Sum
);
24 EXPECT_EQ(Sum2(1, 2), 3);
26 unique_function
<int(int, int)> Sum3
= [](int A
, int B
) { return A
+ B
; };
27 Sum2
= std::move(Sum3
);
28 EXPECT_EQ(Sum2(1, 2), 3);
30 Sum2
= unique_function
<int(int, int)>([](int A
, int B
) { return A
+ B
; });
31 EXPECT_EQ(Sum2(1, 2), 3);
33 // Explicit self-move test.
34 *&Sum2
= std::move(Sum2
);
35 EXPECT_EQ(Sum2(1, 2), 3);
37 Sum2
= unique_function
<int(int, int)>();
40 // Make sure we can forward through l-value reference parameters.
41 unique_function
<void(int &)> Inc
= [](int &X
) { ++X
; };
46 // Make sure we can forward through r-value reference parameters with
48 unique_function
<int(std::unique_ptr
<int> &&)> ReadAndDeallocByRef
=
49 [](std::unique_ptr
<int> &&Ptr
) {
54 std::unique_ptr
<int> Ptr
{new int(13)};
55 EXPECT_EQ(ReadAndDeallocByRef(std::move(Ptr
)), 13);
56 EXPECT_FALSE((bool)Ptr
);
58 // Make sure we can pass a move-only temporary as opposed to a local variable.
59 EXPECT_EQ(ReadAndDeallocByRef(std::unique_ptr
<int>(new int(42))), 42);
61 // Make sure we can pass a move-only type by-value.
62 unique_function
<int(std::unique_ptr
<int>)> ReadAndDeallocByVal
=
63 [](std::unique_ptr
<int> Ptr
) {
68 Ptr
.reset(new int(13));
69 EXPECT_EQ(ReadAndDeallocByVal(std::move(Ptr
)), 13);
70 EXPECT_FALSE((bool)Ptr
);
72 EXPECT_EQ(ReadAndDeallocByVal(std::unique_ptr
<int>(new int(42))), 42);
75 TEST(UniqueFunctionTest
, Captures
) {
76 long A
= 1, B
= 2, C
= 3, D
= 4, E
= 5;
78 unique_function
<long()> Tmp
;
80 unique_function
<long()> C1
= [A
]() { return A
; };
85 unique_function
<long()> C2
= [A
, B
]() { return A
+ B
; };
90 unique_function
<long()> C3
= [A
, B
, C
]() { return A
+ B
+ C
; };
95 unique_function
<long()> C4
= [A
, B
, C
, D
]() { return A
+ B
+ C
+ D
; };
100 unique_function
<long()> C5
= [A
, B
, C
, D
, E
]() { return A
+ B
+ C
+ D
+ E
; };
103 EXPECT_EQ(Tmp(), 15);
106 TEST(UniqueFunctionTest
, MoveOnly
) {
107 struct SmallCallable
{
108 std::unique_ptr
<int> A
{new int(1)};
110 int operator()(int B
) { return *A
+ B
; }
112 unique_function
<int(int)> Small
= SmallCallable();
113 EXPECT_EQ(Small(2), 3);
114 unique_function
<int(int)> Small2
= std::move(Small
);
115 EXPECT_EQ(Small2(2), 3);
117 struct LargeCallable
{
118 std::unique_ptr
<int> A
{new int(1)};
119 std::unique_ptr
<int> B
{new int(2)};
120 std::unique_ptr
<int> C
{new int(3)};
121 std::unique_ptr
<int> D
{new int(4)};
122 std::unique_ptr
<int> E
{new int(5)};
124 int operator()() { return *A
+ *B
+ *C
+ *D
+ *E
; }
126 unique_function
<int()> Large
= LargeCallable();
127 EXPECT_EQ(Large(), 15);
128 unique_function
<int()> Large2
= std::move(Large
);
129 EXPECT_EQ(Large2(), 15);
132 TEST(UniqueFunctionTest
, CountForwardingCopies
) {
136 CopyCounter(int &CopyCount
) : CopyCount(CopyCount
) {}
137 CopyCounter(const CopyCounter
&Arg
) : CopyCount(Arg
.CopyCount
) {
142 unique_function
<void(CopyCounter
)> ByValF
= [](CopyCounter
) {};
144 ByValF(CopyCounter(CopyCount
));
145 EXPECT_EQ(1, CopyCount
);
149 CopyCounter Counter
{CopyCount
};
152 EXPECT_EQ(2, CopyCount
);
154 // Check that we don't generate a copy at all when we can bind a reference all
155 // the way down, even if that reference could *in theory* allow copies.
156 unique_function
<void(const CopyCounter
&)> ByRefF
= [](const CopyCounter
&) {
159 ByRefF(CopyCounter(CopyCount
));
160 EXPECT_EQ(0, CopyCount
);
164 CopyCounter Counter
{CopyCount
};
167 EXPECT_EQ(0, CopyCount
);
169 // If we use a reference, we can make a stronger guarantee that *no* copy
172 Uncopyable() = default;
173 Uncopyable(const Uncopyable
&) = delete;
175 unique_function
<void(const Uncopyable
&)> UncopyableF
=
176 [](const Uncopyable
&) {};
177 UncopyableF(Uncopyable());
182 TEST(UniqueFunctionTest
, CountForwardingMoves
) {
186 MoveCounter(int &MoveCount
) : MoveCount(MoveCount
) {}
187 MoveCounter(MoveCounter
&&Arg
) : MoveCount(Arg
.MoveCount
) { ++MoveCount
; }
190 unique_function
<void(MoveCounter
)> ByValF
= [](MoveCounter
) {};
192 ByValF(MoveCounter(MoveCount
));
193 EXPECT_EQ(1, MoveCount
);
197 MoveCounter Counter
{MoveCount
};
198 ByValF(std::move(Counter
));
200 EXPECT_EQ(2, MoveCount
);
202 // Check that when we use an r-value reference we get no spurious copies.
203 unique_function
<void(MoveCounter
&&)> ByRefF
= [](MoveCounter
&&) {};
205 ByRefF(MoveCounter(MoveCount
));
206 EXPECT_EQ(0, MoveCount
);
210 MoveCounter Counter
{MoveCount
};
211 ByRefF(std::move(Counter
));
213 EXPECT_EQ(0, MoveCount
);
215 // If we use an r-value reference we can in fact make a stronger guarantee
216 // with an unmovable type.
218 Unmovable() = default;
219 Unmovable(Unmovable
&&) = delete;
221 unique_function
<void(const Unmovable
&)> UnmovableF
= [](const Unmovable
&) {
223 UnmovableF(Unmovable());
228 TEST(UniqueFunctionTest
, Const
) {
229 // Can assign from const lambda.
230 unique_function
<int(int) const> Plus2
= [X(std::make_unique
<int>(2))](int Y
) {
233 EXPECT_EQ(5, Plus2(3));
235 // Can call through a const ref.
236 const auto &Plus2Ref
= Plus2
;
237 EXPECT_EQ(5, Plus2Ref(3));
239 // Can move-construct and assign.
240 unique_function
<int(int) const> Plus2A
= std::move(Plus2
);
241 EXPECT_EQ(5, Plus2A(3));
242 unique_function
<int(int) const> Plus2B
;
243 Plus2B
= std::move(Plus2A
);
244 EXPECT_EQ(5, Plus2B(3));
246 // Can convert to non-const function type, but not back.
247 unique_function
<int(int)> Plus2C
= std::move(Plus2B
);
248 EXPECT_EQ(5, Plus2C(3));
250 // Overloaded call operator correctly resolved.
251 struct ChooseCorrectOverload
{
252 StringRef
operator()() { return "non-const"; }
253 StringRef
operator()() const { return "const"; }
255 unique_function
<StringRef()> ChooseMutable
= ChooseCorrectOverload();
256 ChooseCorrectOverload A
;
257 EXPECT_EQ("non-const", ChooseMutable());
258 EXPECT_EQ("non-const", A());
259 unique_function
<StringRef() const> ChooseConst
= ChooseCorrectOverload();
260 const ChooseCorrectOverload
&X
= A
;
261 EXPECT_EQ("const", ChooseConst());
262 EXPECT_EQ("const", X());
265 // Test that overloads on unique_functions are resolved as expected.
266 std::string
returns(StringRef
) { return "not a function"; }
267 std::string
returns(unique_function
<double()> F
) { return "number"; }
268 std::string
returns(unique_function
<StringRef()> F
) { return "string"; }
270 TEST(UniqueFunctionTest
, SFINAE
) {
271 EXPECT_EQ("not a function", returns("boo!"));
272 EXPECT_EQ("number", returns([] { return 42; }));
273 EXPECT_EQ("string", returns([] { return "hello"; }));
276 // A forward declared type, and a templated type.
278 template <typename T
> class Templated
{ T A
; };
280 // Check that we can define unique_function that have references to
281 // incomplete types, even if those types are templated over an
283 TEST(UniqueFunctionTest
, IncompleteTypes
) {
284 unique_function
<void(Templated
<Incomplete
> &&)>
285 IncompleteArgumentRValueReference
;
286 unique_function
<void(Templated
<Incomplete
> &)>
287 IncompleteArgumentLValueReference
;
288 unique_function
<void(Templated
<Incomplete
> *)> IncompleteArgumentPointer
;
289 unique_function
<Templated
<Incomplete
> &()> IncompleteResultLValueReference
;
290 unique_function
<Templated
<Incomplete
> && ()> IncompleteResultRValueReference2
;
291 unique_function
<Templated
<Incomplete
> *()> IncompleteResultPointer
;
294 // Incomplete function returning an incomplete type
295 Incomplete
incompleteFunction();
296 const Incomplete
incompleteFunctionConst();
298 // Check that we can assign a callable to a unique_function when the
299 // callable return value is incomplete.
300 TEST(UniqueFunctionTest
, IncompleteCallableType
) {
301 unique_function
<Incomplete()> IncompleteReturnInCallable
{incompleteFunction
};
302 unique_function
<const Incomplete()> IncompleteReturnInCallableConst
{
303 incompleteFunctionConst
};
304 unique_function
<const Incomplete()> IncompleteReturnInCallableConstConversion
{
308 // Define the incomplete function
310 Incomplete
incompleteFunction() { return {}; }
311 const Incomplete
incompleteFunctionConst() { return {}; }
313 } // anonymous namespace