From d659fe54b35ab9b8e35c72e50a4b8814167d5a84 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 4 Dec 2019 14:13:43 -0800 Subject: Export of internal Abseil changes -- c385118b3ef0528d150bfe7aeeb63e77f9e463cd by Matt Calabrese : Internal-only Archetype generation for testing generic code with user-defined types of various properties. PiperOrigin-RevId: 283833099 -- 4ccf340d3b295aa5b796ee5c97128b61d38899ea by Derek Mauro : Fixes the flags parse_test. Windows doesn't like consecutive path separators. PiperOrigin-RevId: 283614649 -- 5df6d83acb1e49cd1da785cfaf7551f05149f3c9 by Andy Getzendanner : ABSL_INTERNAL_LOG: forward complete __FILE__ to internal_log_function; not just basename. PiperOrigin-RevId: 283406080 GitOrigin-RevId: c385118b3ef0528d150bfe7aeeb63e77f9e463cd Change-Id: Ib0782354691a73fc40185c3262cfd507085b3393 --- absl/base/internal/raw_logging.h | 12 +- absl/flags/parse_test.cc | 16 +- absl/meta/type_traits.h | 45 +- absl/meta/type_traits_test.cc | 21 - absl/types/BUILD.bazel | 34 + absl/types/CMakeLists.txt | 46 + absl/types/internal/conformance_aliases.h | 445 +++++++++ absl/types/internal/conformance_archetype.h | 976 +++++++++++++++++++ absl/types/internal/conformance_profile.h | 374 +++++++ absl/types/internal/conformance_testing_test.cc | 1186 +++++++++++++++++++++++ 10 files changed, 3112 insertions(+), 43 deletions(-) create mode 100644 absl/types/internal/conformance_aliases.h create mode 100644 absl/types/internal/conformance_archetype.h create mode 100644 absl/types/internal/conformance_profile.h create mode 100644 absl/types/internal/conformance_testing_test.cc diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h index 6a4c093..49c8dfb 100644 --- a/absl/base/internal/raw_logging.h +++ b/absl/base/internal/raw_logging.h @@ -70,14 +70,10 @@ // // The API is a subset of the above: each macro only takes two arguments. Use // StrCat if you need to build a richer message. -#define ABSL_INTERNAL_LOG(severity, message) \ - do { \ - constexpr const char* absl_raw_logging_internal_basename = \ - ::absl::raw_logging_internal::Basename(__FILE__, \ - sizeof(__FILE__) - 1); \ - ::absl::raw_logging_internal::internal_log_function( \ - ABSL_RAW_LOGGING_INTERNAL_##severity, \ - absl_raw_logging_internal_basename, __LINE__, message); \ +#define ABSL_INTERNAL_LOG(severity, message) \ + do { \ + ::absl::raw_logging_internal::internal_log_function( \ + ABSL_RAW_LOGGING_INTERNAL_##severity, __FILE__, __LINE__, message); \ } while (0) #define ABSL_INTERNAL_CHECK(condition, message) \ diff --git a/absl/flags/parse_test.cc b/absl/flags/parse_test.cc index 447a3bc..f89fa96 100644 --- a/absl/flags/parse_test.cc +++ b/absl/flags/parse_test.cc @@ -22,6 +22,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/base/internal/scoped_set_env.h" #include "absl/flags/flag.h" +#include "absl/strings/match.h" #include "absl/strings/str_cat.h" #include "absl/strings/substitute.h" #include "absl/types/span.h" @@ -92,8 +93,11 @@ const std::string& GetTestTempDir() { auto len = GetTempPathA(MAX_PATH, temp_path_buffer); if (len < MAX_PATH && len != 0) { - std::string temp_dir_name = absl::StrCat( - temp_path_buffer, "\\parse_test.", GetCurrentProcessId()); + std::string temp_dir_name = temp_path_buffer; + if (!absl::EndsWith(temp_dir_name, "\\")) { + temp_dir_name.push_back('\\'); + } + absl::StrAppend(&temp_dir_name, "parse_test.", GetCurrentProcessId()); if (CreateDirectoryA(temp_dir_name.c_str(), nullptr)) { *res = temp_dir_name; } @@ -104,11 +108,11 @@ const std::string& GetTestTempDir() { *res = unique_name; } #endif + } - if (res->empty()) { - ABSL_INTERNAL_LOG(FATAL, - "Failed to make temporary directory for data files"); - } + if (res->empty()) { + ABSL_INTERNAL_LOG(FATAL, + "Failed to make temporary directory for data files"); } #ifdef _WIN32 diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index d57a879..8cd5f04 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -41,8 +41,18 @@ #include "absl/base/config.h" +// MSVC constructibility traits do not detect destructor properties and so our +// implementations should not use them as a source-of-truth. +#if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) +#define ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1 +#endif + namespace absl { +// Defined and documented later on in this file. +template +struct is_trivially_destructible; + // Defined and documented later on in this file. template struct is_trivially_move_assignable; @@ -65,6 +75,20 @@ union SingleMemberUnion { #pragma warning(pop) #endif // defined(_MSC_VER) && !defined(__GNUC__) +template +struct IsTriviallyMoveConstructibleObject + : std::integral_constant< + bool, std::is_move_constructible< + type_traits_internal::SingleMemberUnion>::value && + absl::is_trivially_destructible::value> {}; + +template +struct IsTriviallyCopyConstructibleObject + : std::integral_constant< + bool, std::is_copy_constructible< + type_traits_internal::SingleMemberUnion>::value && + absl::is_trivially_destructible::value> {}; + template struct IsTriviallyMoveAssignableReference : std::false_type {}; @@ -323,7 +347,9 @@ struct is_trivially_default_constructible : std::integral_constant::value && is_trivially_destructible::value> { -#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE +#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ + !defined( \ + ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) private: static constexpr bool compliant = std::is_trivially_default_constructible::value == @@ -354,10 +380,11 @@ template struct is_trivially_move_constructible : std::conditional< std::is_object::value && !std::is_array::value, - std::is_move_constructible< - type_traits_internal::SingleMemberUnion>, + type_traits_internal::IsTriviallyMoveConstructibleObject, std::is_reference>::type::type { -#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE +#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ + !defined( \ + ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) private: static constexpr bool compliant = std::is_trivially_move_constructible::value == @@ -388,10 +415,11 @@ template struct is_trivially_copy_constructible : std::conditional< std::is_object::value && !std::is_array::value, - std::is_copy_constructible< - type_traits_internal::SingleMemberUnion>, + type_traits_internal::IsTriviallyCopyConstructibleObject, std::is_lvalue_reference>::type::type { -#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE +#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ + !defined( \ + ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) private: static constexpr bool compliant = std::is_trivially_copy_constructible::value == @@ -423,7 +451,8 @@ struct is_trivially_copy_constructible template struct is_trivially_move_assignable : std::conditional< - std::is_object::value && !std::is_array::value, + std::is_object::value && !std::is_array::value && + std::is_move_assignable::value, std::is_move_assignable>, type_traits_internal::IsTriviallyMoveAssignableReference>::type:: type { diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc index 6fbb42f..1aafd0d 100644 --- a/absl/meta/type_traits_test.cc +++ b/absl/meta/type_traits_test.cc @@ -347,21 +347,6 @@ class Base { virtual ~Base() {} }; -// In GCC/Clang, std::is_trivially_constructible requires that the destructor is -// trivial. However, MSVC doesn't require that. This results in different -// behavior when checking is_trivially_constructible on any type with -// nontrivial destructor. Since absl::is_trivially_default_constructible and -// absl::is_trivially_copy_constructible both follows Clang/GCC's interpretation -// and check is_trivially_destructible, it results in inconsistency with -// std::is_trivially_xxx_constructible on MSVC. This macro is used to work -// around this issue in test. In practice, a trivially constructible type -// should also be trivially destructible. -// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 -// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116 -#ifndef _MSC_VER -#define ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE 1 -#endif - // Old versions of libc++, around Clang 3.5 to 3.6, consider deleted destructors // as also being trivial. With the resolution of CWG 1928 and CWG 1734, this // is no longer considered true and has thus been amended. @@ -499,11 +484,9 @@ TEST(TypeTraitsTest, TestTrivialDefaultCtor) { EXPECT_FALSE( absl::is_trivially_default_constructible::value); -#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE // types with nontrivial destructor are nontrivial EXPECT_FALSE( absl::is_trivially_default_constructible::value); -#endif // types with vtables EXPECT_FALSE(absl::is_trivially_default_constructible::value); @@ -607,11 +590,9 @@ TEST(TypeTraitsTest, TestTrivialMoveCtor) { EXPECT_FALSE( absl::is_trivially_move_constructible::value); -#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE // type with nontrivial destructor are nontrivial move construbtible EXPECT_FALSE( absl::is_trivially_move_constructible::value); -#endif // types with vtables EXPECT_FALSE(absl::is_trivially_move_constructible::value); @@ -682,11 +663,9 @@ TEST(TypeTraitsTest, TestTrivialCopyCtor) { EXPECT_FALSE( absl::is_trivially_copy_constructible::value); -#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE // type with nontrivial destructor are nontrivial copy construbtible EXPECT_FALSE( absl::is_trivially_copy_constructible::value); -#endif // types with vtables EXPECT_FALSE(absl::is_trivially_copy_constructible::value); diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel index 236c24b..f2ea9f3 100644 --- a/absl/types/BUILD.bazel +++ b/absl/types/BUILD.bazel @@ -208,6 +208,40 @@ cc_test( ], ) +cc_library( + name = "conformance_testing", + testonly = 1, + hdrs = [ + "internal/conformance_aliases.h", + "internal/conformance_archetype.h", + "internal/conformance_profile.h", + ], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + "//absl/debugging:demangle_internal", + "//absl/meta:type_traits", + "//absl/strings", + "//absl/utility", + "@com_google_googletest//:gtest", + ], +) + +cc_test( + name = "conformance_testing_test", + size = "small", + srcs = [ + "internal/conformance_testing_test.cc", + ], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":conformance_testing", + "//absl/meta:type_traits", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "variant", srcs = ["internal/variant.h"], diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt index 952efc3..c7c8825 100644 --- a/absl/types/CMakeLists.txt +++ b/absl/types/CMakeLists.txt @@ -238,6 +238,52 @@ absl_cc_test( gmock_main ) +absl_cc_library( + NAME + conformance_testing + HDRS + "internal/conformance_aliases.h" + "internal/conformance_archetype.h" + "internal/conformance_profile.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::debugging + absl::type_traits + absl::strings + absl::utility + gmock_main + PUBLIC +) + +absl_cc_test( + NAME + conformance_testing_test + SRCS + "internal/conformance_testing_test.cc" + COPTS + ${ABSL_TEST_COPTS} + ${ABSL_EXCEPTIONS_FLAG} + LINKOPTS + ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} + DEPS + absl::conformance_testing + absl::type_traits + gmock_main +) + +absl_cc_test( + NAME + conformance_testing_test_no_exceptions + SRCS + "internal/conformance_testing_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::conformance_testing + gmock_main +) + absl_cc_library( NAME variant diff --git a/absl/types/internal/conformance_aliases.h b/absl/types/internal/conformance_aliases.h new file mode 100644 index 0000000..7d5d0e0 --- /dev/null +++ b/absl/types/internal/conformance_aliases.h @@ -0,0 +1,445 @@ +// Copyright 2018 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. +// +// ----------------------------------------------------------------------------- +// regularity_aliases.h +// ----------------------------------------------------------------------------- +// +// This file contains type aliases of common ConformanceProfiles and Archetypes +// so that they can be directly used by name without creating them from scratch. + +#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_ALIASES_H_ +#define ABSL_TYPES_INTERNAL_CONFORMANCE_ALIASES_H_ + +#include "absl/types/internal/conformance_archetype.h" +#include "absl/types/internal/conformance_profile.h" + +namespace absl { +namespace types_internal { + +// Creates both a Profile and a corresponding Archetype with root name "name". +#define ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(name, ...) \ + struct name##Profile : __VA_ARGS__ {}; \ + \ + using name##Archetype = ::absl::types_internal::Archetype; \ + \ + template \ + using name##Archetype##_ = ::absl::types_internal::Archetype< \ + ::absl::types_internal::StrongProfileTypedef> + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialDefaultConstructor, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowDefaultConstructor, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasDefaultConstructor, ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialMoveConstructor, ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowMoveConstructor, ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasMoveConstructor, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialCopyConstructor, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowCopyConstructor, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasCopyConstructor, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialMoveAssign, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowMoveAssign, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasMoveAssign, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialCopyAssign, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowCopyAssign, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasCopyAssign, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialDestructor, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowDestructor, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasDestructor, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowEquality, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasEquality, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowInequality, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasInequality, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowLessThan, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasLessThan, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowLessEqual, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasLessEqual, + ConformanceProfile); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowGreaterEqual, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasGreaterEqual, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowGreaterThan, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::maybe, + greater_than_comparable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasGreaterThan, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::maybe, + greater_than_comparable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowSwap, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::maybe, + greater_than_comparable::maybe, swappable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasSwap, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::maybe, + greater_than_comparable::maybe, swappable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasStdHashSpecialization, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::maybe, + greater_than_comparable::maybe, swappable::maybe, hashable::yes>); + +//////////////////////////////////////////////////////////////////////////////// +//// The remaining aliases are combinations of the previous aliases. //// +//////////////////////////////////////////////////////////////////////////////// + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + Equatable, CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + Comparable, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + NothrowEquatable, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + NothrowComparable, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + Value, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + EquatableValue, CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + ComparableValue, CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + DefaultConstructibleValue, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + NothrowMoveConstructible, CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + EquatableNothrowMoveConstructible, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + ComparableNothrowMoveConstructible, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + DefaultConstructibleNothrowMoveConstructible, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + CopyConstructible, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + EquatableCopyConstructible, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + ComparableCopyConstructible, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + DefaultConstructibleCopyConstructible, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + NothrowMovable, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + EquatableNothrowMovable, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + ComparableNothrowMovable, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + DefaultConstructibleNothrowMovable, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + TrivialSpecialMemberFunctions, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + TriviallyComplete, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HashableNothrowMoveConstructible, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HashableCopyConstructible, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HashableNothrowMovable, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HashableValue, + CombineProfiles); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + ComparableHashableValue, + CombineProfiles); + +// The "preferred" profiles that we support in Abseil. +template