// Copyright 2019 The Abseil Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include #include "gtest/gtest.h" #include "absl/meta/type_traits.h" #include "absl/types/internal/conformance_aliases.h" namespace { namespace ti = absl::types_internal; template using DefaultConstructibleWithNewImpl = decltype(::new (std::nothrow) T); template using DefaultConstructibleWithNew = absl::type_traits_internal::is_detected; template using MoveConstructibleWithNewImpl = decltype(::new (std::nothrow) T(std::declval())); template using MoveConstructibleWithNew = absl::type_traits_internal::is_detected; template using CopyConstructibleWithNewImpl = decltype(::new (std::nothrow) T(std::declval())); template using CopyConstructibleWithNew = absl::type_traits_internal::is_detected; template > using NothrowDefaultConstructibleWithNewImpl = typename std::enable_if::type; template using NothrowDefaultConstructibleWithNew = absl::type_traits_internal::is_detected< NothrowDefaultConstructibleWithNewImpl, T>; template ()))>> using NothrowMoveConstructibleWithNewImpl = typename std::enable_if::type; template using NothrowMoveConstructibleWithNew = absl::type_traits_internal::is_detected; template ()))>> using NothrowCopyConstructibleWithNewImpl = typename std::enable_if::type; template using NothrowCopyConstructibleWithNew = absl::type_traits_internal::is_detected; // NOTE: ?: is used to verify contextually-convertible to bool and not simply // implicit or explicit convertibility. #define ABSL_INTERNAL_COMPARISON_OP_EXPR(op) \ ((std::declval() op std::declval()) ? true : true) #define ABSL_INTERNAL_COMPARISON_OP_TRAIT(name, op) \ template \ using name##Impl = decltype(ABSL_INTERNAL_COMPARISON_OP_EXPR(op)); \ \ template \ using name = absl::type_traits_internal::is_detected; \ \ template > \ using Nothrow##name##Impl = typename std::enable_if::type; \ \ template \ using Nothrow##name = \ absl::type_traits_internal::is_detected ABSL_INTERNAL_COMPARISON_OP_TRAIT(EqualityComparable, ==); ABSL_INTERNAL_COMPARISON_OP_TRAIT(InequalityComparable, !=); ABSL_INTERNAL_COMPARISON_OP_TRAIT(LessThanComparable, <); ABSL_INTERNAL_COMPARISON_OP_TRAIT(LessEqualComparable, <=); ABSL_INTERNAL_COMPARISON_OP_TRAIT(GreaterEqualComparable, >=); ABSL_INTERNAL_COMPARISON_OP_TRAIT(GreaterThanComparable, >); #undef ABSL_INTERNAL_COMPARISON_OP_TRAIT template class ProfileTest : public ::testing::Test {}; TYPED_TEST_SUITE_P(ProfileTest); TYPED_TEST_P(ProfileTest, HasAppropriateConstructionProperties) { using profile = typename TypeParam::profile; using arch = typename TypeParam::arch; using expected_profile = typename TypeParam::expected_profile; using props = ti::PropertiesOfT; using arch_props = ti::PropertiesOfArchetypeT; using expected_props = ti::PropertiesOfT; // Make sure all of the properties are as expected. // There are seemingly redundant tests here to make it easier to diagnose // the specifics of the failure if something were to go wrong. EXPECT_TRUE((std::is_same::value)); EXPECT_TRUE((std::is_same::value)); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(props::default_constructible_support, expected_props::default_constructible_support); EXPECT_EQ(props::move_constructible_support, expected_props::move_constructible_support); EXPECT_EQ(props::copy_constructible_support, expected_props::copy_constructible_support); EXPECT_EQ(props::destructible_support, expected_props::destructible_support); // Avoid additional error message noise when profile and archetype match with // each other but were not what was expected. if (!std::is_same::value) { EXPECT_EQ(arch_props::default_constructible_support, expected_props::default_constructible_support); EXPECT_EQ(arch_props::move_constructible_support, expected_props::move_constructible_support); EXPECT_EQ(arch_props::copy_constructible_support, expected_props::copy_constructible_support); EXPECT_EQ(arch_props::destructible_support, expected_props::destructible_support); } ////////////////////////////////////////////////////////////////////////////// // Default constructor checks // ////////////////////////////////////////////////////////////////////////////// EXPECT_EQ(props::default_constructible_support, expected_props::default_constructible_support); switch (expected_props::default_constructible_support) { case ti::default_constructible::maybe: EXPECT_FALSE(DefaultConstructibleWithNew::value); EXPECT_FALSE(NothrowDefaultConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_FALSE(std::is_default_constructible::value); EXPECT_FALSE(std::is_nothrow_default_constructible::value); EXPECT_FALSE(absl::is_trivially_default_constructible::value); } break; case ti::default_constructible::yes: EXPECT_TRUE(DefaultConstructibleWithNew::value); EXPECT_FALSE(NothrowDefaultConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_TRUE(std::is_default_constructible::value); EXPECT_FALSE(std::is_nothrow_default_constructible::value); EXPECT_FALSE(absl::is_trivially_default_constructible::value); } break; case ti::default_constructible::nothrow: EXPECT_TRUE(DefaultConstructibleWithNew::value); EXPECT_TRUE(NothrowDefaultConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_TRUE(std::is_default_constructible::value); EXPECT_TRUE(std::is_nothrow_default_constructible::value); EXPECT_FALSE(absl::is_trivially_default_constructible::value); // Constructor traits also check the destructor. if (std::is_nothrow_destructible::value) { EXPECT_TRUE(std::is_nothrow_default_constructible::value); } } break; case ti::default_constructible::trivial: EXPECT_TRUE(DefaultConstructibleWithNew::value); EXPECT_TRUE(NothrowDefaultConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_TRUE(std::is_default_constructible::value); EXPECT_TRUE(std::is_nothrow_default_constructible::value); // Constructor triviality traits require trivially destructible types. if (absl::is_trivially_destructible::value) { EXPECT_TRUE(absl::is_trivially_default_constructible::value); } } break; } ////////////////////////////////////////////////////////////////////////////// // Move constructor checks // ////////////////////////////////////////////////////////////////////////////// EXPECT_EQ(props::move_constructible_support, expected_props::move_constructible_support); switch (expected_props::move_constructible_support) { case ti::move_constructible::maybe: EXPECT_FALSE(MoveConstructibleWithNew::value); EXPECT_FALSE(NothrowMoveConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_FALSE(std::is_move_constructible::value); EXPECT_FALSE(std::is_nothrow_move_constructible::value); EXPECT_FALSE(absl::is_trivially_move_constructible::value); } break; case ti::move_constructible::yes: EXPECT_TRUE(MoveConstructibleWithNew::value); EXPECT_FALSE(NothrowMoveConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_TRUE(std::is_move_constructible::value); EXPECT_FALSE(std::is_nothrow_move_constructible::value); EXPECT_FALSE(absl::is_trivially_move_constructible::value); } break; case ti::move_constructible::nothrow: EXPECT_TRUE(MoveConstructibleWithNew::value); EXPECT_TRUE(NothrowMoveConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_TRUE(std::is_move_constructible::value); EXPECT_TRUE(std::is_nothrow_move_constructible::value); EXPECT_FALSE(absl::is_trivially_move_constructible::value); // Constructor traits also check the destructor. if (std::is_nothrow_destructible::value) { EXPECT_TRUE(std::is_nothrow_move_constructible::value); } } break; case ti::move_constructible::trivial: EXPECT_TRUE(MoveConstructibleWithNew::value); EXPECT_TRUE(NothrowMoveConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_TRUE(std::is_move_constructible::value); EXPECT_TRUE(std::is_nothrow_move_constructible::value); // Constructor triviality traits require trivially destructible types. if (absl::is_trivially_destructible::value) { EXPECT_TRUE(absl::is_trivially_move_constructible::value); } } break; } ////////////////////////////////////////////////////////////////////////////// // Copy constructor checks // ////////////////////////////////////////////////////////////////////////////// EXPECT_EQ(props::copy_constructible_support, expected_props::copy_constructible_support); switch (expected_props::copy_constructible_support) { case ti::copy_constructible::maybe: EXPECT_FALSE(CopyConstructibleWithNew::value); EXPECT_FALSE(NothrowCopyConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_FALSE(std::is_copy_constructible::value); EXPECT_FALSE(std::is_nothrow_copy_constructible::value); EXPECT_FALSE(absl::is_trivially_copy_constructible::value); } break; case ti::copy_constructible::yes: EXPECT_TRUE(CopyConstructibleWithNew::value); EXPECT_FALSE(NothrowCopyConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_TRUE(std::is_copy_constructible::value); EXPECT_FALSE(std::is_nothrow_copy_constructible::value); EXPECT_FALSE(absl::is_trivially_copy_constructible::value); } break; case ti::copy_constructible::nothrow: EXPECT_TRUE(CopyConstructibleWithNew::value); EXPECT_TRUE(NothrowCopyConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_TRUE(std::is_copy_constructible::value); EXPECT_TRUE(std::is_nothrow_copy_constructible::value); EXPECT_FALSE(absl::is_trivially_copy_constructible::value); // Constructor traits also check the destructor. if (std::is_nothrow_destructible::value) { EXPECT_TRUE(std::is_nothrow_copy_constructible::value); } } break; case ti::copy_constructible::trivial: EXPECT_TRUE(CopyConstructibleWithNew::value); EXPECT_TRUE(NothrowCopyConstructibleWithNew::value); // Standard constructible traits depend on the destructor. if (std::is_destructible::value) { EXPECT_TRUE(std::is_copy_constructible::value); EXPECT_TRUE(std::is_nothrow_copy_constructible::value); // Constructor triviality traits require trivially destructible types. if (absl::is_trivially_destructible::value) { EXPECT_TRUE(absl::is_trivially_copy_constructible::value); } } break; } ////////////////////////////////////////////////////////////////////////////// // Destructible checks // ////////////////////////////////////////////////////////////////////////////// EXPECT_EQ(props::destructible_support, expected_props::destructible_support); switch (expected_props::destructible_support) { case ti::destructible::maybe: EXPECT_FALSE(std::is_destructible::value); EXPECT_FALSE(std::is_nothrow_destructible::value); EXPECT_FALSE(absl::is_trivially_destructible::value); break; case ti::destructible::yes: EXPECT_TRUE(std::is_destructible::value); EXPECT_FALSE(std::is_nothrow_destructible::value); EXPECT_FALSE(absl::is_trivially_destructible::value); break; case ti::destructible::nothrow: EXPECT_TRUE(std::is_destructible::value); EXPECT_TRUE(std::is_nothrow_destructible::value); EXPECT_FALSE(absl::is_trivially_destructible::value); break; case ti::destructible::trivial: EXPECT_TRUE(std::is_destructible::value); EXPECT_TRUE(std::is_nothrow_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); break; } } TYPED_TEST_P(ProfileTest, HasAppropriateAssignmentProperties) { using profile = typename TypeParam::profile; using arch = typename TypeParam::arch; using expected_profile = typename TypeParam::expected_profile; using props = ti::PropertiesOfT; using arch_props = ti::PropertiesOfArchetypeT; using expected_props = ti::PropertiesOfT; // Make sure all of the properties are as expected. // There are seemingly redundant tests here to make it easier to diagnose // the specifics of the failure if something were to go wrong. EXPECT_TRUE((std::is_same::value)); EXPECT_TRUE((std::is_same::value)); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(props::move_assignable_support, expected_props::move_assignable_support); EXPECT_EQ(props::copy_assignable_support, expected_props::copy_assignable_support); // Avoid additional error message noise when profile and archetype match with // each other but were not what was expected. if (!std::is_same::value) { EXPECT_EQ(arch_props::move_assignable_support, expected_props::move_assignable_support); EXPECT_EQ(arch_props::copy_assignable_support, expected_props::copy_assignable_support); } ////////////////////////////////////////////////////////////////////////////// // Move assignment checks // ////////////////////////////////////////////////////////////////////////////// EXPECT_EQ(props::move_assignable_support, expected_props::move_assignable_support); switch (expected_props::move_assignable_support) { case ti::move_assignable::maybe: EXPECT_FALSE(std::is_move_assignable::value); EXPECT_FALSE(std::is_nothrow_move_assignable::value); EXPECT_FALSE(absl::is_trivially_move_assignable::value); break; case ti::move_assignable::yes: EXPECT_TRUE(std::is_move_assignable::value); EXPECT_FALSE(std::is_nothrow_move_assignable::value); EXPECT_FALSE(absl::is_trivially_move_assignable::value); break; case ti::move_assignable::nothrow: EXPECT_TRUE(std::is_move_assignable::value); EXPECT_TRUE(std::is_nothrow_move_assignable::value); EXPECT_FALSE(absl::is_trivially_move_assignable::value); break; case ti::move_assignable::trivial: EXPECT_TRUE(std::is_move_assignable::value); EXPECT_TRUE(std::is_nothrow_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); break; } ////////////////////////////////////////////////////////////////////////////// // Copy assignment checks // ////////////////////////////////////////////////////////////////////////////// EXPECT_EQ(props::copy_assignable_support, expected_props::copy_assignable_support); switch (expected_props::copy_assignable_support) { case ti::copy_assignable::maybe: EXPECT_FALSE(std::is_copy_assignable::value); EXPECT_FALSE(std::is_nothrow_copy_assignable::value); EXPECT_FALSE(absl::is_trivially_copy_assignable::value); break; case ti::copy_assignable::yes: EXPECT_TRUE(std::is_copy_assignable::value); EXPECT_FALSE(std::is_nothrow_copy_assignable::value); EXPECT_FALSE(absl::is_trivially_copy_assignable::value); break; case ti::copy_assignable::nothrow: EXPECT_TRUE(std::is_copy_assignable::value); EXPECT_TRUE(std::is_nothrow_copy_assignable::value); EXPECT_FALSE(absl::is_trivially_copy_assignable::value); break; case ti::copy_assignable::trivial: EXPECT_TRUE(std::is_copy_assignable::value); EXPECT_TRUE(std::is_nothrow_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); break; } } TYPED_TEST_P(ProfileTest, HasAppropriateComparisonProperties) { using profile = typename TypeParam::profile; using arch = typename TypeParam::arch; using expected_profile = typename TypeParam::expected_profile; using props = ti::PropertiesOfT; using arch_props = ti::PropertiesOfArchetypeT; using expected_props = ti::PropertiesOfT; // Make sure all of the properties are as expected. // There are seemingly redundant tests here to make it easier to diagnose // the specifics of the failure if something were to go wrong. EXPECT_TRUE((std::is_same::value)); EXPECT_TRUE((std::is_same::value)); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(props::equality_comparable_support, expected_props::equality_comparable_support); EXPECT_EQ(props::inequality_comparable_support, expected_props::inequality_comparable_support); EXPECT_EQ(props::less_than_comparable_support, expected_props::less_than_comparable_support); EXPECT_EQ(props::less_equal_comparable_support, expected_props::less_equal_comparable_support); EXPECT_EQ(props::greater_equal_comparable_support, expected_props::greater_equal_comparable_support); EXPECT_EQ(props::greater_than_comparable_support, expected_props::greater_than_comparable_support); // Avoid additional error message noise when profile and archetype match with // each other but were not what was expected. if (!std::is_same::value) { EXPECT_EQ(arch_props::equality_comparable_support, expected_props::equality_comparable_support); EXPECT_EQ(arch_props::inequality_comparable_support, expected_props::inequality_comparable_support); EXPECT_EQ(arch_props::less_than_comparable_support, expected_props::less_than_comparable_support); EXPECT_EQ(arch_props::less_equal_comparable_support, expected_props::less_equal_comparable_support); EXPECT_EQ(arch_props::greater_equal_comparable_support, expected_props::greater_equal_comparable_support); EXPECT_EQ(arch_props::greater_than_comparable_support, expected_props::greater_than_comparable_support); } ////////////////////////////////////////////////////////////////////////////// // Equality comparable checks // ////////////////////////////////////////////////////////////////////////////// switch (expected_props::equality_comparable_support) { case ti::equality_comparable::maybe: EXPECT_FALSE(EqualityComparable::value); EXPECT_FALSE(NothrowEqualityComparable::value); break; case ti::equality_comparable::yes: EXPECT_TRUE(EqualityComparable::value); EXPECT_FALSE(NothrowEqualityComparable::value); break; case ti::equality_comparable::nothrow: EXPECT_TRUE(EqualityComparable::value); EXPECT_TRUE(NothrowEqualityComparable::value); break; } ////////////////////////////////////////////////////////////////////////////// // Inequality comparable checks // ////////////////////////////////////////////////////////////////////////////// switch (expected_props::inequality_comparable_support) { case ti::inequality_comparable::maybe: EXPECT_FALSE(InequalityComparable::value); EXPECT_FALSE(NothrowInequalityComparable::value); break; case ti::inequality_comparable::yes: EXPECT_TRUE(InequalityComparable::value); EXPECT_FALSE(NothrowInequalityComparable::value); break; case ti::inequality_comparable::nothrow: EXPECT_TRUE(InequalityComparable::value); EXPECT_TRUE(NothrowInequalityComparable::value); break; } ////////////////////////////////////////////////////////////////////////////// // Less than comparable checks // ////////////////////////////////////////////////////////////////////////////// switch (expected_props::less_than_comparable_support) { case ti::less_than_comparable::maybe: EXPECT_FALSE(LessThanComparable::value); EXPECT_FALSE(NothrowLessThanComparable::value); break; case ti::less_than_comparable::yes: EXPECT_TRUE(LessThanComparable::value); EXPECT_FALSE(NothrowLessThanComparable::value); break; case ti::less_than_comparable::nothrow: EXPECT_TRUE(LessThanComparable::value); EXPECT_TRUE(NothrowLessThanComparable::value); break; } ////////////////////////////////////////////////////////////////////////////// // Less equal comparable checks // ////////////////////////////////////////////////////////////////////////////// switch (expected_props::less_equal_comparable_support) { case ti::less_equal_comparable::maybe: EXPECT_FALSE(LessEqualComparable::value); EXPECT_FALSE(NothrowLessEqualComparable::value); break; case ti::less_equal_comparable::yes: EXPECT_TRUE(LessEqualComparable::value); EXPECT_FALSE(NothrowLessEqualComparable::value); break; case ti::less_equal_comparable::nothrow: EXPECT_TRUE(LessEqualComparable::value); EXPECT_TRUE(NothrowLessEqualComparable::value); break; } ////////////////////////////////////////////////////////////////////////////// // Greater equal comparable checks // ////////////////////////////////////////////////////////////////////////////// switch (expected_props::greater_equal_comparable_support) { case ti::greater_equal_comparable::maybe: EXPECT_FALSE(GreaterEqualComparable::value); EXPECT_FALSE(NothrowGreaterEqualComparable::value); break; case ti::greater_equal_comparable::yes: EXPECT_TRUE(GreaterEqualComparable::value); EXPECT_FALSE(NothrowGreaterEqualComparable::value); break; case ti::greater_equal_comparable::nothrow: EXPECT_TRUE(GreaterEqualComparable::value); EXPECT_TRUE(NothrowGreaterEqualComparable::value); break; } ////////////////////////////////////////////////////////////////////////////// // Greater than comparable checks // ////////////////////////////////////////////////////////////////////////////// switch (expected_props::greater_than_comparable_support) { case ti::greater_than_comparable::maybe: EXPECT_FALSE(GreaterThanComparable::value); EXPECT_FALSE(NothrowGreaterThanComparable::value); break; case ti::greater_than_comparable::yes: EXPECT_TRUE(GreaterThanComparable::value); EXPECT_FALSE(NothrowGreaterThanComparable::value); break; case ti::greater_than_comparable::nothrow: EXPECT_TRUE(GreaterThanComparable::value); EXPECT_TRUE(NothrowGreaterThanComparable::value); break; } } TYPED_TEST_P(ProfileTest, HasAppropriateAuxilliaryProperties) { using profile = typename TypeParam::profile; using arch = typename TypeParam::arch; using expected_profile = typename TypeParam::expected_profile; using props = ti::PropertiesOfT; using arch_props = ti::PropertiesOfArchetypeT; using expected_props = ti::PropertiesOfT; // Make sure all of the properties are as expected. // There are seemingly redundant tests here to make it easier to diagnose // the specifics of the failure if something were to go wrong. EXPECT_TRUE((std::is_same::value)); EXPECT_TRUE((std::is_same::value)); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(props::swappable_support, expected_props::swappable_support); EXPECT_EQ(props::hashable_support, expected_props::hashable_support); // Avoid additional error message noise when profile and archetype match with // each other but were not what was expected. if (!std::is_same::value) { EXPECT_EQ(arch_props::swappable_support, expected_props::swappable_support); EXPECT_EQ(arch_props::hashable_support, expected_props::hashable_support); } ////////////////////////////////////////////////////////////////////////////// // Swappable checks // ////////////////////////////////////////////////////////////////////////////// switch (expected_props::swappable_support) { case ti::swappable::maybe: EXPECT_FALSE(absl::type_traits_internal::IsSwappable::value); EXPECT_FALSE(absl::type_traits_internal::IsNothrowSwappable::value); break; case ti::swappable::yes: EXPECT_TRUE(absl::type_traits_internal::IsSwappable::value); EXPECT_FALSE(absl::type_traits_internal::IsNothrowSwappable::value); break; case ti::swappable::nothrow: EXPECT_TRUE(absl::type_traits_internal::IsSwappable::value); EXPECT_TRUE(absl::type_traits_internal::IsNothrowSwappable::value); break; } ////////////////////////////////////////////////////////////////////////////// // Hashable checks // ////////////////////////////////////////////////////////////////////////////// switch (expected_props::hashable_support) { case ti::hashable::maybe: #if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ EXPECT_FALSE(absl::type_traits_internal::IsHashable::value); #endif // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ break; case ti::hashable::yes: EXPECT_TRUE(absl::type_traits_internal::IsHashable::value); break; } } REGISTER_TYPED_TEST_SUITE_P(ProfileTest, HasAppropriateConstructionProperties, HasAppropriateAssignmentProperties, HasAppropriateComparisonProperties, HasAppropriateAuxilliaryProperties); template struct ProfileAndExpectation { using profile = Profile; using arch = Arch; using expected_profile = ExpectedProfile; }; using CoreProfilesToTest = ::testing::Types< // The terminating case of combine (all properties are "maybe"). ProfileAndExpectation, ti::Archetype>, ti::ConformanceProfile<>>, // Core default constructor profiles ProfileAndExpectation< ti::HasDefaultConstructorProfile, ti::HasDefaultConstructorArchetype, ti::ConformanceProfile>, ProfileAndExpectation< ti::HasNothrowDefaultConstructorProfile, ti::HasNothrowDefaultConstructorArchetype, ti::ConformanceProfile>, ProfileAndExpectation< ti::HasTrivialDefaultConstructorProfile, ti::HasTrivialDefaultConstructorArchetype, ti::ConformanceProfile>, // Core move constructor profiles ProfileAndExpectation< ti::HasMoveConstructorProfile, ti::HasMoveConstructorArchetype, ti::ConformanceProfile>, ProfileAndExpectation< ti::HasNothrowMoveConstructorProfile, ti::HasNothrowMoveConstructorArchetype, ti::ConformanceProfile>, ProfileAndExpectation< ti::HasTrivialMoveConstructorProfile, ti::HasTrivialMoveConstructorArchetype, ti::ConformanceProfile>, // Core copy constructor profiles ProfileAndExpectation< ti::HasCopyConstructorProfile, ti::HasCopyConstructorArchetype, ti::ConformanceProfile>, ProfileAndExpectation< ti::HasNothrowCopyConstructorProfile, ti::HasNothrowCopyConstructorArchetype, ti::ConformanceProfile>, ProfileAndExpectation< ti::HasTrivialCopyConstructorProfile, ti::HasTrivialCopyConstructorArchetype, ti::ConformanceProfile>, // Core move assignment profiles ProfileAndExpectation< ti::HasMoveAssignProfile, ti::HasMoveAssignArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::yes>>, ProfileAndExpectation< ti::HasNothrowMoveAssignProfile, ti::HasNothrowMoveAssignArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::nothrow>>, ProfileAndExpectation< ti::HasTrivialMoveAssignProfile, ti::HasTrivialMoveAssignArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::trivial>>, // Core copy assignment profiles ProfileAndExpectation< ti::HasCopyAssignProfile, ti::HasCopyAssignArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::yes>>, ProfileAndExpectation< ti::HasNothrowCopyAssignProfile, ti::HasNothrowCopyAssignArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::nothrow>>, ProfileAndExpectation< ti::HasTrivialCopyAssignProfile, ti::HasTrivialCopyAssignArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::trivial>>, // Core destructor profiles ProfileAndExpectation< ti::HasDestructorProfile, ti::HasDestructorArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::yes>>, ProfileAndExpectation< ti::HasNothrowDestructorProfile, ti::HasNothrowDestructorArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::nothrow>>, ProfileAndExpectation< ti::HasTrivialDestructorProfile, ti::HasTrivialDestructorArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::trivial>>, // Core equality comparable profiles ProfileAndExpectation< ti::HasEqualityProfile, ti::HasEqualityArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::yes>>, ProfileAndExpectation< ti::HasNothrowEqualityProfile, ti::HasNothrowEqualityArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::nothrow>>, // Core inequality comparable profiles ProfileAndExpectation< ti::HasInequalityProfile, ti::HasInequalityArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::yes>>, ProfileAndExpectation< ti::HasNothrowInequalityProfile, ti::HasNothrowInequalityArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::nothrow>>, // Core less than comparable profiles ProfileAndExpectation< ti::HasLessThanProfile, ti::HasLessThanArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::yes>>, ProfileAndExpectation< ti::HasNothrowLessThanProfile, ti::HasNothrowLessThanArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::nothrow>>, // Core less equal comparable profiles ProfileAndExpectation< ti::HasLessEqualProfile, ti::HasLessEqualArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::yes>>, ProfileAndExpectation< ti::HasNothrowLessEqualProfile, ti::HasNothrowLessEqualArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::nothrow>>, // Core greater equal comparable profiles ProfileAndExpectation< ti::HasGreaterEqualProfile, ti::HasGreaterEqualArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::yes>>, ProfileAndExpectation< ti::HasNothrowGreaterEqualProfile, ti::HasNothrowGreaterEqualArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::nothrow>>, // Core greater than comparable profiles ProfileAndExpectation< ti::HasGreaterThanProfile, ti::HasGreaterThanArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::maybe, ti::greater_than_comparable::yes>>, ProfileAndExpectation< ti::HasNothrowGreaterThanProfile, ti::HasNothrowGreaterThanArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::maybe, ti::greater_than_comparable::nothrow>>, // Core swappable profiles ProfileAndExpectation< ti::HasSwapProfile, ti::HasSwapArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::maybe, ti::greater_than_comparable::maybe, ti::swappable::yes>>, ProfileAndExpectation< ti::HasNothrowSwapProfile, ti::HasNothrowSwapArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::maybe, ti::greater_than_comparable::maybe, ti::swappable::nothrow>>, // Core hashable profiles ProfileAndExpectation< ti::HasStdHashSpecializationProfile, ti::HasStdHashSpecializationArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::maybe, ti::greater_than_comparable::maybe, ti::swappable::maybe, ti::hashable::yes>>>; using CommonProfilesToTest = ::testing::Types< // NothrowMoveConstructible ProfileAndExpectation< ti::NothrowMoveConstructibleProfile, ti::NothrowMoveConstructibleArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::nothrow, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::nothrow>>, // CopyConstructible ProfileAndExpectation< ti::CopyConstructibleProfile, ti::CopyConstructibleArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::nothrow, ti::copy_constructible::yes, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::nothrow>>, // NothrowMovable ProfileAndExpectation< ti::NothrowMovableProfile, ti::NothrowMovableArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::nothrow, ti::copy_constructible::maybe, ti::move_assignable::nothrow, ti::copy_assignable::maybe, ti::destructible::nothrow, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::maybe, ti::greater_than_comparable::maybe, ti::swappable::nothrow>>, // Value ProfileAndExpectation< ti::ValueProfile, ti::ValueArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::nothrow, ti::copy_constructible::yes, ti::move_assignable::nothrow, ti::copy_assignable::yes, ti::destructible::nothrow, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::maybe, ti::greater_than_comparable::maybe, ti::swappable::nothrow>>, //////////////////////////////////////////////////////////////////////////// // Common but also DefaultConstructible // //////////////////////////////////////////////////////////////////////////// // DefaultConstructibleNothrowMoveConstructible ProfileAndExpectation< ti::DefaultConstructibleNothrowMoveConstructibleProfile, ti::DefaultConstructibleNothrowMoveConstructibleArchetype, ti::ConformanceProfile< ti::default_constructible::yes, ti::move_constructible::nothrow, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::nothrow>>, // DefaultConstructibleCopyConstructible ProfileAndExpectation< ti::DefaultConstructibleCopyConstructibleProfile, ti::DefaultConstructibleCopyConstructibleArchetype, ti::ConformanceProfile< ti::default_constructible::yes, ti::move_constructible::nothrow, ti::copy_constructible::yes, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::nothrow>>, // DefaultConstructibleNothrowMovable ProfileAndExpectation< ti::DefaultConstructibleNothrowMovableProfile, ti::DefaultConstructibleNothrowMovableArchetype, ti::ConformanceProfile< ti::default_constructible::yes, ti::move_constructible::nothrow, ti::copy_constructible::maybe, ti::move_assignable::nothrow, ti::copy_assignable::maybe, ti::destructible::nothrow, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::maybe, ti::greater_than_comparable::maybe, ti::swappable::nothrow>>, // DefaultConstructibleValue ProfileAndExpectation< ti::DefaultConstructibleValueProfile, ti::DefaultConstructibleValueArchetype, ti::ConformanceProfile< ti::default_constructible::yes, ti::move_constructible::nothrow, ti::copy_constructible::yes, ti::move_assignable::nothrow, ti::copy_assignable::yes, ti::destructible::nothrow, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::maybe, ti::greater_than_comparable::maybe, ti::swappable::nothrow>>>; using ComparableHelpersProfilesToTest = ::testing::Types< // Equatable ProfileAndExpectation< ti::EquatableProfile, ti::EquatableArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::yes, ti::inequality_comparable::yes>>, // Comparable ProfileAndExpectation< ti::ComparableProfile, ti::ComparableArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::yes, ti::inequality_comparable::yes, ti::less_than_comparable::yes, ti::less_equal_comparable::yes, ti::greater_equal_comparable::yes, ti::greater_than_comparable::yes>>, // NothrowEquatable ProfileAndExpectation< ti::NothrowEquatableProfile, ti::NothrowEquatableArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::nothrow, ti::inequality_comparable::nothrow>>, // NothrowComparable ProfileAndExpectation< ti::NothrowComparableProfile, ti::NothrowComparableArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::maybe, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::maybe, ti::equality_comparable::nothrow, ti::inequality_comparable::nothrow, ti::less_than_comparable::nothrow, ti::less_equal_comparable::nothrow, ti::greater_equal_comparable::nothrow, ti::greater_than_comparable::nothrow>>>; using CommonComparableProfilesToTest = ::testing::Types< // ComparableNothrowMoveConstructible ProfileAndExpectation< ti::ComparableNothrowMoveConstructibleProfile, ti::ComparableNothrowMoveConstructibleArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::nothrow, ti::copy_constructible::maybe, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::nothrow, ti::equality_comparable::yes, ti::inequality_comparable::yes, ti::less_than_comparable::yes, ti::less_equal_comparable::yes, ti::greater_equal_comparable::yes, ti::greater_than_comparable::yes>>, // ComparableCopyConstructible ProfileAndExpectation< ti::ComparableCopyConstructibleProfile, ti::ComparableCopyConstructibleArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::nothrow, ti::copy_constructible::yes, ti::move_assignable::maybe, ti::copy_assignable::maybe, ti::destructible::nothrow, ti::equality_comparable::yes, ti::inequality_comparable::yes, ti::less_than_comparable::yes, ti::less_equal_comparable::yes, ti::greater_equal_comparable::yes, ti::greater_than_comparable::yes>>, // ComparableNothrowMovable ProfileAndExpectation< ti::ComparableNothrowMovableProfile, ti::ComparableNothrowMovableArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::nothrow, ti::copy_constructible::maybe, ti::move_assignable::nothrow, ti::copy_assignable::maybe, ti::destructible::nothrow, ti::equality_comparable::yes, ti::inequality_comparable::yes, ti::less_than_comparable::yes, ti::less_equal_comparable::yes, ti::greater_equal_comparable::yes, ti::greater_than_comparable::yes, ti::swappable::nothrow>>, // ComparableValue ProfileAndExpectation< ti::ComparableValueProfile, ti::ComparableValueArchetype, ti::ConformanceProfile< ti::default_constructible::maybe, ti::move_constructible::nothrow, ti::copy_constructible::yes, ti::move_assignable::nothrow, ti::copy_assignable::yes, ti::destructible::nothrow, ti::equality_comparable::yes, ti::inequality_comparable::yes, ti::less_than_comparable::yes, ti::less_equal_comparable::yes, ti::greater_equal_comparable::yes, ti::greater_than_comparable::yes, ti::swappable::nothrow>>>; using TrivialProfilesToTest = ::testing::Types< ProfileAndExpectation< ti::TrivialSpecialMemberFunctionsProfile, ti::TrivialSpecialMemberFunctionsArchetype, ti::ConformanceProfile< ti::default_constructible::trivial, ti::move_constructible::trivial, ti::copy_constructible::trivial, ti::move_assignable::trivial, ti::copy_assignable::trivial, ti::destructible::trivial, ti::equality_comparable::maybe, ti::inequality_comparable::maybe, ti::less_than_comparable::maybe, ti::less_equal_comparable::maybe, ti::greater_equal_comparable::maybe, ti::greater_than_comparable::maybe, ti::swappable::nothrow>>, ProfileAndExpectation< ti::TriviallyCompleteProfile, ti::TriviallyCompleteArchetype, ti::ConformanceProfile< ti::default_constructible::trivial, ti::move_constructible::trivial, ti::copy_constructible::trivial, ti::move_assignable::trivial, ti::copy_assignable::trivial, ti::destructible::trivial, ti::equality_comparable::yes, ti::inequality_comparable::yes, ti::less_than_comparable::yes, ti::less_equal_comparable::yes, ti::greater_equal_comparable::yes, ti::greater_than_comparable::yes, ti::swappable::nothrow, ti::hashable::yes>>>; INSTANTIATE_TYPED_TEST_SUITE_P(Core, ProfileTest, CoreProfilesToTest); INSTANTIATE_TYPED_TEST_SUITE_P(Common, ProfileTest, CommonProfilesToTest); INSTANTIATE_TYPED_TEST_SUITE_P(ComparableHelpers, ProfileTest, ComparableHelpersProfilesToTest); INSTANTIATE_TYPED_TEST_SUITE_P(CommonComparable, ProfileTest, CommonComparableProfilesToTest); INSTANTIATE_TYPED_TEST_SUITE_P(Trivial, ProfileTest, TrivialProfilesToTest); // TODO(calabrese) Test runtime results } // namespace