LeechCraft  0.6.70-13729-g7046a9d2a7
Modular cross-platform feature rich live environment.
currytest.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * LeechCraft - modular cross-platform feature rich internet client.
3  * Copyright (C) 2006-2014 Georg Rudoy
4  *
5  * Boost Software License - Version 1.0 - August 17th, 2003
6  *
7  * Permission is hereby granted, free of charge, to any person or organization
8  * obtaining a copy of the software and accompanying documentation covered by
9  * this license (the "Software") to use, reproduce, display, distribute,
10  * execute, and transmit the Software, and to prepare derivative works of the
11  * Software, and to permit third-parties to whom the Software is furnished to
12  * do so, all subject to the following:
13  *
14  * The copyright notices in the Software and this entire statement, including
15  * the above license grant, this restriction and the following disclaimer,
16  * must be included in all copies of the Software, in whole or in part, and
17  * all derivative works of the Software, unless such copies or derivative
18  * works are solely in the form of machine-executable object code generated by
19  * a source language processor.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
24  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
25  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  **********************************************************************/
29 
30 #include "currytest.h"
31 #include <memory>
32 #include <QtTest>
33 #include <curry.h>
34 
35 QTEST_APPLESS_MAIN (LC::Util::CurryTest)
36 
37 namespace LC::Util
38 {
39  void CurryTest::testBasic ()
40  {
41  auto sum = [] (int a, int b, int c) { return a + b + c; };
42  QCOMPARE (Curry (sum) (1) (2) (3), 6);
43 
44  auto stored = Curry (sum);
45  QCOMPARE (stored (1) (2) (3), 6);
46  QCOMPARE (stored (0) (2) (3), 5);
47 
48  auto storedApplied = Curry (sum) (0);
49  QCOMPARE (storedApplied (2) (3), 5);
50  }
51 
52  void CurryTest::testMoveArgs ()
53  {
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);
56 
57  auto curried = Curry (func) (std::make_unique<int> (1));
58  QCOMPARE (std::move (curried) (std::make_unique<int> (2)), 3);
59  }
60 
61  void CurryTest::testMoveFun ()
62  {
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);
66  }
67 
68  void CurryTest::testRValueFun ()
69  {
70  auto sum = [] (int&& a, int&& b, int&& c) { return a + b + c; };
71  QCOMPARE (Curry (sum) (1) (2) (3), 6);
72  }
73 
74  void CurryTest::testRefModifications ()
75  {
76  int a = 5;
77  int b = 6;
78  auto func = [] (int& a, int& b) { ++a; ++b; return a + b; };
79  QCOMPARE (Curry (func) (a) (b), 13);
80  QCOMPARE (a, 6);
81  QCOMPARE (b, 7);
82  }
83 
84  namespace
85  {
86  template<typename T>
87  struct Counter
88  {
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;
95 
96  Counter ()
97  {
98  ++DefConstrs_;
99  }
100 
101  Counter (const Counter&)
102  {
103  ++CopyConstrs_;
104  }
105 
106  Counter (Counter&&)
107  {
108  ++MoveConstrs_;
109  }
110 
111  Counter& operator= (const Counter&)
112  {
113  ++CopyAssignments_;
114  return *this;
115  }
116 
117  Counter& operator= (Counter&&)
118  {
119  ++MoveAssignments_;
120  return *this;
121  }
122 
123  ~Counter ()
124  {
125  ++Dtors_;
126  }
127  };
128  }
129 
130  void CurryTest::testNoExtraCopiesByValue ()
131  {
132  using C1 = Counter<struct Tag1>;
133  using C2 = Counter<struct Tag2>;
134 
135  auto func = [] (C1, C2) { return 0; };
136  QCOMPARE (Curry (func) (C1 {}) (C2 {}), 0);
137 
138  QCOMPARE (C1::CopyConstrs_, 0);
139  QCOMPARE (C2::CopyConstrs_, 0);
140  QCOMPARE (C1::CopyAssignments_, 0);
141  QCOMPARE (C2::CopyAssignments_, 0);
142 
143  QCOMPARE (C1::MoveConstrs_, 2);
144  QCOMPARE (C2::MoveConstrs_, 1);
145  QCOMPARE (C1::MoveAssignments_, 0);
146  QCOMPARE (C2::MoveAssignments_, 0);
147  }
148 
149  void CurryTest::testNoExtraCopiesByRef ()
150  {
151  using C1 = Counter<struct Tag1>;
152  using C2 = Counter<struct Tag2>;
153 
154  auto func = [] (C1&&, C2&&) { return 0; };
155  QCOMPARE (Curry (func) (C1 {}) (C2 {}), 0);
156 
157  QCOMPARE (C1::CopyConstrs_, 0);
158  QCOMPARE (C2::CopyConstrs_, 0);
159  QCOMPARE (C1::CopyAssignments_, 0);
160  QCOMPARE (C2::CopyAssignments_, 0);
161 
162  QCOMPARE (C1::MoveConstrs_, 1);
163  QCOMPARE (C2::MoveConstrs_, 0);
164  QCOMPARE (C1::MoveAssignments_, 0);
165  QCOMPARE (C2::MoveAssignments_, 0);
166  }
167 
168  void CurryTest::testNoExtraCopiesByConstRef ()
169  {
170  using C1 = Counter<struct Tag1>;
171  using C2 = Counter<struct Tag2>;
172 
173  auto func = [] (const C1&, const C2&) { return 0; };
174  QCOMPARE (Curry (func) (C1 {}) (C2 {}), 0);
175 
176  QCOMPARE (C1::CopyConstrs_, 0);
177  QCOMPARE (C2::CopyConstrs_, 0);
178  QCOMPARE (C1::CopyAssignments_, 0);
179  QCOMPARE (C2::CopyAssignments_, 0);
180 
181  QCOMPARE (C1::MoveConstrs_, 1);
182  QCOMPARE (C2::MoveConstrs_, 0);
183  QCOMPARE (C1::MoveAssignments_, 0);
184  QCOMPARE (C2::MoveAssignments_, 0);
185  }
186 
187  void CurryTest::testNoExtraCopiesByConstRefToExisting ()
188  {
189  using C1 = Counter<struct Tag1>;
190  using C2 = Counter<struct Tag2>;
191 
192  auto func = [] (const C1&, const C2&) { return 0; };
193  C1 c1;
194  C2 c2;
195  QCOMPARE (Curry (func) (c1) (c2), 0);
196 
197  QCOMPARE (C1::CopyConstrs_, 0);
198  QCOMPARE (C2::CopyConstrs_, 0);
199  QCOMPARE (C1::CopyAssignments_, 0);
200  QCOMPARE (C2::CopyAssignments_, 0);
201 
202  QCOMPARE (C1::MoveConstrs_, 0);
203  QCOMPARE (C2::MoveConstrs_, 0);
204  QCOMPARE (C1::MoveAssignments_, 0);
205  QCOMPARE (C2::MoveAssignments_, 0);
206  }
207 }
CurryImpl< std::decay_t< F >, Args... > Curry(F &&f, Args &&... args)
Definition: curry.h:93