39 void CurryTest::testBasic ()
41 auto sum = [] (
int a,
int b,
int c) {
return a + b + c; };
42 QCOMPARE (
Curry (sum) (1) (2) (3), 6);
44 auto stored =
Curry (sum);
45 QCOMPARE (stored (1) (2) (3), 6);
46 QCOMPARE (stored (0) (2) (3), 5);
48 auto storedApplied =
Curry (sum) (0);
49 QCOMPARE (storedApplied (2) (3), 5);
52 void CurryTest::testMoveArgs ()
54 auto func = [] (std::unique_ptr<int> a, std::unique_ptr<int> b) {
return *a + *b; };
55 QCOMPARE (
Curry (func) (std::make_unique<int> (1)) (std::make_unique<int> (2)), 3);
57 auto curried =
Curry (func) (std::make_unique<int> (1));
58 QCOMPARE (std::move (curried) (std::make_unique<int> (2)), 3);
61 void CurryTest::testMoveFun ()
63 auto ptr = std::make_unique<int> (10);
64 auto func = [ptr = std::move (ptr)] (std::unique_ptr<int> a, std::unique_ptr<int> b) {
return *ptr + *a + *b; };
65 QCOMPARE (
Curry (std::move (func)) (std::make_unique<int> (1)) (std::make_unique<int> (2)), 13);
68 void CurryTest::testRValueFun ()
70 auto sum = [] (
int&& a,
int&& b,
int&& c) {
return a + b + c; };
71 QCOMPARE (
Curry (sum) (1) (2) (3), 6);
74 void CurryTest::testRefModifications ()
78 auto func = [] (
int& a,
int& b) { ++a; ++b;
return a + b; };
79 QCOMPARE (
Curry (func) (a) (b), 13);
89 static inline int DefConstrs_ = 0;
90 static inline int CopyConstrs_ = 0;
91 static inline int CopyAssignments_ = 0;
92 static inline int MoveConstrs_ = 0;
93 static inline int MoveAssignments_ = 0;
94 static inline int Dtors_ = 0;
101 Counter (
const Counter&)
111 Counter& operator= (
const Counter&)
117 Counter& operator= (Counter&&)
130 void CurryTest::testNoExtraCopiesByValue ()
132 using C1 = Counter<struct Tag1>;
133 using C2 = Counter<struct Tag2>;
135 auto func = [] (C1, C2) {
return 0; };
136 QCOMPARE (
Curry (func) (C1 {}) (C2 {}), 0);
138 QCOMPARE (C1::CopyConstrs_, 0);
139 QCOMPARE (C2::CopyConstrs_, 0);
140 QCOMPARE (C1::CopyAssignments_, 0);
141 QCOMPARE (C2::CopyAssignments_, 0);
143 QCOMPARE (C1::MoveConstrs_, 2);
144 QCOMPARE (C2::MoveConstrs_, 1);
145 QCOMPARE (C1::MoveAssignments_, 0);
146 QCOMPARE (C2::MoveAssignments_, 0);
149 void CurryTest::testNoExtraCopiesByRef ()
151 using C1 = Counter<struct Tag1>;
152 using C2 = Counter<struct Tag2>;
154 auto func = [] (C1&&, C2&&) {
return 0; };
155 QCOMPARE (
Curry (func) (C1 {}) (C2 {}), 0);
157 QCOMPARE (C1::CopyConstrs_, 0);
158 QCOMPARE (C2::CopyConstrs_, 0);
159 QCOMPARE (C1::CopyAssignments_, 0);
160 QCOMPARE (C2::CopyAssignments_, 0);
162 QCOMPARE (C1::MoveConstrs_, 1);
163 QCOMPARE (C2::MoveConstrs_, 0);
164 QCOMPARE (C1::MoveAssignments_, 0);
165 QCOMPARE (C2::MoveAssignments_, 0);
168 void CurryTest::testNoExtraCopiesByConstRef ()
170 using C1 = Counter<struct Tag1>;
171 using C2 = Counter<struct Tag2>;
173 auto func = [] (
const C1&,
const C2&) {
return 0; };
174 QCOMPARE (
Curry (func) (C1 {}) (C2 {}), 0);
176 QCOMPARE (C1::CopyConstrs_, 0);
177 QCOMPARE (C2::CopyConstrs_, 0);
178 QCOMPARE (C1::CopyAssignments_, 0);
179 QCOMPARE (C2::CopyAssignments_, 0);
181 QCOMPARE (C1::MoveConstrs_, 1);
182 QCOMPARE (C2::MoveConstrs_, 0);
183 QCOMPARE (C1::MoveAssignments_, 0);
184 QCOMPARE (C2::MoveAssignments_, 0);
187 void CurryTest::testNoExtraCopiesByConstRefToExisting ()
189 using C1 = Counter<struct Tag1>;
190 using C2 = Counter<struct Tag2>;
192 auto func = [] (
const C1&,
const C2&) {
return 0; };
195 QCOMPARE (
Curry (func) (c1) (c2), 0);
197 QCOMPARE (C1::CopyConstrs_, 0);
198 QCOMPARE (C2::CopyConstrs_, 0);
199 QCOMPARE (C1::CopyAssignments_, 0);
200 QCOMPARE (C2::CopyAssignments_, 0);
202 QCOMPARE (C1::MoveConstrs_, 0);
203 QCOMPARE (C2::MoveConstrs_, 0);
204 QCOMPARE (C1::MoveAssignments_, 0);
205 QCOMPARE (C2::MoveAssignments_, 0);
CurryImpl< std::decay_t< F >, Args... > Curry(F &&f, Args &&... args)