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