blob: 20bc9da4d594f4d11fa51379949e8298e5db2b34 [file] [log] [blame]
David Blaikiea28eda7e2013-02-20 00:26:04 +00001//===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
David Blaikiea28eda7e2013-02-20 00:26:04 +000010#include "llvm/ADT/Optional.h"
Chandler Carruth3c0d6072017-06-06 11:06:56 +000011#include "gtest/gtest.h"
Tim Shen4c26d962016-08-11 20:10:15 +000012
David Blaikiea28eda7e2013-02-20 00:26:04 +000013using namespace llvm;
14
15namespace {
16
17struct NonDefaultConstructible {
18 static unsigned CopyConstructions;
19 static unsigned Destructions;
20 static unsigned CopyAssignments;
21 explicit NonDefaultConstructible(int) {
22 }
23 NonDefaultConstructible(const NonDefaultConstructible&) {
24 ++CopyConstructions;
25 }
26 NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
27 ++CopyAssignments;
28 return *this;
29 }
30 ~NonDefaultConstructible() {
31 ++Destructions;
32 }
33 static void ResetCounts() {
34 CopyConstructions = 0;
35 Destructions = 0;
36 CopyAssignments = 0;
37 }
38};
39
40unsigned NonDefaultConstructible::CopyConstructions = 0;
41unsigned NonDefaultConstructible::Destructions = 0;
42unsigned NonDefaultConstructible::CopyAssignments = 0;
43
44// Test fixture
45class OptionalTest : public testing::Test {
46};
47
48TEST_F(OptionalTest, NonDefaultConstructibleTest) {
49 Optional<NonDefaultConstructible> O;
50 EXPECT_FALSE(O);
51}
52
53TEST_F(OptionalTest, ResetTest) {
54 NonDefaultConstructible::ResetCounts();
55 Optional<NonDefaultConstructible> O(NonDefaultConstructible(3));
56 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
57 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
58 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
59 NonDefaultConstructible::ResetCounts();
David Blaikie4318fc52013-02-20 06:25:36 +000060 O.reset();
David Blaikiea28eda7e2013-02-20 00:26:04 +000061 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
62 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
63 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
64}
65
66TEST_F(OptionalTest, InitializationLeakTest) {
67 NonDefaultConstructible::ResetCounts();
68 Optional<NonDefaultConstructible>(NonDefaultConstructible(3));
69 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
70 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
71 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
72}
73
74TEST_F(OptionalTest, CopyConstructionTest) {
75 NonDefaultConstructible::ResetCounts();
76 {
77 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
78 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
79 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
80 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
81 NonDefaultConstructible::ResetCounts();
82 Optional<NonDefaultConstructible> B(A);
83 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
84 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
85 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
86 NonDefaultConstructible::ResetCounts();
87 }
88 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
89 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
90 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
91}
92
93TEST_F(OptionalTest, ConstructingCopyAssignmentTest) {
94 NonDefaultConstructible::ResetCounts();
95 {
96 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
97 Optional<NonDefaultConstructible> B;
98 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
99 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
100 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
101 NonDefaultConstructible::ResetCounts();
102 B = A;
103 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
104 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
105 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
106 NonDefaultConstructible::ResetCounts();
107 }
108 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
109 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
110 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
111}
112
113TEST_F(OptionalTest, CopyingCopyAssignmentTest) {
114 NonDefaultConstructible::ResetCounts();
115 {
116 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
117 Optional<NonDefaultConstructible> B(NonDefaultConstructible(4));
118 EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions);
119 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
120 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
121 NonDefaultConstructible::ResetCounts();
122 B = A;
123 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
124 EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments);
125 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
126 NonDefaultConstructible::ResetCounts();
127 }
128 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
129 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
130 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
131}
132
133TEST_F(OptionalTest, DeletingCopyAssignmentTest) {
134 NonDefaultConstructible::ResetCounts();
135 {
136 Optional<NonDefaultConstructible> A;
137 Optional<NonDefaultConstructible> B(NonDefaultConstructible(3));
138 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
139 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
140 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
141 NonDefaultConstructible::ResetCounts();
142 B = A;
143 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
144 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
145 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
146 NonDefaultConstructible::ResetCounts();
147 }
148 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
149 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
150 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
151}
152
153TEST_F(OptionalTest, NullCopyConstructionTest) {
154 NonDefaultConstructible::ResetCounts();
155 {
156 Optional<NonDefaultConstructible> A;
157 Optional<NonDefaultConstructible> B;
158 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
159 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
160 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
161 NonDefaultConstructible::ResetCounts();
162 B = A;
163 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
164 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
165 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
166 NonDefaultConstructible::ResetCounts();
167 }
168 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
169 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
170 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
171}
172
Jordan Rose88c0ed32014-09-29 18:56:08 +0000173TEST_F(OptionalTest, GetValueOr) {
174 Optional<int> A;
175 EXPECT_EQ(42, A.getValueOr(42));
176
177 A = 5;
178 EXPECT_EQ(5, A.getValueOr(42));
179}
180
Jordan Rose771ac702014-10-01 02:12:35 +0000181struct MultiArgConstructor {
182 int x, y;
183 MultiArgConstructor(int x, int y) : x(x), y(y) {}
184 explicit MultiArgConstructor(int x, bool positive)
185 : x(x), y(positive ? x : -x) {}
186
Aaron Ballman66981fe2015-02-15 22:54:22 +0000187 MultiArgConstructor(const MultiArgConstructor &) = delete;
188 MultiArgConstructor(MultiArgConstructor &&) = delete;
189 MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
190 MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
Jordan Rose771ac702014-10-01 02:12:35 +0000191
192 static unsigned Destructions;
193 ~MultiArgConstructor() {
194 ++Destructions;
195 }
196 static void ResetCounts() {
197 Destructions = 0;
198 }
199};
200unsigned MultiArgConstructor::Destructions = 0;
201
202TEST_F(OptionalTest, Emplace) {
203 MultiArgConstructor::ResetCounts();
204 Optional<MultiArgConstructor> A;
205
206 A.emplace(1, 2);
207 EXPECT_TRUE(A.hasValue());
208 EXPECT_EQ(1, A->x);
209 EXPECT_EQ(2, A->y);
210 EXPECT_EQ(0u, MultiArgConstructor::Destructions);
211
212 A.emplace(5, false);
213 EXPECT_TRUE(A.hasValue());
214 EXPECT_EQ(5, A->x);
215 EXPECT_EQ(-5, A->y);
216 EXPECT_EQ(1u, MultiArgConstructor::Destructions);
217}
218
David Blaikie48574022013-02-21 07:58:45 +0000219struct MoveOnly {
220 static unsigned MoveConstructions;
221 static unsigned Destructions;
222 static unsigned MoveAssignments;
223 int val;
224 explicit MoveOnly(int val) : val(val) {
225 }
226 MoveOnly(MoveOnly&& other) {
227 val = other.val;
228 ++MoveConstructions;
229 }
230 MoveOnly &operator=(MoveOnly&& other) {
231 val = other.val;
232 ++MoveAssignments;
233 return *this;
234 }
235 ~MoveOnly() {
236 ++Destructions;
237 }
238 static void ResetCounts() {
239 MoveConstructions = 0;
240 Destructions = 0;
241 MoveAssignments = 0;
242 }
243};
244
245unsigned MoveOnly::MoveConstructions = 0;
246unsigned MoveOnly::Destructions = 0;
247unsigned MoveOnly::MoveAssignments = 0;
248
David Blaikieea722552013-02-21 07:55:39 +0000249TEST_F(OptionalTest, MoveOnlyNull) {
250 MoveOnly::ResetCounts();
251 Optional<MoveOnly> O;
252 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
253 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
254 EXPECT_EQ(0u, MoveOnly::Destructions);
255}
256
257TEST_F(OptionalTest, MoveOnlyConstruction) {
258 MoveOnly::ResetCounts();
259 Optional<MoveOnly> O(MoveOnly(3));
260 EXPECT_TRUE((bool)O);
261 EXPECT_EQ(3, O->val);
262 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
263 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
264 EXPECT_EQ(1u, MoveOnly::Destructions);
265}
266
267TEST_F(OptionalTest, MoveOnlyMoveConstruction) {
268 Optional<MoveOnly> A(MoveOnly(3));
269 MoveOnly::ResetCounts();
270 Optional<MoveOnly> B(std::move(A));
Benjamin Kramer211131c2018-01-25 17:24:22 +0000271 EXPECT_TRUE((bool)A);
David Blaikieea722552013-02-21 07:55:39 +0000272 EXPECT_TRUE((bool)B);
273 EXPECT_EQ(3, B->val);
274 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
275 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
Benjamin Kramer211131c2018-01-25 17:24:22 +0000276 EXPECT_EQ(0u, MoveOnly::Destructions);
David Blaikieea722552013-02-21 07:55:39 +0000277}
278
279TEST_F(OptionalTest, MoveOnlyAssignment) {
280 MoveOnly::ResetCounts();
281 Optional<MoveOnly> O;
282 O = MoveOnly(3);
283 EXPECT_TRUE((bool)O);
284 EXPECT_EQ(3, O->val);
285 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
286 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
287 EXPECT_EQ(1u, MoveOnly::Destructions);
288}
289
290TEST_F(OptionalTest, MoveOnlyInitializingAssignment) {
291 Optional<MoveOnly> A(MoveOnly(3));
292 Optional<MoveOnly> B;
293 MoveOnly::ResetCounts();
294 B = std::move(A);
Benjamin Kramer211131c2018-01-25 17:24:22 +0000295 EXPECT_TRUE((bool)A);
David Blaikieea722552013-02-21 07:55:39 +0000296 EXPECT_TRUE((bool)B);
297 EXPECT_EQ(3, B->val);
298 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
299 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
Benjamin Kramer211131c2018-01-25 17:24:22 +0000300 EXPECT_EQ(0u, MoveOnly::Destructions);
David Blaikieea722552013-02-21 07:55:39 +0000301}
302
303TEST_F(OptionalTest, MoveOnlyNullingAssignment) {
304 Optional<MoveOnly> A;
305 Optional<MoveOnly> B(MoveOnly(3));
306 MoveOnly::ResetCounts();
307 B = std::move(A);
308 EXPECT_FALSE((bool)A);
309 EXPECT_FALSE((bool)B);
310 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
311 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
312 EXPECT_EQ(1u, MoveOnly::Destructions);
313}
314
315TEST_F(OptionalTest, MoveOnlyAssigningAssignment) {
316 Optional<MoveOnly> A(MoveOnly(3));
317 Optional<MoveOnly> B(MoveOnly(4));
318 MoveOnly::ResetCounts();
319 B = std::move(A);
Benjamin Kramer211131c2018-01-25 17:24:22 +0000320 EXPECT_TRUE((bool)A);
David Blaikieea722552013-02-21 07:55:39 +0000321 EXPECT_TRUE((bool)B);
322 EXPECT_EQ(3, B->val);
323 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
324 EXPECT_EQ(1u, MoveOnly::MoveAssignments);
Benjamin Kramer211131c2018-01-25 17:24:22 +0000325 EXPECT_EQ(0u, MoveOnly::Destructions);
David Blaikieea722552013-02-21 07:55:39 +0000326}
327
David Blaikie7538bab2014-10-01 18:29:44 +0000328struct Immovable {
329 static unsigned Constructions;
330 static unsigned Destructions;
331 int val;
332 explicit Immovable(int val) : val(val) {
333 ++Constructions;
334 }
335 ~Immovable() {
336 ++Destructions;
337 }
338 static void ResetCounts() {
339 Constructions = 0;
340 Destructions = 0;
341 }
342private:
343 // This should disable all move/copy operations.
Aaron Ballman66981fe2015-02-15 22:54:22 +0000344 Immovable(Immovable&& other) = delete;
David Blaikie7538bab2014-10-01 18:29:44 +0000345};
346
347unsigned Immovable::Constructions = 0;
348unsigned Immovable::Destructions = 0;
349
David Blaikie42f40db2014-10-01 21:19:39 +0000350TEST_F(OptionalTest, ImmovableEmplace) {
David Blaikie7538bab2014-10-01 18:29:44 +0000351 Optional<Immovable> A;
352 Immovable::ResetCounts();
Jordan Rose771ac702014-10-01 02:12:35 +0000353 A.emplace(4);
354 EXPECT_TRUE((bool)A);
355 EXPECT_EQ(4, A->val);
David Blaikie7538bab2014-10-01 18:29:44 +0000356 EXPECT_EQ(1u, Immovable::Constructions);
357 EXPECT_EQ(0u, Immovable::Destructions);
Jordan Rose771ac702014-10-01 02:12:35 +0000358}
359
Jordan Rose88c0ed32014-09-29 18:56:08 +0000360#if LLVM_HAS_RVALUE_REFERENCE_THIS
361
362TEST_F(OptionalTest, MoveGetValueOr) {
363 Optional<MoveOnly> A;
364
365 MoveOnly::ResetCounts();
366 EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val);
367 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
368 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
369 EXPECT_EQ(2u, MoveOnly::Destructions);
370
371 A = MoveOnly(5);
372 MoveOnly::ResetCounts();
373 EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val);
374 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
375 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
376 EXPECT_EQ(2u, MoveOnly::Destructions);
377}
378
379#endif // LLVM_HAS_RVALUE_REFERENCE_THIS
380
Tim Shen4c26d962016-08-11 20:10:15 +0000381struct EqualTo {
382 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
383 return X == Y;
384 }
385};
386
387struct NotEqualTo {
388 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
389 return X != Y;
390 }
391};
392
393struct Less {
394 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
395 return X < Y;
396 }
397};
398
399struct Greater {
400 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
401 return X > Y;
402 }
403};
404
405struct LessEqual {
406 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
407 return X <= Y;
408 }
409};
410
411struct GreaterEqual {
412 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
413 return X >= Y;
414 }
415};
416
417template <typename OperatorT, typename T>
418void CheckRelation(const Optional<T> &Lhs, const Optional<T> &Rhs,
419 bool Expected) {
420 EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs));
421
422 if (Lhs)
423 EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs));
424 else
425 EXPECT_EQ(Expected, OperatorT::apply(None, Rhs));
426
427 if (Rhs)
428 EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs));
429 else
430 EXPECT_EQ(Expected, OperatorT::apply(Lhs, None));
431}
432
433struct EqualityMock {};
434const Optional<EqualityMock> NoneEq, EqualityLhs((EqualityMock())),
435 EqualityRhs((EqualityMock()));
436bool IsEqual;
437
438bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) {
439 EXPECT_EQ(&*EqualityLhs, &Lhs);
440 EXPECT_EQ(&*EqualityRhs, &Rhs);
441 return IsEqual;
442}
443
444TEST_F(OptionalTest, OperatorEqual) {
445 CheckRelation<EqualTo>(NoneEq, NoneEq, true);
446 CheckRelation<EqualTo>(NoneEq, EqualityRhs, false);
447 CheckRelation<EqualTo>(EqualityLhs, NoneEq, false);
448
449 IsEqual = false;
450 CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
451 IsEqual = true;
452 CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
453}
454
455TEST_F(OptionalTest, OperatorNotEqual) {
456 CheckRelation<NotEqualTo>(NoneEq, NoneEq, false);
457 CheckRelation<NotEqualTo>(NoneEq, EqualityRhs, true);
458 CheckRelation<NotEqualTo>(EqualityLhs, NoneEq, true);
459
460 IsEqual = false;
461 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
462 IsEqual = true;
463 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
464}
465
466struct InequalityMock {};
467const Optional<InequalityMock> NoneIneq, InequalityLhs((InequalityMock())),
468 InequalityRhs((InequalityMock()));
469bool IsLess;
470
471bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) {
472 EXPECT_EQ(&*InequalityLhs, &Lhs);
473 EXPECT_EQ(&*InequalityRhs, &Rhs);
474 return IsLess;
475}
476
477TEST_F(OptionalTest, OperatorLess) {
478 CheckRelation<Less>(NoneIneq, NoneIneq, false);
479 CheckRelation<Less>(NoneIneq, InequalityRhs, true);
480 CheckRelation<Less>(InequalityLhs, NoneIneq, false);
481
482 IsLess = false;
483 CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
484 IsLess = true;
485 CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
486}
487
488TEST_F(OptionalTest, OperatorGreater) {
489 CheckRelation<Greater>(NoneIneq, NoneIneq, false);
490 CheckRelation<Greater>(NoneIneq, InequalityRhs, false);
491 CheckRelation<Greater>(InequalityLhs, NoneIneq, true);
492
493 IsLess = false;
494 CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
495 IsLess = true;
496 CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
497}
498
499TEST_F(OptionalTest, OperatorLessEqual) {
500 CheckRelation<LessEqual>(NoneIneq, NoneIneq, true);
501 CheckRelation<LessEqual>(NoneIneq, InequalityRhs, true);
502 CheckRelation<LessEqual>(InequalityLhs, NoneIneq, false);
503
504 IsLess = false;
505 CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
506 IsLess = true;
507 CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
508}
509
510TEST_F(OptionalTest, OperatorGreaterEqual) {
511 CheckRelation<GreaterEqual>(NoneIneq, NoneIneq, true);
512 CheckRelation<GreaterEqual>(NoneIneq, InequalityRhs, false);
513 CheckRelation<GreaterEqual>(InequalityLhs, NoneIneq, true);
514
515 IsLess = false;
516 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
517 IsLess = true;
518 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
David Blaikie11683212015-08-19 23:07:27 +0000519}
520
David Blaikiea28eda7e2013-02-20 00:26:04 +0000521} // end anonymous namespace
522