LeechCraft  0.6.70-10870-g558588d6ec
Modular cross-platform feature rich live environment.
visitortest.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 "visitortest.h"
31 #include <QtTest>
32 #include <visitor.h>
33 
35 
36 namespace LeechCraft
37 {
38 namespace Util
39 {
40  using Variant_t = boost::variant<int, char, std::string, QString, double, float>;
41 
42  struct S1
43  {
44  int field1;
45  double field2;
46  };
47 
48  struct S2
49  {
50  int field1;
51  double field2;
52  };
53 
54  using SVariant_t = boost::variant<S1, S2>;
55 
56  void VisitorTest::testBasicVisitor ()
57  {
58  Variant_t v { 'a' };
59  const auto& res = Visit (v,
60  [] (char) { return true; },
61  [] (int) { return false; },
62  [] (std::string) { return false; },
63  [] (QString) { return false; },
64  [] (double) { return false; },
65  [] (float) { return false; });
66  QCOMPARE (res, true);
67  }
68 
69  void VisitorTest::testBasicVisitorGenericFallback ()
70  {
71  Variant_t v { 'a' };
72  const auto& res = Visit (v,
73  [] (char) { return true; },
74  [] (int) { return false; },
75  [] (auto) { return false; });
76  QCOMPARE (res, true);
77  }
78 
79  void VisitorTest::testBasicVisitorCoercion ()
80  {
81  Variant_t v { 'a' };
82  const auto& res = Visit (v,
83  [] (int) { return true; },
84  [] (std::string) { return false; },
85  [] (QString) { return false; },
86  [] (double) { return false; },
87  [] (float) { return false; });
88  QCOMPARE (res, true);
89  }
90 
91  void VisitorTest::testBasicVisitorCoercionGenericFallback ()
92  {
93  Variant_t v { 'a' };
94  const auto& res = Visit (v,
95  [] (int) { return false; },
96  [] (QString) { return false; },
97  [] (auto) { return true; });
98  QCOMPARE (res, true);
99  }
100 
101 #define NC nc = std::unique_ptr<int> {}
102 
103  void VisitorTest::testNonCopyableFunctors ()
104  {
105  Variant_t v { 'a' };
106  const auto& res = Visit (v,
107  [NC] (char) { return true; },
108  [NC] (int) { return false; },
109  [NC] (std::string) { return false; },
110  [NC] (QString) { return false; },
111  [NC] (double) { return false; },
112  [NC] (float) { return false; });
113  QCOMPARE (res, true);
114  }
115 #undef NC
116 
117  void VisitorTest::testDifferentReturnTypes ()
118  {
119  struct Foo {};
120  struct Bar : Foo {};
121 
122  Variant_t v { 'a' };
123  decltype (auto) res = Visit (v,
124  [] (int) -> Foo* { return nullptr; },
125  [] (char) -> Foo* { return nullptr; },
126  [] (auto) -> Bar* { return nullptr; });
127 
128  decltype (auto) res2 = Visit (v,
129  [] (int) -> Bar* { return nullptr; },
130  [] (char) -> Bar* { return nullptr; },
131  [] (auto) -> Foo* { return nullptr; });
132 
133  static_assert (std::is_same_v<decltype (res), Foo*>);
134  static_assert (std::is_same_v<decltype (res2), Foo*>);
135 
136  QCOMPARE (res, nullptr);
137  QCOMPARE (res2, nullptr);
138  }
139 
140  void VisitorTest::testAcceptsRValueRef ()
141  {
142  const auto& res = Visit (Variant_t { 'a' },
143  [] (char) { return true; },
144  [] (auto) { return false; });
145  QCOMPARE (res, true);
146  }
147 
148  void VisitorTest::testLValueRef ()
149  {
150  Variant_t v { 'a' };
151  int ref = 0;
152  auto& res = Visit (v, [&ref] (auto) -> int& { return ref; });
153  res = 10;
154  QCOMPARE (ref, 10);
155  }
156 
157  void VisitorTest::testLValueRef2 ()
158  {
159  SVariant_t v { S1 { 0, 0 } };
160  Visit (v, [] (auto& s) -> int& { return s.field1; }) = 10;
161  const auto& res = Visit (v, [] (const auto& s) -> const int& { return s.field1; });
162  QCOMPARE (res, 10);
163  }
164 
165  void VisitorTest::testPrepareVisitor ()
166  {
167  Variant_t v { 'a' };
168  Visitor visitor
169  {
170  [] (char) { return true; },
171  [] (int) { return false; },
172  [] (std::string) { return false; },
173  [] (QString) { return false; },
174  [] (double) { return false; },
175  [] (float) { return false; }
176  };
177 
178  const auto& res = visitor (v);
179  QCOMPARE (res, true);
180  }
181 
182  void VisitorTest::testPrepareVisitorConst ()
183  {
184  const Variant_t v { 'a' };
185  Visitor visitor
186  {
187  [] (char) { return true; },
188  [] (int) { return false; },
189  [] (std::string) { return false; },
190  [] (QString) { return false; },
191  [] (double) { return false; },
192  [] (float) { return false; }
193  };
194 
195  const auto& res = visitor (v);
196  QCOMPARE (res, true);
197  }
198 
199  void VisitorTest::testPrepareVisitorRValue ()
200  {
201  Visitor visitor
202  {
203  [] (char) { return true; },
204  [] (int) { return false; },
205  [] (std::string) { return false; },
206  [] (QString) { return false; },
207  [] (double) { return false; },
208  [] (float) { return false; }
209  };
210 
211  const auto& res = visitor (Variant_t { 'a' });
212  QCOMPARE (res, true);
213  }
214 
215  void VisitorTest::testPrepareVisitorFinally ()
216  {
217  Variant_t v { 'a' };
218 
219  bool fin = false;
220 
221  auto visitor = Visitor
222  {
223  [] (char) { return true; },
224  [] (auto) { return false; }
225  }.Finally ([&fin] { fin = true; });
226 
227  const auto& res = visitor (v);
228  QCOMPARE (res, true);
229  QCOMPARE (fin, true);
230  }
231 
232  void VisitorTest::testPrepareJustAutoVisitor ()
233  {
234  using Variant_t = boost::variant<int, double, float>;
235 
236  Visitor visitor
237  {
238  [] (auto e) { return std::to_string (e); }
239  };
240 
241  const auto& res = visitor (Variant_t { 10 });
242  QCOMPARE (res, std::string { "10" });
243  }
244 
245  void VisitorTest::testPrepareRecursiveVisitor ()
246  {
247  using SubVariant_t = boost::variant<int, double, float>;
248  using Variant_t = boost::variant<SubVariant_t, QString>;
249 
250  Visitor visitor
251  {
252  [] (const QString& str) { return str; },
253  Visitor { [] (auto e) { return QString::fromStdString (std::to_string (e)); } }
254  };
255 
256  const auto& res = visitor (Variant_t { SubVariant_t { 10 } });
257  QCOMPARE (res, QString { "10" });
258  }
259 
260  void VisitorTest::testPrepareVisitorMutable ()
261  {
262  Variant_t v { 'a' };
263  Visitor visitor
264  {
265  [] (int) mutable { return true; },
266  [] (auto) mutable { return false; }
267  };
268 
269  const auto& res = visitor (v);
270  QCOMPARE (res, true);
271  }
272 }
273 }
boost::variant< S1, S2 > SVariant_t
Definition: visitortest.cpp:54
auto Visit(const Either< Left, Right > &either, Args &&... args)
Definition: either.h:209
Visitor(Args &&...) -> Visitor< Void, Args... >
#define NC
boost::variant< int, char, std::string, QString, double, float > Variant_t
Definition: visitortest.cpp:40