1 // Copyright 2019 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "absl/types/internal/conformance_testing.h"
16
17 #include <new>
18 #include <type_traits>
19 #include <utility>
20
21 #include "gtest/gtest.h"
22 #include "absl/meta/type_traits.h"
23 #include "absl/types/internal/conformance_aliases.h"
24 #include "absl/types/internal/conformance_profile.h"
25
26 namespace {
27
28 namespace ti = absl::types_internal;
29
30 template <class T>
31 using DefaultConstructibleWithNewImpl = decltype(::new (std::nothrow) T);
32
33 template <class T>
34 using DefaultConstructibleWithNew =
35 absl::type_traits_internal::is_detected<DefaultConstructibleWithNewImpl, T>;
36
37 template <class T>
38 using MoveConstructibleWithNewImpl =
39 decltype(::new (std::nothrow) T(std::declval<T>()));
40
41 template <class T>
42 using MoveConstructibleWithNew =
43 absl::type_traits_internal::is_detected<MoveConstructibleWithNewImpl, T>;
44
45 template <class T>
46 using CopyConstructibleWithNewImpl =
47 decltype(::new (std::nothrow) T(std::declval<const T&>()));
48
49 template <class T>
50 using CopyConstructibleWithNew =
51 absl::type_traits_internal::is_detected<CopyConstructibleWithNewImpl, T>;
52
53 template <class T,
54 class Result =
55 std::integral_constant<bool, noexcept(::new (std::nothrow) T)>>
56 using NothrowDefaultConstructibleWithNewImpl =
57 typename std::enable_if<Result::value>::type;
58
59 template <class T>
60 using NothrowDefaultConstructibleWithNew =
61 absl::type_traits_internal::is_detected<
62 NothrowDefaultConstructibleWithNewImpl, T>;
63
64 template <class T,
65 class Result = std::integral_constant<
66 bool, noexcept(::new (std::nothrow) T(std::declval<T>()))>>
67 using NothrowMoveConstructibleWithNewImpl =
68 typename std::enable_if<Result::value>::type;
69
70 template <class T>
71 using NothrowMoveConstructibleWithNew =
72 absl::type_traits_internal::is_detected<NothrowMoveConstructibleWithNewImpl,
73 T>;
74
75 template <class T,
76 class Result = std::integral_constant<
77 bool, noexcept(::new (std::nothrow) T(std::declval<const T&>()))>>
78 using NothrowCopyConstructibleWithNewImpl =
79 typename std::enable_if<Result::value>::type;
80
81 template <class T>
82 using NothrowCopyConstructibleWithNew =
83 absl::type_traits_internal::is_detected<NothrowCopyConstructibleWithNewImpl,
84 T>;
85
86 // NOTE: ?: is used to verify contextually-convertible to bool and not simply
87 // implicit or explicit convertibility.
88 #define ABSL_INTERNAL_COMPARISON_OP_EXPR(op) \
89 ((std::declval<const T&>() op std::declval<const T&>()) ? true : true)
90
91 #define ABSL_INTERNAL_COMPARISON_OP_TRAIT(name, op) \
92 template <class T> \
93 using name##Impl = decltype(ABSL_INTERNAL_COMPARISON_OP_EXPR(op)); \
94 \
95 template <class T> \
96 using name = absl::type_traits_internal::is_detected<name##Impl, T>; \
97 \
98 template <class T, \
99 class Result = std::integral_constant< \
100 bool, noexcept(ABSL_INTERNAL_COMPARISON_OP_EXPR(op))>> \
101 using Nothrow##name##Impl = typename std::enable_if<Result::value>::type; \
102 \
103 template <class T> \
104 using Nothrow##name = \
105 absl::type_traits_internal::is_detected<Nothrow##name##Impl, T>
106
107 ABSL_INTERNAL_COMPARISON_OP_TRAIT(EqualityComparable, ==);
108 ABSL_INTERNAL_COMPARISON_OP_TRAIT(InequalityComparable, !=);
109 ABSL_INTERNAL_COMPARISON_OP_TRAIT(LessThanComparable, <);
110 ABSL_INTERNAL_COMPARISON_OP_TRAIT(LessEqualComparable, <=);
111 ABSL_INTERNAL_COMPARISON_OP_TRAIT(GreaterEqualComparable, >=);
112 ABSL_INTERNAL_COMPARISON_OP_TRAIT(GreaterThanComparable, >);
113
114 #undef ABSL_INTERNAL_COMPARISON_OP_TRAIT
115
116 template <class T>
117 class ProfileTest : public ::testing::Test {};
118
119 TYPED_TEST_SUITE_P(ProfileTest);
120
TYPED_TEST_P(ProfileTest,HasAppropriateConstructionProperties)121 TYPED_TEST_P(ProfileTest, HasAppropriateConstructionProperties) {
122 using profile = typename TypeParam::profile;
123 using arch = typename TypeParam::arch;
124 using expected_profile = typename TypeParam::expected_profile;
125
126 using props = ti::PropertiesOfT<profile>;
127 using arch_props = ti::PropertiesOfArchetypeT<arch>;
128 using expected_props = ti::PropertiesOfT<expected_profile>;
129
130 // Make sure all of the properties are as expected.
131 // There are seemingly redundant tests here to make it easier to diagnose
132 // the specifics of the failure if something were to go wrong.
133 EXPECT_TRUE((std::is_same<props, arch_props>::value));
134 EXPECT_TRUE((std::is_same<props, expected_props>::value));
135 EXPECT_TRUE((std::is_same<arch_props, expected_props>::value));
136
137 EXPECT_EQ(props::default_constructible_support,
138 expected_props::default_constructible_support);
139
140 EXPECT_EQ(props::move_constructible_support,
141 expected_props::move_constructible_support);
142
143 EXPECT_EQ(props::copy_constructible_support,
144 expected_props::copy_constructible_support);
145
146 EXPECT_EQ(props::destructible_support, expected_props::destructible_support);
147
148 // Avoid additional error message noise when profile and archetype match with
149 // each other but were not what was expected.
150 if (!std::is_same<props, arch_props>::value) {
151 EXPECT_EQ(arch_props::default_constructible_support,
152 expected_props::default_constructible_support);
153
154 EXPECT_EQ(arch_props::move_constructible_support,
155 expected_props::move_constructible_support);
156
157 EXPECT_EQ(arch_props::copy_constructible_support,
158 expected_props::copy_constructible_support);
159
160 EXPECT_EQ(arch_props::destructible_support,
161 expected_props::destructible_support);
162 }
163
164 //////////////////////////////////////////////////////////////////////////////
165 // Default constructor checks //
166 //////////////////////////////////////////////////////////////////////////////
167 EXPECT_EQ(props::default_constructible_support,
168 expected_props::default_constructible_support);
169
170 switch (expected_props::default_constructible_support) {
171 case ti::default_constructible::maybe:
172 EXPECT_FALSE(DefaultConstructibleWithNew<arch>::value);
173 EXPECT_FALSE(NothrowDefaultConstructibleWithNew<arch>::value);
174
175 // Standard constructible traits depend on the destructor.
176 if (std::is_destructible<arch>::value) {
177 EXPECT_FALSE(std::is_default_constructible<arch>::value);
178 EXPECT_FALSE(std::is_nothrow_default_constructible<arch>::value);
179 EXPECT_FALSE(absl::is_trivially_default_constructible<arch>::value);
180 }
181 break;
182 case ti::default_constructible::yes:
183 EXPECT_TRUE(DefaultConstructibleWithNew<arch>::value);
184 EXPECT_FALSE(NothrowDefaultConstructibleWithNew<arch>::value);
185
186 // Standard constructible traits depend on the destructor.
187 if (std::is_destructible<arch>::value) {
188 EXPECT_TRUE(std::is_default_constructible<arch>::value);
189 EXPECT_FALSE(std::is_nothrow_default_constructible<arch>::value);
190 EXPECT_FALSE(absl::is_trivially_default_constructible<arch>::value);
191 }
192 break;
193 case ti::default_constructible::nothrow:
194 EXPECT_TRUE(DefaultConstructibleWithNew<arch>::value);
195 EXPECT_TRUE(NothrowDefaultConstructibleWithNew<arch>::value);
196
197 // Standard constructible traits depend on the destructor.
198 if (std::is_destructible<arch>::value) {
199 EXPECT_TRUE(std::is_default_constructible<arch>::value);
200 EXPECT_TRUE(std::is_nothrow_default_constructible<arch>::value);
201 EXPECT_FALSE(absl::is_trivially_default_constructible<arch>::value);
202
203 // Constructor traits also check the destructor.
204 if (std::is_nothrow_destructible<arch>::value) {
205 EXPECT_TRUE(std::is_nothrow_default_constructible<arch>::value);
206 }
207 }
208 break;
209 case ti::default_constructible::trivial:
210 EXPECT_TRUE(DefaultConstructibleWithNew<arch>::value);
211 EXPECT_TRUE(NothrowDefaultConstructibleWithNew<arch>::value);
212
213 // Standard constructible traits depend on the destructor.
214 if (std::is_destructible<arch>::value) {
215 EXPECT_TRUE(std::is_default_constructible<arch>::value);
216 EXPECT_TRUE(std::is_nothrow_default_constructible<arch>::value);
217
218 // Constructor triviality traits require trivially destructible types.
219 if (absl::is_trivially_destructible<arch>::value) {
220 EXPECT_TRUE(absl::is_trivially_default_constructible<arch>::value);
221 }
222 }
223 break;
224 }
225
226 //////////////////////////////////////////////////////////////////////////////
227 // Move constructor checks //
228 //////////////////////////////////////////////////////////////////////////////
229 EXPECT_EQ(props::move_constructible_support,
230 expected_props::move_constructible_support);
231
232 switch (expected_props::move_constructible_support) {
233 case ti::move_constructible::maybe:
234 EXPECT_FALSE(MoveConstructibleWithNew<arch>::value);
235 EXPECT_FALSE(NothrowMoveConstructibleWithNew<arch>::value);
236
237 // Standard constructible traits depend on the destructor.
238 if (std::is_destructible<arch>::value) {
239 EXPECT_FALSE(std::is_move_constructible<arch>::value);
240 EXPECT_FALSE(std::is_nothrow_move_constructible<arch>::value);
241 EXPECT_FALSE(absl::is_trivially_move_constructible<arch>::value);
242 }
243 break;
244 case ti::move_constructible::yes:
245 EXPECT_TRUE(MoveConstructibleWithNew<arch>::value);
246 EXPECT_FALSE(NothrowMoveConstructibleWithNew<arch>::value);
247
248 // Standard constructible traits depend on the destructor.
249 if (std::is_destructible<arch>::value) {
250 EXPECT_TRUE(std::is_move_constructible<arch>::value);
251 EXPECT_FALSE(std::is_nothrow_move_constructible<arch>::value);
252 EXPECT_FALSE(absl::is_trivially_move_constructible<arch>::value);
253 }
254 break;
255 case ti::move_constructible::nothrow:
256 EXPECT_TRUE(MoveConstructibleWithNew<arch>::value);
257 EXPECT_TRUE(NothrowMoveConstructibleWithNew<arch>::value);
258
259 // Standard constructible traits depend on the destructor.
260 if (std::is_destructible<arch>::value) {
261 EXPECT_TRUE(std::is_move_constructible<arch>::value);
262 EXPECT_TRUE(std::is_nothrow_move_constructible<arch>::value);
263 EXPECT_FALSE(absl::is_trivially_move_constructible<arch>::value);
264
265 // Constructor traits also check the destructor.
266 if (std::is_nothrow_destructible<arch>::value) {
267 EXPECT_TRUE(std::is_nothrow_move_constructible<arch>::value);
268 }
269 }
270 break;
271 case ti::move_constructible::trivial:
272 EXPECT_TRUE(MoveConstructibleWithNew<arch>::value);
273 EXPECT_TRUE(NothrowMoveConstructibleWithNew<arch>::value);
274
275 // Standard constructible traits depend on the destructor.
276 if (std::is_destructible<arch>::value) {
277 EXPECT_TRUE(std::is_move_constructible<arch>::value);
278 EXPECT_TRUE(std::is_nothrow_move_constructible<arch>::value);
279
280 // Constructor triviality traits require trivially destructible types.
281 if (absl::is_trivially_destructible<arch>::value) {
282 EXPECT_TRUE(absl::is_trivially_move_constructible<arch>::value);
283 }
284 }
285 break;
286 }
287
288 //////////////////////////////////////////////////////////////////////////////
289 // Copy constructor checks //
290 //////////////////////////////////////////////////////////////////////////////
291 EXPECT_EQ(props::copy_constructible_support,
292 expected_props::copy_constructible_support);
293
294 switch (expected_props::copy_constructible_support) {
295 case ti::copy_constructible::maybe:
296 EXPECT_FALSE(CopyConstructibleWithNew<arch>::value);
297 EXPECT_FALSE(NothrowCopyConstructibleWithNew<arch>::value);
298
299 // Standard constructible traits depend on the destructor.
300 if (std::is_destructible<arch>::value) {
301 EXPECT_FALSE(std::is_copy_constructible<arch>::value);
302 EXPECT_FALSE(std::is_nothrow_copy_constructible<arch>::value);
303 EXPECT_FALSE(absl::is_trivially_copy_constructible<arch>::value);
304 }
305 break;
306 case ti::copy_constructible::yes:
307 EXPECT_TRUE(CopyConstructibleWithNew<arch>::value);
308 EXPECT_FALSE(NothrowCopyConstructibleWithNew<arch>::value);
309
310 // Standard constructible traits depend on the destructor.
311 if (std::is_destructible<arch>::value) {
312 EXPECT_TRUE(std::is_copy_constructible<arch>::value);
313 EXPECT_FALSE(std::is_nothrow_copy_constructible<arch>::value);
314 EXPECT_FALSE(absl::is_trivially_copy_constructible<arch>::value);
315 }
316 break;
317 case ti::copy_constructible::nothrow:
318 EXPECT_TRUE(CopyConstructibleWithNew<arch>::value);
319 EXPECT_TRUE(NothrowCopyConstructibleWithNew<arch>::value);
320
321 // Standard constructible traits depend on the destructor.
322 if (std::is_destructible<arch>::value) {
323 EXPECT_TRUE(std::is_copy_constructible<arch>::value);
324 EXPECT_TRUE(std::is_nothrow_copy_constructible<arch>::value);
325 EXPECT_FALSE(absl::is_trivially_copy_constructible<arch>::value);
326
327 // Constructor traits also check the destructor.
328 if (std::is_nothrow_destructible<arch>::value) {
329 EXPECT_TRUE(std::is_nothrow_copy_constructible<arch>::value);
330 }
331 }
332 break;
333 case ti::copy_constructible::trivial:
334 EXPECT_TRUE(CopyConstructibleWithNew<arch>::value);
335 EXPECT_TRUE(NothrowCopyConstructibleWithNew<arch>::value);
336
337 // Standard constructible traits depend on the destructor.
338 if (std::is_destructible<arch>::value) {
339 EXPECT_TRUE(std::is_copy_constructible<arch>::value);
340 EXPECT_TRUE(std::is_nothrow_copy_constructible<arch>::value);
341
342 // Constructor triviality traits require trivially destructible types.
343 if (absl::is_trivially_destructible<arch>::value) {
344 EXPECT_TRUE(absl::is_trivially_copy_constructible<arch>::value);
345 }
346 }
347 break;
348 }
349
350 //////////////////////////////////////////////////////////////////////////////
351 // Destructible checks //
352 //////////////////////////////////////////////////////////////////////////////
353 EXPECT_EQ(props::destructible_support, expected_props::destructible_support);
354
355 switch (expected_props::destructible_support) {
356 case ti::destructible::maybe:
357 EXPECT_FALSE(std::is_destructible<arch>::value);
358 EXPECT_FALSE(std::is_nothrow_destructible<arch>::value);
359 EXPECT_FALSE(absl::is_trivially_destructible<arch>::value);
360 break;
361 case ti::destructible::yes:
362 EXPECT_TRUE(std::is_destructible<arch>::value);
363 EXPECT_FALSE(std::is_nothrow_destructible<arch>::value);
364 EXPECT_FALSE(absl::is_trivially_destructible<arch>::value);
365 break;
366 case ti::destructible::nothrow:
367 EXPECT_TRUE(std::is_destructible<arch>::value);
368 EXPECT_TRUE(std::is_nothrow_destructible<arch>::value);
369 EXPECT_FALSE(absl::is_trivially_destructible<arch>::value);
370 break;
371 case ti::destructible::trivial:
372 EXPECT_TRUE(std::is_destructible<arch>::value);
373 EXPECT_TRUE(std::is_nothrow_destructible<arch>::value);
374 EXPECT_TRUE(absl::is_trivially_destructible<arch>::value);
375 break;
376 }
377 }
378
TYPED_TEST_P(ProfileTest,HasAppropriateAssignmentProperties)379 TYPED_TEST_P(ProfileTest, HasAppropriateAssignmentProperties) {
380 using profile = typename TypeParam::profile;
381 using arch = typename TypeParam::arch;
382 using expected_profile = typename TypeParam::expected_profile;
383
384 using props = ti::PropertiesOfT<profile>;
385 using arch_props = ti::PropertiesOfArchetypeT<arch>;
386 using expected_props = ti::PropertiesOfT<expected_profile>;
387
388 // Make sure all of the properties are as expected.
389 // There are seemingly redundant tests here to make it easier to diagnose
390 // the specifics of the failure if something were to go wrong.
391 EXPECT_TRUE((std::is_same<props, arch_props>::value));
392 EXPECT_TRUE((std::is_same<props, expected_props>::value));
393 EXPECT_TRUE((std::is_same<arch_props, expected_props>::value));
394
395 EXPECT_EQ(props::move_assignable_support,
396 expected_props::move_assignable_support);
397
398 EXPECT_EQ(props::copy_assignable_support,
399 expected_props::copy_assignable_support);
400
401 // Avoid additional error message noise when profile and archetype match with
402 // each other but were not what was expected.
403 if (!std::is_same<props, arch_props>::value) {
404 EXPECT_EQ(arch_props::move_assignable_support,
405 expected_props::move_assignable_support);
406
407 EXPECT_EQ(arch_props::copy_assignable_support,
408 expected_props::copy_assignable_support);
409 }
410
411 //////////////////////////////////////////////////////////////////////////////
412 // Move assignment checks //
413 //////////////////////////////////////////////////////////////////////////////
414 EXPECT_EQ(props::move_assignable_support,
415 expected_props::move_assignable_support);
416
417 switch (expected_props::move_assignable_support) {
418 case ti::move_assignable::maybe:
419 EXPECT_FALSE(std::is_move_assignable<arch>::value);
420 EXPECT_FALSE(std::is_nothrow_move_assignable<arch>::value);
421 EXPECT_FALSE(absl::is_trivially_move_assignable<arch>::value);
422 break;
423 case ti::move_assignable::yes:
424 EXPECT_TRUE(std::is_move_assignable<arch>::value);
425 EXPECT_FALSE(std::is_nothrow_move_assignable<arch>::value);
426 EXPECT_FALSE(absl::is_trivially_move_assignable<arch>::value);
427 break;
428 case ti::move_assignable::nothrow:
429 EXPECT_TRUE(std::is_move_assignable<arch>::value);
430 EXPECT_TRUE(std::is_nothrow_move_assignable<arch>::value);
431 EXPECT_FALSE(absl::is_trivially_move_assignable<arch>::value);
432 break;
433 case ti::move_assignable::trivial:
434 EXPECT_TRUE(std::is_move_assignable<arch>::value);
435 EXPECT_TRUE(std::is_nothrow_move_assignable<arch>::value);
436 EXPECT_TRUE(absl::is_trivially_move_assignable<arch>::value);
437 break;
438 }
439
440 //////////////////////////////////////////////////////////////////////////////
441 // Copy assignment checks //
442 //////////////////////////////////////////////////////////////////////////////
443 EXPECT_EQ(props::copy_assignable_support,
444 expected_props::copy_assignable_support);
445
446 switch (expected_props::copy_assignable_support) {
447 case ti::copy_assignable::maybe:
448 EXPECT_FALSE(std::is_copy_assignable<arch>::value);
449 EXPECT_FALSE(std::is_nothrow_copy_assignable<arch>::value);
450 EXPECT_FALSE(absl::is_trivially_copy_assignable<arch>::value);
451 break;
452 case ti::copy_assignable::yes:
453 EXPECT_TRUE(std::is_copy_assignable<arch>::value);
454 EXPECT_FALSE(std::is_nothrow_copy_assignable<arch>::value);
455 EXPECT_FALSE(absl::is_trivially_copy_assignable<arch>::value);
456 break;
457 case ti::copy_assignable::nothrow:
458 EXPECT_TRUE(std::is_copy_assignable<arch>::value);
459 EXPECT_TRUE(std::is_nothrow_copy_assignable<arch>::value);
460 EXPECT_FALSE(absl::is_trivially_copy_assignable<arch>::value);
461 break;
462 case ti::copy_assignable::trivial:
463 EXPECT_TRUE(std::is_copy_assignable<arch>::value);
464 EXPECT_TRUE(std::is_nothrow_copy_assignable<arch>::value);
465 EXPECT_TRUE(absl::is_trivially_copy_assignable<arch>::value);
466 break;
467 }
468 }
469
TYPED_TEST_P(ProfileTest,HasAppropriateComparisonProperties)470 TYPED_TEST_P(ProfileTest, HasAppropriateComparisonProperties) {
471 using profile = typename TypeParam::profile;
472 using arch = typename TypeParam::arch;
473 using expected_profile = typename TypeParam::expected_profile;
474
475 using props = ti::PropertiesOfT<profile>;
476 using arch_props = ti::PropertiesOfArchetypeT<arch>;
477 using expected_props = ti::PropertiesOfT<expected_profile>;
478
479 // Make sure all of the properties are as expected.
480 // There are seemingly redundant tests here to make it easier to diagnose
481 // the specifics of the failure if something were to go wrong.
482 EXPECT_TRUE((std::is_same<props, arch_props>::value));
483 EXPECT_TRUE((std::is_same<props, expected_props>::value));
484 EXPECT_TRUE((std::is_same<arch_props, expected_props>::value));
485
486 EXPECT_EQ(props::equality_comparable_support,
487 expected_props::equality_comparable_support);
488
489 EXPECT_EQ(props::inequality_comparable_support,
490 expected_props::inequality_comparable_support);
491
492 EXPECT_EQ(props::less_than_comparable_support,
493 expected_props::less_than_comparable_support);
494
495 EXPECT_EQ(props::less_equal_comparable_support,
496 expected_props::less_equal_comparable_support);
497
498 EXPECT_EQ(props::greater_equal_comparable_support,
499 expected_props::greater_equal_comparable_support);
500
501 EXPECT_EQ(props::greater_than_comparable_support,
502 expected_props::greater_than_comparable_support);
503
504 // Avoid additional error message noise when profile and archetype match with
505 // each other but were not what was expected.
506 if (!std::is_same<props, arch_props>::value) {
507 EXPECT_EQ(arch_props::equality_comparable_support,
508 expected_props::equality_comparable_support);
509
510 EXPECT_EQ(arch_props::inequality_comparable_support,
511 expected_props::inequality_comparable_support);
512
513 EXPECT_EQ(arch_props::less_than_comparable_support,
514 expected_props::less_than_comparable_support);
515
516 EXPECT_EQ(arch_props::less_equal_comparable_support,
517 expected_props::less_equal_comparable_support);
518
519 EXPECT_EQ(arch_props::greater_equal_comparable_support,
520 expected_props::greater_equal_comparable_support);
521
522 EXPECT_EQ(arch_props::greater_than_comparable_support,
523 expected_props::greater_than_comparable_support);
524 }
525
526 //////////////////////////////////////////////////////////////////////////////
527 // Equality comparable checks //
528 //////////////////////////////////////////////////////////////////////////////
529 switch (expected_props::equality_comparable_support) {
530 case ti::equality_comparable::maybe:
531 EXPECT_FALSE(EqualityComparable<arch>::value);
532 EXPECT_FALSE(NothrowEqualityComparable<arch>::value);
533 break;
534 case ti::equality_comparable::yes:
535 EXPECT_TRUE(EqualityComparable<arch>::value);
536 EXPECT_FALSE(NothrowEqualityComparable<arch>::value);
537 break;
538 case ti::equality_comparable::nothrow:
539 EXPECT_TRUE(EqualityComparable<arch>::value);
540 EXPECT_TRUE(NothrowEqualityComparable<arch>::value);
541 break;
542 }
543
544 //////////////////////////////////////////////////////////////////////////////
545 // Inequality comparable checks //
546 //////////////////////////////////////////////////////////////////////////////
547 switch (expected_props::inequality_comparable_support) {
548 case ti::inequality_comparable::maybe:
549 EXPECT_FALSE(InequalityComparable<arch>::value);
550 EXPECT_FALSE(NothrowInequalityComparable<arch>::value);
551 break;
552 case ti::inequality_comparable::yes:
553 EXPECT_TRUE(InequalityComparable<arch>::value);
554 EXPECT_FALSE(NothrowInequalityComparable<arch>::value);
555 break;
556 case ti::inequality_comparable::nothrow:
557 EXPECT_TRUE(InequalityComparable<arch>::value);
558 EXPECT_TRUE(NothrowInequalityComparable<arch>::value);
559 break;
560 }
561
562 //////////////////////////////////////////////////////////////////////////////
563 // Less than comparable checks //
564 //////////////////////////////////////////////////////////////////////////////
565 switch (expected_props::less_than_comparable_support) {
566 case ti::less_than_comparable::maybe:
567 EXPECT_FALSE(LessThanComparable<arch>::value);
568 EXPECT_FALSE(NothrowLessThanComparable<arch>::value);
569 break;
570 case ti::less_than_comparable::yes:
571 EXPECT_TRUE(LessThanComparable<arch>::value);
572 EXPECT_FALSE(NothrowLessThanComparable<arch>::value);
573 break;
574 case ti::less_than_comparable::nothrow:
575 EXPECT_TRUE(LessThanComparable<arch>::value);
576 EXPECT_TRUE(NothrowLessThanComparable<arch>::value);
577 break;
578 }
579
580 //////////////////////////////////////////////////////////////////////////////
581 // Less equal comparable checks //
582 //////////////////////////////////////////////////////////////////////////////
583 switch (expected_props::less_equal_comparable_support) {
584 case ti::less_equal_comparable::maybe:
585 EXPECT_FALSE(LessEqualComparable<arch>::value);
586 EXPECT_FALSE(NothrowLessEqualComparable<arch>::value);
587 break;
588 case ti::less_equal_comparable::yes:
589 EXPECT_TRUE(LessEqualComparable<arch>::value);
590 EXPECT_FALSE(NothrowLessEqualComparable<arch>::value);
591 break;
592 case ti::less_equal_comparable::nothrow:
593 EXPECT_TRUE(LessEqualComparable<arch>::value);
594 EXPECT_TRUE(NothrowLessEqualComparable<arch>::value);
595 break;
596 }
597
598 //////////////////////////////////////////////////////////////////////////////
599 // Greater equal comparable checks //
600 //////////////////////////////////////////////////////////////////////////////
601 switch (expected_props::greater_equal_comparable_support) {
602 case ti::greater_equal_comparable::maybe:
603 EXPECT_FALSE(GreaterEqualComparable<arch>::value);
604 EXPECT_FALSE(NothrowGreaterEqualComparable<arch>::value);
605 break;
606 case ti::greater_equal_comparable::yes:
607 EXPECT_TRUE(GreaterEqualComparable<arch>::value);
608 EXPECT_FALSE(NothrowGreaterEqualComparable<arch>::value);
609 break;
610 case ti::greater_equal_comparable::nothrow:
611 EXPECT_TRUE(GreaterEqualComparable<arch>::value);
612 EXPECT_TRUE(NothrowGreaterEqualComparable<arch>::value);
613 break;
614 }
615
616 //////////////////////////////////////////////////////////////////////////////
617 // Greater than comparable checks //
618 //////////////////////////////////////////////////////////////////////////////
619 switch (expected_props::greater_than_comparable_support) {
620 case ti::greater_than_comparable::maybe:
621 EXPECT_FALSE(GreaterThanComparable<arch>::value);
622 EXPECT_FALSE(NothrowGreaterThanComparable<arch>::value);
623 break;
624 case ti::greater_than_comparable::yes:
625 EXPECT_TRUE(GreaterThanComparable<arch>::value);
626 EXPECT_FALSE(NothrowGreaterThanComparable<arch>::value);
627 break;
628 case ti::greater_than_comparable::nothrow:
629 EXPECT_TRUE(GreaterThanComparable<arch>::value);
630 EXPECT_TRUE(NothrowGreaterThanComparable<arch>::value);
631 break;
632 }
633 }
634
TYPED_TEST_P(ProfileTest,HasAppropriateAuxilliaryProperties)635 TYPED_TEST_P(ProfileTest, HasAppropriateAuxilliaryProperties) {
636 using profile = typename TypeParam::profile;
637 using arch = typename TypeParam::arch;
638 using expected_profile = typename TypeParam::expected_profile;
639
640 using props = ti::PropertiesOfT<profile>;
641 using arch_props = ti::PropertiesOfArchetypeT<arch>;
642 using expected_props = ti::PropertiesOfT<expected_profile>;
643
644 // Make sure all of the properties are as expected.
645 // There are seemingly redundant tests here to make it easier to diagnose
646 // the specifics of the failure if something were to go wrong.
647 EXPECT_TRUE((std::is_same<props, arch_props>::value));
648 EXPECT_TRUE((std::is_same<props, expected_props>::value));
649 EXPECT_TRUE((std::is_same<arch_props, expected_props>::value));
650
651 EXPECT_EQ(props::swappable_support, expected_props::swappable_support);
652
653 EXPECT_EQ(props::hashable_support, expected_props::hashable_support);
654
655 // Avoid additional error message noise when profile and archetype match with
656 // each other but were not what was expected.
657 if (!std::is_same<props, arch_props>::value) {
658 EXPECT_EQ(arch_props::swappable_support, expected_props::swappable_support);
659
660 EXPECT_EQ(arch_props::hashable_support, expected_props::hashable_support);
661 }
662
663 //////////////////////////////////////////////////////////////////////////////
664 // Swappable checks //
665 //////////////////////////////////////////////////////////////////////////////
666 switch (expected_props::swappable_support) {
667 case ti::swappable::maybe:
668 EXPECT_FALSE(absl::type_traits_internal::IsSwappable<arch>::value);
669 EXPECT_FALSE(absl::type_traits_internal::IsNothrowSwappable<arch>::value);
670 break;
671 case ti::swappable::yes:
672 EXPECT_TRUE(absl::type_traits_internal::IsSwappable<arch>::value);
673 EXPECT_FALSE(absl::type_traits_internal::IsNothrowSwappable<arch>::value);
674 break;
675 case ti::swappable::nothrow:
676 EXPECT_TRUE(absl::type_traits_internal::IsSwappable<arch>::value);
677 EXPECT_TRUE(absl::type_traits_internal::IsNothrowSwappable<arch>::value);
678 break;
679 }
680
681 //////////////////////////////////////////////////////////////////////////////
682 // Hashable checks //
683 //////////////////////////////////////////////////////////////////////////////
684 switch (expected_props::hashable_support) {
685 case ti::hashable::maybe:
686 #if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
687 EXPECT_FALSE(absl::type_traits_internal::IsHashable<arch>::value);
688 #endif // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
689 break;
690 case ti::hashable::yes:
691 EXPECT_TRUE(absl::type_traits_internal::IsHashable<arch>::value);
692 break;
693 }
694 }
695
696 REGISTER_TYPED_TEST_SUITE_P(ProfileTest, HasAppropriateConstructionProperties,
697 HasAppropriateAssignmentProperties,
698 HasAppropriateComparisonProperties,
699 HasAppropriateAuxilliaryProperties);
700
701 template <class Profile, class Arch, class ExpectedProfile>
702 struct ProfileAndExpectation {
703 using profile = Profile;
704 using arch = Arch;
705 using expected_profile = ExpectedProfile;
706 };
707
708 using CoreProfilesToTest = ::testing::Types<
709 // The terminating case of combine (all properties are "maybe").
710 ProfileAndExpectation<ti::CombineProfiles<>,
711 ti::Archetype<ti::CombineProfiles<>>,
712 ti::ConformanceProfile<>>,
713
714 // Core default constructor profiles
715 ProfileAndExpectation<
716 ti::HasDefaultConstructorProfile, ti::HasDefaultConstructorArchetype,
717 ti::ConformanceProfile<ti::default_constructible::yes>>,
718 ProfileAndExpectation<
719 ti::HasNothrowDefaultConstructorProfile,
720 ti::HasNothrowDefaultConstructorArchetype,
721 ti::ConformanceProfile<ti::default_constructible::nothrow>>,
722 ProfileAndExpectation<
723 ti::HasTrivialDefaultConstructorProfile,
724 ti::HasTrivialDefaultConstructorArchetype,
725 ti::ConformanceProfile<ti::default_constructible::trivial>>,
726
727 // Core move constructor profiles
728 ProfileAndExpectation<
729 ti::HasMoveConstructorProfile, ti::HasMoveConstructorArchetype,
730 ti::ConformanceProfile<ti::default_constructible::maybe,
731 ti::move_constructible::yes>>,
732 ProfileAndExpectation<
733 ti::HasNothrowMoveConstructorProfile,
734 ti::HasNothrowMoveConstructorArchetype,
735 ti::ConformanceProfile<ti::default_constructible::maybe,
736 ti::move_constructible::nothrow>>,
737 ProfileAndExpectation<
738 ti::HasTrivialMoveConstructorProfile,
739 ti::HasTrivialMoveConstructorArchetype,
740 ti::ConformanceProfile<ti::default_constructible::maybe,
741 ti::move_constructible::trivial>>,
742
743 // Core copy constructor profiles
744 ProfileAndExpectation<
745 ti::HasCopyConstructorProfile, ti::HasCopyConstructorArchetype,
746 ti::ConformanceProfile<ti::default_constructible::maybe,
747 ti::move_constructible::maybe,
748 ti::copy_constructible::yes>>,
749 ProfileAndExpectation<
750 ti::HasNothrowCopyConstructorProfile,
751 ti::HasNothrowCopyConstructorArchetype,
752 ti::ConformanceProfile<ti::default_constructible::maybe,
753 ti::move_constructible::maybe,
754 ti::copy_constructible::nothrow>>,
755 ProfileAndExpectation<
756 ti::HasTrivialCopyConstructorProfile,
757 ti::HasTrivialCopyConstructorArchetype,
758 ti::ConformanceProfile<ti::default_constructible::maybe,
759 ti::move_constructible::maybe,
760 ti::copy_constructible::trivial>>,
761
762 // Core move assignment profiles
763 ProfileAndExpectation<
764 ti::HasMoveAssignProfile, ti::HasMoveAssignArchetype,
765 ti::ConformanceProfile<
766 ti::default_constructible::maybe, ti::move_constructible::maybe,
767 ti::copy_constructible::maybe, ti::move_assignable::yes>>,
768 ProfileAndExpectation<
769 ti::HasNothrowMoveAssignProfile, ti::HasNothrowMoveAssignArchetype,
770 ti::ConformanceProfile<
771 ti::default_constructible::maybe, ti::move_constructible::maybe,
772 ti::copy_constructible::maybe, ti::move_assignable::nothrow>>,
773 ProfileAndExpectation<
774 ti::HasTrivialMoveAssignProfile, ti::HasTrivialMoveAssignArchetype,
775 ti::ConformanceProfile<
776 ti::default_constructible::maybe, ti::move_constructible::maybe,
777 ti::copy_constructible::maybe, ti::move_assignable::trivial>>,
778
779 // Core copy assignment profiles
780 ProfileAndExpectation<
781 ti::HasCopyAssignProfile, ti::HasCopyAssignArchetype,
782 ti::ConformanceProfile<
783 ti::default_constructible::maybe, ti::move_constructible::maybe,
784 ti::copy_constructible::maybe, ti::move_assignable::maybe,
785 ti::copy_assignable::yes>>,
786 ProfileAndExpectation<
787 ti::HasNothrowCopyAssignProfile, ti::HasNothrowCopyAssignArchetype,
788 ti::ConformanceProfile<
789 ti::default_constructible::maybe, ti::move_constructible::maybe,
790 ti::copy_constructible::maybe, ti::move_assignable::maybe,
791 ti::copy_assignable::nothrow>>,
792 ProfileAndExpectation<
793 ti::HasTrivialCopyAssignProfile, ti::HasTrivialCopyAssignArchetype,
794 ti::ConformanceProfile<
795 ti::default_constructible::maybe, ti::move_constructible::maybe,
796 ti::copy_constructible::maybe, ti::move_assignable::maybe,
797 ti::copy_assignable::trivial>>,
798
799 // Core destructor profiles
800 ProfileAndExpectation<
801 ti::HasDestructorProfile, ti::HasDestructorArchetype,
802 ti::ConformanceProfile<
803 ti::default_constructible::maybe, ti::move_constructible::maybe,
804 ti::copy_constructible::maybe, ti::move_assignable::maybe,
805 ti::copy_assignable::maybe, ti::destructible::yes>>,
806 ProfileAndExpectation<
807 ti::HasNothrowDestructorProfile, ti::HasNothrowDestructorArchetype,
808 ti::ConformanceProfile<
809 ti::default_constructible::maybe, ti::move_constructible::maybe,
810 ti::copy_constructible::maybe, ti::move_assignable::maybe,
811 ti::copy_assignable::maybe, ti::destructible::nothrow>>,
812 ProfileAndExpectation<
813 ti::HasTrivialDestructorProfile, ti::HasTrivialDestructorArchetype,
814 ti::ConformanceProfile<
815 ti::default_constructible::maybe, ti::move_constructible::maybe,
816 ti::copy_constructible::maybe, ti::move_assignable::maybe,
817 ti::copy_assignable::maybe, ti::destructible::trivial>>,
818
819 // Core equality comparable profiles
820 ProfileAndExpectation<
821 ti::HasEqualityProfile, ti::HasEqualityArchetype,
822 ti::ConformanceProfile<
823 ti::default_constructible::maybe, ti::move_constructible::maybe,
824 ti::copy_constructible::maybe, ti::move_assignable::maybe,
825 ti::copy_assignable::maybe, ti::destructible::maybe,
826 ti::equality_comparable::yes>>,
827 ProfileAndExpectation<
828 ti::HasNothrowEqualityProfile, ti::HasNothrowEqualityArchetype,
829 ti::ConformanceProfile<
830 ti::default_constructible::maybe, ti::move_constructible::maybe,
831 ti::copy_constructible::maybe, ti::move_assignable::maybe,
832 ti::copy_assignable::maybe, ti::destructible::maybe,
833 ti::equality_comparable::nothrow>>,
834
835 // Core inequality comparable profiles
836 ProfileAndExpectation<
837 ti::HasInequalityProfile, ti::HasInequalityArchetype,
838 ti::ConformanceProfile<
839 ti::default_constructible::maybe, ti::move_constructible::maybe,
840 ti::copy_constructible::maybe, ti::move_assignable::maybe,
841 ti::copy_assignable::maybe, ti::destructible::maybe,
842 ti::equality_comparable::maybe, ti::inequality_comparable::yes>>,
843 ProfileAndExpectation<
844 ti::HasNothrowInequalityProfile, ti::HasNothrowInequalityArchetype,
845 ti::ConformanceProfile<
846 ti::default_constructible::maybe, ti::move_constructible::maybe,
847 ti::copy_constructible::maybe, ti::move_assignable::maybe,
848 ti::copy_assignable::maybe, ti::destructible::maybe,
849 ti::equality_comparable::maybe,
850 ti::inequality_comparable::nothrow>>,
851
852 // Core less than comparable profiles
853 ProfileAndExpectation<
854 ti::HasLessThanProfile, ti::HasLessThanArchetype,
855 ti::ConformanceProfile<
856 ti::default_constructible::maybe, ti::move_constructible::maybe,
857 ti::copy_constructible::maybe, ti::move_assignable::maybe,
858 ti::copy_assignable::maybe, ti::destructible::maybe,
859 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
860 ti::less_than_comparable::yes>>,
861 ProfileAndExpectation<
862 ti::HasNothrowLessThanProfile, ti::HasNothrowLessThanArchetype,
863 ti::ConformanceProfile<
864 ti::default_constructible::maybe, ti::move_constructible::maybe,
865 ti::copy_constructible::maybe, ti::move_assignable::maybe,
866 ti::copy_assignable::maybe, ti::destructible::maybe,
867 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
868 ti::less_than_comparable::nothrow>>,
869
870 // Core less equal comparable profiles
871 ProfileAndExpectation<
872 ti::HasLessEqualProfile, ti::HasLessEqualArchetype,
873 ti::ConformanceProfile<
874 ti::default_constructible::maybe, ti::move_constructible::maybe,
875 ti::copy_constructible::maybe, ti::move_assignable::maybe,
876 ti::copy_assignable::maybe, ti::destructible::maybe,
877 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
878 ti::less_than_comparable::maybe, ti::less_equal_comparable::yes>>,
879 ProfileAndExpectation<
880 ti::HasNothrowLessEqualProfile, ti::HasNothrowLessEqualArchetype,
881 ti::ConformanceProfile<
882 ti::default_constructible::maybe, ti::move_constructible::maybe,
883 ti::copy_constructible::maybe, ti::move_assignable::maybe,
884 ti::copy_assignable::maybe, ti::destructible::maybe,
885 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
886 ti::less_than_comparable::maybe,
887 ti::less_equal_comparable::nothrow>>,
888
889 // Core greater equal comparable profiles
890 ProfileAndExpectation<
891 ti::HasGreaterEqualProfile, ti::HasGreaterEqualArchetype,
892 ti::ConformanceProfile<
893 ti::default_constructible::maybe, ti::move_constructible::maybe,
894 ti::copy_constructible::maybe, ti::move_assignable::maybe,
895 ti::copy_assignable::maybe, ti::destructible::maybe,
896 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
897 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
898 ti::greater_equal_comparable::yes>>,
899 ProfileAndExpectation<
900 ti::HasNothrowGreaterEqualProfile, ti::HasNothrowGreaterEqualArchetype,
901 ti::ConformanceProfile<
902 ti::default_constructible::maybe, ti::move_constructible::maybe,
903 ti::copy_constructible::maybe, ti::move_assignable::maybe,
904 ti::copy_assignable::maybe, ti::destructible::maybe,
905 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
906 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
907 ti::greater_equal_comparable::nothrow>>,
908
909 // Core greater than comparable profiles
910 ProfileAndExpectation<
911 ti::HasGreaterThanProfile, ti::HasGreaterThanArchetype,
912 ti::ConformanceProfile<
913 ti::default_constructible::maybe, ti::move_constructible::maybe,
914 ti::copy_constructible::maybe, ti::move_assignable::maybe,
915 ti::copy_assignable::maybe, ti::destructible::maybe,
916 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
917 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
918 ti::greater_equal_comparable::maybe,
919 ti::greater_than_comparable::yes>>,
920 ProfileAndExpectation<
921 ti::HasNothrowGreaterThanProfile, ti::HasNothrowGreaterThanArchetype,
922 ti::ConformanceProfile<
923 ti::default_constructible::maybe, ti::move_constructible::maybe,
924 ti::copy_constructible::maybe, ti::move_assignable::maybe,
925 ti::copy_assignable::maybe, ti::destructible::maybe,
926 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
927 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
928 ti::greater_equal_comparable::maybe,
929 ti::greater_than_comparable::nothrow>>,
930
931 // Core swappable profiles
932 ProfileAndExpectation<
933 ti::HasSwapProfile, ti::HasSwapArchetype,
934 ti::ConformanceProfile<
935 ti::default_constructible::maybe, ti::move_constructible::maybe,
936 ti::copy_constructible::maybe, ti::move_assignable::maybe,
937 ti::copy_assignable::maybe, ti::destructible::maybe,
938 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
939 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
940 ti::greater_equal_comparable::maybe,
941 ti::greater_than_comparable::maybe, ti::swappable::yes>>,
942 ProfileAndExpectation<
943 ti::HasNothrowSwapProfile, ti::HasNothrowSwapArchetype,
944 ti::ConformanceProfile<
945 ti::default_constructible::maybe, ti::move_constructible::maybe,
946 ti::copy_constructible::maybe, ti::move_assignable::maybe,
947 ti::copy_assignable::maybe, ti::destructible::maybe,
948 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
949 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
950 ti::greater_equal_comparable::maybe,
951 ti::greater_than_comparable::maybe, ti::swappable::nothrow>>,
952
953 // Core hashable profiles
954 ProfileAndExpectation<
955 ti::HasStdHashSpecializationProfile,
956 ti::HasStdHashSpecializationArchetype,
957 ti::ConformanceProfile<
958 ti::default_constructible::maybe, ti::move_constructible::maybe,
959 ti::copy_constructible::maybe, ti::move_assignable::maybe,
960 ti::copy_assignable::maybe, ti::destructible::maybe,
961 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
962 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
963 ti::greater_equal_comparable::maybe,
964 ti::greater_than_comparable::maybe, ti::swappable::maybe,
965 ti::hashable::yes>>>;
966
967 using CommonProfilesToTest = ::testing::Types<
968 // NothrowMoveConstructible
969 ProfileAndExpectation<
970 ti::NothrowMoveConstructibleProfile,
971 ti::NothrowMoveConstructibleArchetype,
972 ti::ConformanceProfile<
973 ti::default_constructible::maybe, ti::move_constructible::nothrow,
974 ti::copy_constructible::maybe, ti::move_assignable::maybe,
975 ti::copy_assignable::maybe, ti::destructible::nothrow>>,
976
977 // CopyConstructible
978 ProfileAndExpectation<
979 ti::CopyConstructibleProfile, ti::CopyConstructibleArchetype,
980 ti::ConformanceProfile<
981 ti::default_constructible::maybe, ti::move_constructible::nothrow,
982 ti::copy_constructible::yes, ti::move_assignable::maybe,
983 ti::copy_assignable::maybe, ti::destructible::nothrow>>,
984
985 // NothrowMovable
986 ProfileAndExpectation<
987 ti::NothrowMovableProfile, ti::NothrowMovableArchetype,
988 ti::ConformanceProfile<
989 ti::default_constructible::maybe, ti::move_constructible::nothrow,
990 ti::copy_constructible::maybe, ti::move_assignable::nothrow,
991 ti::copy_assignable::maybe, ti::destructible::nothrow,
992 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
993 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
994 ti::greater_equal_comparable::maybe,
995 ti::greater_than_comparable::maybe, ti::swappable::nothrow>>,
996
997 // Value
998 ProfileAndExpectation<
999 ti::ValueProfile, ti::ValueArchetype,
1000 ti::ConformanceProfile<
1001 ti::default_constructible::maybe, ti::move_constructible::nothrow,
1002 ti::copy_constructible::yes, ti::move_assignable::nothrow,
1003 ti::copy_assignable::yes, ti::destructible::nothrow,
1004 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
1005 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
1006 ti::greater_equal_comparable::maybe,
1007 ti::greater_than_comparable::maybe, ti::swappable::nothrow>>,
1008
1009 ////////////////////////////////////////////////////////////////////////////
1010 // Common but also DefaultConstructible //
1011 ////////////////////////////////////////////////////////////////////////////
1012
1013 // DefaultConstructibleNothrowMoveConstructible
1014 ProfileAndExpectation<
1015 ti::DefaultConstructibleNothrowMoveConstructibleProfile,
1016 ti::DefaultConstructibleNothrowMoveConstructibleArchetype,
1017 ti::ConformanceProfile<
1018 ti::default_constructible::yes, ti::move_constructible::nothrow,
1019 ti::copy_constructible::maybe, ti::move_assignable::maybe,
1020 ti::copy_assignable::maybe, ti::destructible::nothrow>>,
1021
1022 // DefaultConstructibleCopyConstructible
1023 ProfileAndExpectation<
1024 ti::DefaultConstructibleCopyConstructibleProfile,
1025 ti::DefaultConstructibleCopyConstructibleArchetype,
1026 ti::ConformanceProfile<
1027 ti::default_constructible::yes, ti::move_constructible::nothrow,
1028 ti::copy_constructible::yes, ti::move_assignable::maybe,
1029 ti::copy_assignable::maybe, ti::destructible::nothrow>>,
1030
1031 // DefaultConstructibleNothrowMovable
1032 ProfileAndExpectation<
1033 ti::DefaultConstructibleNothrowMovableProfile,
1034 ti::DefaultConstructibleNothrowMovableArchetype,
1035 ti::ConformanceProfile<
1036 ti::default_constructible::yes, ti::move_constructible::nothrow,
1037 ti::copy_constructible::maybe, ti::move_assignable::nothrow,
1038 ti::copy_assignable::maybe, ti::destructible::nothrow,
1039 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
1040 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
1041 ti::greater_equal_comparable::maybe,
1042 ti::greater_than_comparable::maybe, ti::swappable::nothrow>>,
1043
1044 // DefaultConstructibleValue
1045 ProfileAndExpectation<
1046 ti::DefaultConstructibleValueProfile,
1047 ti::DefaultConstructibleValueArchetype,
1048 ti::ConformanceProfile<
1049 ti::default_constructible::yes, ti::move_constructible::nothrow,
1050 ti::copy_constructible::yes, ti::move_assignable::nothrow,
1051 ti::copy_assignable::yes, ti::destructible::nothrow,
1052 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
1053 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
1054 ti::greater_equal_comparable::maybe,
1055 ti::greater_than_comparable::maybe, ti::swappable::nothrow>>>;
1056
1057 using ComparableHelpersProfilesToTest = ::testing::Types<
1058 // Equatable
1059 ProfileAndExpectation<
1060 ti::EquatableProfile, ti::EquatableArchetype,
1061 ti::ConformanceProfile<
1062 ti::default_constructible::maybe, ti::move_constructible::maybe,
1063 ti::copy_constructible::maybe, ti::move_assignable::maybe,
1064 ti::copy_assignable::maybe, ti::destructible::maybe,
1065 ti::equality_comparable::yes, ti::inequality_comparable::yes>>,
1066
1067 // Comparable
1068 ProfileAndExpectation<
1069 ti::ComparableProfile, ti::ComparableArchetype,
1070 ti::ConformanceProfile<
1071 ti::default_constructible::maybe, ti::move_constructible::maybe,
1072 ti::copy_constructible::maybe, ti::move_assignable::maybe,
1073 ti::copy_assignable::maybe, ti::destructible::maybe,
1074 ti::equality_comparable::yes, ti::inequality_comparable::yes,
1075 ti::less_than_comparable::yes, ti::less_equal_comparable::yes,
1076 ti::greater_equal_comparable::yes,
1077 ti::greater_than_comparable::yes>>,
1078
1079 // NothrowEquatable
1080 ProfileAndExpectation<
1081 ti::NothrowEquatableProfile, ti::NothrowEquatableArchetype,
1082 ti::ConformanceProfile<
1083 ti::default_constructible::maybe, ti::move_constructible::maybe,
1084 ti::copy_constructible::maybe, ti::move_assignable::maybe,
1085 ti::copy_assignable::maybe, ti::destructible::maybe,
1086 ti::equality_comparable::nothrow,
1087 ti::inequality_comparable::nothrow>>,
1088
1089 // NothrowComparable
1090 ProfileAndExpectation<
1091 ti::NothrowComparableProfile, ti::NothrowComparableArchetype,
1092 ti::ConformanceProfile<
1093 ti::default_constructible::maybe, ti::move_constructible::maybe,
1094 ti::copy_constructible::maybe, ti::move_assignable::maybe,
1095 ti::copy_assignable::maybe, ti::destructible::maybe,
1096 ti::equality_comparable::nothrow,
1097 ti::inequality_comparable::nothrow,
1098 ti::less_than_comparable::nothrow,
1099 ti::less_equal_comparable::nothrow,
1100 ti::greater_equal_comparable::nothrow,
1101 ti::greater_than_comparable::nothrow>>>;
1102
1103 using CommonComparableProfilesToTest = ::testing::Types<
1104 // ComparableNothrowMoveConstructible
1105 ProfileAndExpectation<
1106 ti::ComparableNothrowMoveConstructibleProfile,
1107 ti::ComparableNothrowMoveConstructibleArchetype,
1108 ti::ConformanceProfile<
1109 ti::default_constructible::maybe, ti::move_constructible::nothrow,
1110 ti::copy_constructible::maybe, ti::move_assignable::maybe,
1111 ti::copy_assignable::maybe, ti::destructible::nothrow,
1112 ti::equality_comparable::yes, ti::inequality_comparable::yes,
1113 ti::less_than_comparable::yes, ti::less_equal_comparable::yes,
1114 ti::greater_equal_comparable::yes,
1115 ti::greater_than_comparable::yes>>,
1116
1117 // ComparableCopyConstructible
1118 ProfileAndExpectation<
1119 ti::ComparableCopyConstructibleProfile,
1120 ti::ComparableCopyConstructibleArchetype,
1121 ti::ConformanceProfile<
1122 ti::default_constructible::maybe, ti::move_constructible::nothrow,
1123 ti::copy_constructible::yes, ti::move_assignable::maybe,
1124 ti::copy_assignable::maybe, ti::destructible::nothrow,
1125 ti::equality_comparable::yes, ti::inequality_comparable::yes,
1126 ti::less_than_comparable::yes, ti::less_equal_comparable::yes,
1127 ti::greater_equal_comparable::yes,
1128 ti::greater_than_comparable::yes>>,
1129
1130 // ComparableNothrowMovable
1131 ProfileAndExpectation<
1132 ti::ComparableNothrowMovableProfile,
1133 ti::ComparableNothrowMovableArchetype,
1134 ti::ConformanceProfile<
1135 ti::default_constructible::maybe, ti::move_constructible::nothrow,
1136 ti::copy_constructible::maybe, ti::move_assignable::nothrow,
1137 ti::copy_assignable::maybe, ti::destructible::nothrow,
1138 ti::equality_comparable::yes, ti::inequality_comparable::yes,
1139 ti::less_than_comparable::yes, ti::less_equal_comparable::yes,
1140 ti::greater_equal_comparable::yes, ti::greater_than_comparable::yes,
1141 ti::swappable::nothrow>>,
1142
1143 // ComparableValue
1144 ProfileAndExpectation<
1145 ti::ComparableValueProfile, ti::ComparableValueArchetype,
1146 ti::ConformanceProfile<
1147 ti::default_constructible::maybe, ti::move_constructible::nothrow,
1148 ti::copy_constructible::yes, ti::move_assignable::nothrow,
1149 ti::copy_assignable::yes, ti::destructible::nothrow,
1150 ti::equality_comparable::yes, ti::inequality_comparable::yes,
1151 ti::less_than_comparable::yes, ti::less_equal_comparable::yes,
1152 ti::greater_equal_comparable::yes, ti::greater_than_comparable::yes,
1153 ti::swappable::nothrow>>>;
1154
1155 using TrivialProfilesToTest = ::testing::Types<
1156 ProfileAndExpectation<
1157 ti::TrivialSpecialMemberFunctionsProfile,
1158 ti::TrivialSpecialMemberFunctionsArchetype,
1159 ti::ConformanceProfile<
1160 ti::default_constructible::trivial, ti::move_constructible::trivial,
1161 ti::copy_constructible::trivial, ti::move_assignable::trivial,
1162 ti::copy_assignable::trivial, ti::destructible::trivial,
1163 ti::equality_comparable::maybe, ti::inequality_comparable::maybe,
1164 ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe,
1165 ti::greater_equal_comparable::maybe,
1166 ti::greater_than_comparable::maybe, ti::swappable::nothrow>>,
1167
1168 ProfileAndExpectation<
1169 ti::TriviallyCompleteProfile, ti::TriviallyCompleteArchetype,
1170 ti::ConformanceProfile<
1171 ti::default_constructible::trivial, ti::move_constructible::trivial,
1172 ti::copy_constructible::trivial, ti::move_assignable::trivial,
1173 ti::copy_assignable::trivial, ti::destructible::trivial,
1174 ti::equality_comparable::yes, ti::inequality_comparable::yes,
1175 ti::less_than_comparable::yes, ti::less_equal_comparable::yes,
1176 ti::greater_equal_comparable::yes, ti::greater_than_comparable::yes,
1177 ti::swappable::nothrow, ti::hashable::yes>>>;
1178
1179 INSTANTIATE_TYPED_TEST_SUITE_P(Core, ProfileTest, CoreProfilesToTest);
1180 INSTANTIATE_TYPED_TEST_SUITE_P(Common, ProfileTest, CommonProfilesToTest);
1181 INSTANTIATE_TYPED_TEST_SUITE_P(ComparableHelpers, ProfileTest,
1182 ComparableHelpersProfilesToTest);
1183 INSTANTIATE_TYPED_TEST_SUITE_P(CommonComparable, ProfileTest,
1184 CommonComparableProfilesToTest);
1185 INSTANTIATE_TYPED_TEST_SUITE_P(Trivial, ProfileTest, TrivialProfilesToTest);
1186
TEST(ConformanceTestingTest,Basic)1187 TEST(ConformanceTestingTest, Basic) {
1188 using profile = ti::CombineProfiles<ti::TriviallyCompleteProfile,
1189 ti::NothrowComparableProfile>;
1190
1191 using lim = std::numeric_limits<float>;
1192
1193 ABSL_INTERNAL_ASSERT_CONFORMANCE_OF(float)
1194 .INITIALIZER(-lim::infinity())
1195 .INITIALIZER(lim::lowest())
1196 .INITIALIZER(-1.f)
1197 .INITIALIZER(-lim::min())
1198 .EQUIVALENCE_CLASS(INITIALIZER(-0.f), INITIALIZER(0.f))
1199 .INITIALIZER(lim::min())
1200 .INITIALIZER(1.f)
1201 .INITIALIZER(lim::max())
1202 .INITIALIZER(lim::infinity())
1203 .WITH_STRICT_PROFILE(absl::types_internal::RegularityDomain, profile);
1204 }
1205
1206 struct BadMoveConstruct {
1207 BadMoveConstruct() = default;
BadMoveConstruct__anon7d2b0ec90111::BadMoveConstruct1208 BadMoveConstruct(BadMoveConstruct&& other) noexcept
1209 : value(other.value + 1) {}
1210 BadMoveConstruct& operator=(BadMoveConstruct&& other) noexcept = default;
1211 int value = 0;
1212
operator ==(BadMoveConstruct const & lhs,BadMoveConstruct const & rhs)1213 friend bool operator==(BadMoveConstruct const& lhs,
1214 BadMoveConstruct const& rhs) {
1215 return lhs.value == rhs.value;
1216 }
operator !=(BadMoveConstruct const & lhs,BadMoveConstruct const & rhs)1217 friend bool operator!=(BadMoveConstruct const& lhs,
1218 BadMoveConstruct const& rhs) {
1219 return lhs.value != rhs.value;
1220 }
1221 };
1222
1223 struct BadMoveAssign {
1224 BadMoveAssign() = default;
1225 BadMoveAssign(BadMoveAssign&& other) noexcept = default;
operator =__anon7d2b0ec90111::BadMoveAssign1226 BadMoveAssign& operator=(BadMoveAssign&& other) noexcept {
1227 int new_value = other.value + 1;
1228 value = new_value;
1229 return *this;
1230 }
1231 int value = 0;
1232
operator ==(BadMoveAssign const & lhs,BadMoveAssign const & rhs)1233 friend bool operator==(BadMoveAssign const& lhs, BadMoveAssign const& rhs) {
1234 return lhs.value == rhs.value;
1235 }
operator !=(BadMoveAssign const & lhs,BadMoveAssign const & rhs)1236 friend bool operator!=(BadMoveAssign const& lhs, BadMoveAssign const& rhs) {
1237 return lhs.value != rhs.value;
1238 }
1239 };
1240
1241 enum class WhichCompIsBad { eq, ne, lt, le, ge, gt };
1242
1243 template <WhichCompIsBad Which>
1244 struct BadCompare {
1245 int value;
1246
operator ==(BadCompare const & lhs,BadCompare const & rhs)1247 friend bool operator==(BadCompare const& lhs, BadCompare const& rhs) {
1248 return Which == WhichCompIsBad::eq ? lhs.value != rhs.value
1249 : lhs.value == rhs.value;
1250 }
1251
operator !=(BadCompare const & lhs,BadCompare const & rhs)1252 friend bool operator!=(BadCompare const& lhs, BadCompare const& rhs) {
1253 return Which == WhichCompIsBad::ne ? lhs.value == rhs.value
1254 : lhs.value != rhs.value;
1255 }
1256
operator <(BadCompare const & lhs,BadCompare const & rhs)1257 friend bool operator<(BadCompare const& lhs, BadCompare const& rhs) {
1258 return Which == WhichCompIsBad::lt ? lhs.value >= rhs.value
1259 : lhs.value < rhs.value;
1260 }
1261
operator <=(BadCompare const & lhs,BadCompare const & rhs)1262 friend bool operator<=(BadCompare const& lhs, BadCompare const& rhs) {
1263 return Which == WhichCompIsBad::le ? lhs.value > rhs.value
1264 : lhs.value <= rhs.value;
1265 }
1266
operator >=(BadCompare const & lhs,BadCompare const & rhs)1267 friend bool operator>=(BadCompare const& lhs, BadCompare const& rhs) {
1268 return Which == WhichCompIsBad::ge ? lhs.value < rhs.value
1269 : lhs.value >= rhs.value;
1270 }
1271
operator >(BadCompare const & lhs,BadCompare const & rhs)1272 friend bool operator>(BadCompare const& lhs, BadCompare const& rhs) {
1273 return Which == WhichCompIsBad::gt ? lhs.value <= rhs.value
1274 : lhs.value > rhs.value;
1275 }
1276 };
1277
TEST(ConformanceTestingDeathTest,Failures)1278 TEST(ConformanceTestingDeathTest, Failures) {
1279 {
1280 using profile = ti::CombineProfiles<ti::TriviallyCompleteProfile,
1281 ti::NothrowComparableProfile>;
1282
1283 // Note: The initializers are intentionally in the wrong order.
1284 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(float)
1285 .INITIALIZER(1.f)
1286 .INITIALIZER(0.f)
1287 .WITH_LOOSE_PROFILE(profile);
1288 }
1289
1290 {
1291 using profile =
1292 ti::CombineProfiles<ti::NothrowMovableProfile, ti::EquatableProfile>;
1293
1294 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadMoveConstruct)
1295 .DUE_TO("Move construction")
1296 .INITIALIZER(BadMoveConstruct())
1297 .WITH_LOOSE_PROFILE(profile);
1298 }
1299
1300 {
1301 using profile =
1302 ti::CombineProfiles<ti::NothrowMovableProfile, ti::EquatableProfile>;
1303
1304 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadMoveAssign)
1305 .DUE_TO("Move assignment")
1306 .INITIALIZER(BadMoveAssign())
1307 .WITH_LOOSE_PROFILE(profile);
1308 }
1309 }
1310
TEST(ConformanceTestingDeathTest,CompFailures)1311 TEST(ConformanceTestingDeathTest, CompFailures) {
1312 using profile = ti::ComparableProfile;
1313
1314 {
1315 using BadComp = BadCompare<WhichCompIsBad::eq>;
1316
1317 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadComp)
1318 .DUE_TO("Comparison")
1319 .INITIALIZER(BadComp{0})
1320 .INITIALIZER(BadComp{1})
1321 .WITH_LOOSE_PROFILE(profile);
1322 }
1323
1324 {
1325 using BadComp = BadCompare<WhichCompIsBad::ne>;
1326
1327 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadComp)
1328 .DUE_TO("Comparison")
1329 .INITIALIZER(BadComp{0})
1330 .INITIALIZER(BadComp{1})
1331 .WITH_LOOSE_PROFILE(profile);
1332 }
1333
1334 {
1335 using BadComp = BadCompare<WhichCompIsBad::lt>;
1336
1337 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadComp)
1338 .DUE_TO("Comparison")
1339 .INITIALIZER(BadComp{0})
1340 .INITIALIZER(BadComp{1})
1341 .WITH_LOOSE_PROFILE(profile);
1342 }
1343
1344 {
1345 using BadComp = BadCompare<WhichCompIsBad::le>;
1346
1347 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadComp)
1348 .DUE_TO("Comparison")
1349 .INITIALIZER(BadComp{0})
1350 .INITIALIZER(BadComp{1})
1351 .WITH_LOOSE_PROFILE(profile);
1352 }
1353
1354 {
1355 using BadComp = BadCompare<WhichCompIsBad::ge>;
1356
1357 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadComp)
1358 .DUE_TO("Comparison")
1359 .INITIALIZER(BadComp{0})
1360 .INITIALIZER(BadComp{1})
1361 .WITH_LOOSE_PROFILE(profile);
1362 }
1363
1364 {
1365 using BadComp = BadCompare<WhichCompIsBad::gt>;
1366
1367 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadComp)
1368 .DUE_TO("Comparison")
1369 .INITIALIZER(BadComp{0})
1370 .INITIALIZER(BadComp{1})
1371 .WITH_LOOSE_PROFILE(profile);
1372 }
1373 }
1374
1375 struct BadSelfMove {
1376 BadSelfMove() = default;
1377 BadSelfMove(BadSelfMove&&) = default;
operator =__anon7d2b0ec90111::BadSelfMove1378 BadSelfMove& operator=(BadSelfMove&& other) noexcept {
1379 if (this == &other) {
1380 broken_state = true;
1381 }
1382 return *this;
1383 }
1384
operator ==(const BadSelfMove & lhs,const BadSelfMove & rhs)1385 friend bool operator==(const BadSelfMove& lhs, const BadSelfMove& rhs) {
1386 return !(lhs.broken_state || rhs.broken_state);
1387 }
1388
operator !=(const BadSelfMove & lhs,const BadSelfMove & rhs)1389 friend bool operator!=(const BadSelfMove& lhs, const BadSelfMove& rhs) {
1390 return lhs.broken_state || rhs.broken_state;
1391 }
1392
1393 bool broken_state = false;
1394 };
1395
TEST(ConformanceTestingDeathTest,SelfMoveFailure)1396 TEST(ConformanceTestingDeathTest, SelfMoveFailure) {
1397 using profile = ti::EquatableNothrowMovableProfile;
1398
1399 {
1400 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadSelfMove)
1401 .DUE_TO("Move assignment")
1402 .INITIALIZER(BadSelfMove())
1403 .WITH_LOOSE_PROFILE(profile);
1404 }
1405 }
1406
1407 struct BadSelfCopy {
1408 BadSelfCopy() = default;
1409 BadSelfCopy(BadSelfCopy&&) = default;
1410 BadSelfCopy(const BadSelfCopy&) = default;
1411 BadSelfCopy& operator=(BadSelfCopy&&) = default;
operator =__anon7d2b0ec90111::BadSelfCopy1412 BadSelfCopy& operator=(BadSelfCopy const& other) {
1413 if (this == &other) {
1414 broken_state = true;
1415 }
1416 return *this;
1417 }
1418
operator ==(const BadSelfCopy & lhs,const BadSelfCopy & rhs)1419 friend bool operator==(const BadSelfCopy& lhs, const BadSelfCopy& rhs) {
1420 return !(lhs.broken_state || rhs.broken_state);
1421 }
1422
operator !=(const BadSelfCopy & lhs,const BadSelfCopy & rhs)1423 friend bool operator!=(const BadSelfCopy& lhs, const BadSelfCopy& rhs) {
1424 return lhs.broken_state || rhs.broken_state;
1425 }
1426
1427 bool broken_state = false;
1428 };
1429
TEST(ConformanceTestingDeathTest,SelfCopyFailure)1430 TEST(ConformanceTestingDeathTest, SelfCopyFailure) {
1431 using profile = ti::EquatableValueProfile;
1432
1433 {
1434 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadSelfCopy)
1435 .DUE_TO("Copy assignment")
1436 .INITIALIZER(BadSelfCopy())
1437 .WITH_LOOSE_PROFILE(profile);
1438 }
1439 }
1440
1441 struct BadSelfSwap {
swap(BadSelfSwap & lhs,BadSelfSwap & rhs)1442 friend void swap(BadSelfSwap& lhs, BadSelfSwap& rhs) noexcept {
1443 if (&lhs == &rhs) lhs.broken_state = true;
1444 }
1445
operator ==(const BadSelfSwap & lhs,const BadSelfSwap & rhs)1446 friend bool operator==(const BadSelfSwap& lhs, const BadSelfSwap& rhs) {
1447 return !(lhs.broken_state || rhs.broken_state);
1448 }
1449
operator !=(const BadSelfSwap & lhs,const BadSelfSwap & rhs)1450 friend bool operator!=(const BadSelfSwap& lhs, const BadSelfSwap& rhs) {
1451 return lhs.broken_state || rhs.broken_state;
1452 }
1453
1454 bool broken_state = false;
1455 };
1456
TEST(ConformanceTestingDeathTest,SelfSwapFailure)1457 TEST(ConformanceTestingDeathTest, SelfSwapFailure) {
1458 using profile = ti::EquatableNothrowMovableProfile;
1459
1460 {
1461 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadSelfSwap)
1462 .DUE_TO("Swap")
1463 .INITIALIZER(BadSelfSwap())
1464 .WITH_LOOSE_PROFILE(profile);
1465 }
1466 }
1467
1468 struct BadDefaultInitializedMoveAssign {
BadDefaultInitializedMoveAssign__anon7d2b0ec90111::BadDefaultInitializedMoveAssign1469 BadDefaultInitializedMoveAssign() : default_initialized(true) {}
BadDefaultInitializedMoveAssign__anon7d2b0ec90111::BadDefaultInitializedMoveAssign1470 explicit BadDefaultInitializedMoveAssign(int v) : value(v) {}
BadDefaultInitializedMoveAssign__anon7d2b0ec90111::BadDefaultInitializedMoveAssign1471 BadDefaultInitializedMoveAssign(
1472 BadDefaultInitializedMoveAssign&& other) noexcept
1473 : value(other.value) {}
operator =__anon7d2b0ec90111::BadDefaultInitializedMoveAssign1474 BadDefaultInitializedMoveAssign& operator=(
1475 BadDefaultInitializedMoveAssign&& other) noexcept {
1476 value = other.value;
1477 if (default_initialized) ++value; // Bad move if lhs is default initialized
1478 return *this;
1479 }
1480
operator ==(const BadDefaultInitializedMoveAssign & lhs,const BadDefaultInitializedMoveAssign & rhs)1481 friend bool operator==(const BadDefaultInitializedMoveAssign& lhs,
1482 const BadDefaultInitializedMoveAssign& rhs) {
1483 return lhs.value == rhs.value;
1484 }
1485
operator !=(const BadDefaultInitializedMoveAssign & lhs,const BadDefaultInitializedMoveAssign & rhs)1486 friend bool operator!=(const BadDefaultInitializedMoveAssign& lhs,
1487 const BadDefaultInitializedMoveAssign& rhs) {
1488 return lhs.value != rhs.value;
1489 }
1490
1491 bool default_initialized = false;
1492 int value = 0;
1493 };
1494
TEST(ConformanceTestingDeathTest,DefaultInitializedMoveAssignFailure)1495 TEST(ConformanceTestingDeathTest, DefaultInitializedMoveAssignFailure) {
1496 using profile =
1497 ti::CombineProfiles<ti::DefaultConstructibleNothrowMovableProfile,
1498 ti::EquatableProfile>;
1499
1500 {
1501 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadDefaultInitializedMoveAssign)
1502 .DUE_TO("move assignment")
1503 .INITIALIZER(BadDefaultInitializedMoveAssign(0))
1504 .WITH_LOOSE_PROFILE(profile);
1505 }
1506 }
1507
1508 struct BadDefaultInitializedCopyAssign {
BadDefaultInitializedCopyAssign__anon7d2b0ec90111::BadDefaultInitializedCopyAssign1509 BadDefaultInitializedCopyAssign() : default_initialized(true) {}
BadDefaultInitializedCopyAssign__anon7d2b0ec90111::BadDefaultInitializedCopyAssign1510 explicit BadDefaultInitializedCopyAssign(int v) : value(v) {}
BadDefaultInitializedCopyAssign__anon7d2b0ec90111::BadDefaultInitializedCopyAssign1511 BadDefaultInitializedCopyAssign(
1512 BadDefaultInitializedCopyAssign&& other) noexcept
1513 : value(other.value) {}
BadDefaultInitializedCopyAssign__anon7d2b0ec90111::BadDefaultInitializedCopyAssign1514 BadDefaultInitializedCopyAssign(const BadDefaultInitializedCopyAssign& other)
1515 : value(other.value) {}
1516
operator =__anon7d2b0ec90111::BadDefaultInitializedCopyAssign1517 BadDefaultInitializedCopyAssign& operator=(
1518 BadDefaultInitializedCopyAssign&& other) noexcept {
1519 value = other.value;
1520 return *this;
1521 }
1522
operator =__anon7d2b0ec90111::BadDefaultInitializedCopyAssign1523 BadDefaultInitializedCopyAssign& operator=(
1524 const BadDefaultInitializedCopyAssign& other) {
1525 value = other.value;
1526 if (default_initialized) ++value; // Bad move if lhs is default initialized
1527 return *this;
1528 }
1529
operator ==(const BadDefaultInitializedCopyAssign & lhs,const BadDefaultInitializedCopyAssign & rhs)1530 friend bool operator==(const BadDefaultInitializedCopyAssign& lhs,
1531 const BadDefaultInitializedCopyAssign& rhs) {
1532 return lhs.value == rhs.value;
1533 }
1534
operator !=(const BadDefaultInitializedCopyAssign & lhs,const BadDefaultInitializedCopyAssign & rhs)1535 friend bool operator!=(const BadDefaultInitializedCopyAssign& lhs,
1536 const BadDefaultInitializedCopyAssign& rhs) {
1537 return lhs.value != rhs.value;
1538 }
1539
1540 bool default_initialized = false;
1541 int value = 0;
1542 };
1543
TEST(ConformanceTestingDeathTest,DefaultInitializedAssignFailure)1544 TEST(ConformanceTestingDeathTest, DefaultInitializedAssignFailure) {
1545 using profile = ti::CombineProfiles<ti::DefaultConstructibleValueProfile,
1546 ti::EquatableProfile>;
1547
1548 {
1549 ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(BadDefaultInitializedCopyAssign)
1550 .DUE_TO("copy assignment")
1551 .INITIALIZER(BadDefaultInitializedCopyAssign(0))
1552 .WITH_LOOSE_PROFILE(profile);
1553 }
1554 }
1555
1556 } // namespace
1557