Export of internal Abseil changes
-- c385118b3ef0528d150bfe7aeeb63e77f9e463cd by Matt Calabrese <calabrese@google.com>: Internal-only Archetype generation for testing generic code with user-defined types of various properties. PiperOrigin-RevId: 283833099 -- 4ccf340d3b295aa5b796ee5c97128b61d38899ea by Derek Mauro <dmauro@google.com>: Fixes the flags parse_test. Windows doesn't like consecutive path separators. PiperOrigin-RevId: 283614649 -- 5df6d83acb1e49cd1da785cfaf7551f05149f3c9 by Andy Getzendanner <durandal@google.com>: ABSL_INTERNAL_LOG: forward complete __FILE__ to internal_log_function; not just basename. PiperOrigin-RevId: 283406080 GitOrigin-RevId: c385118b3ef0528d150bfe7aeeb63e77f9e463cd Change-Id: Ib0782354691a73fc40185c3262cfd507085b3393
This commit is contained in:
parent
a4b757b5d4
commit
d659fe54b3
10 changed files with 3112 additions and 43 deletions
|
@ -72,12 +72,8 @@
|
||||||
// StrCat if you need to build a richer message.
|
// StrCat if you need to build a richer message.
|
||||||
#define ABSL_INTERNAL_LOG(severity, message) \
|
#define ABSL_INTERNAL_LOG(severity, message) \
|
||||||
do { \
|
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::internal_log_function( \
|
||||||
ABSL_RAW_LOGGING_INTERNAL_##severity, \
|
ABSL_RAW_LOGGING_INTERNAL_##severity, __FILE__, __LINE__, message); \
|
||||||
absl_raw_logging_internal_basename, __LINE__, message); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define ABSL_INTERNAL_CHECK(condition, message) \
|
#define ABSL_INTERNAL_CHECK(condition, message) \
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "absl/base/internal/raw_logging.h"
|
#include "absl/base/internal/raw_logging.h"
|
||||||
#include "absl/base/internal/scoped_set_env.h"
|
#include "absl/base/internal/scoped_set_env.h"
|
||||||
#include "absl/flags/flag.h"
|
#include "absl/flags/flag.h"
|
||||||
|
#include "absl/strings/match.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/strings/substitute.h"
|
#include "absl/strings/substitute.h"
|
||||||
#include "absl/types/span.h"
|
#include "absl/types/span.h"
|
||||||
|
@ -92,8 +93,11 @@ const std::string& GetTestTempDir() {
|
||||||
|
|
||||||
auto len = GetTempPathA(MAX_PATH, temp_path_buffer);
|
auto len = GetTempPathA(MAX_PATH, temp_path_buffer);
|
||||||
if (len < MAX_PATH && len != 0) {
|
if (len < MAX_PATH && len != 0) {
|
||||||
std::string temp_dir_name = absl::StrCat(
|
std::string temp_dir_name = temp_path_buffer;
|
||||||
temp_path_buffer, "\\parse_test.", GetCurrentProcessId());
|
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)) {
|
if (CreateDirectoryA(temp_dir_name.c_str(), nullptr)) {
|
||||||
*res = temp_dir_name;
|
*res = temp_dir_name;
|
||||||
}
|
}
|
||||||
|
@ -104,12 +108,12 @@ const std::string& GetTestTempDir() {
|
||||||
*res = unique_name;
|
*res = unique_name;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (res->empty()) {
|
if (res->empty()) {
|
||||||
ABSL_INTERNAL_LOG(FATAL,
|
ABSL_INTERNAL_LOG(FATAL,
|
||||||
"Failed to make temporary directory for data files");
|
"Failed to make temporary directory for data files");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
*res += "\\";
|
*res += "\\";
|
||||||
|
|
|
@ -41,8 +41,18 @@
|
||||||
|
|
||||||
#include "absl/base/config.h"
|
#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 {
|
namespace absl {
|
||||||
|
|
||||||
|
// Defined and documented later on in this file.
|
||||||
|
template <typename T>
|
||||||
|
struct is_trivially_destructible;
|
||||||
|
|
||||||
// Defined and documented later on in this file.
|
// Defined and documented later on in this file.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_trivially_move_assignable;
|
struct is_trivially_move_assignable;
|
||||||
|
@ -65,6 +75,20 @@ union SingleMemberUnion {
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif // defined(_MSC_VER) && !defined(__GNUC__)
|
#endif // defined(_MSC_VER) && !defined(__GNUC__)
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct IsTriviallyMoveConstructibleObject
|
||||||
|
: std::integral_constant<
|
||||||
|
bool, std::is_move_constructible<
|
||||||
|
type_traits_internal::SingleMemberUnion<T>>::value &&
|
||||||
|
absl::is_trivially_destructible<T>::value> {};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct IsTriviallyCopyConstructibleObject
|
||||||
|
: std::integral_constant<
|
||||||
|
bool, std::is_copy_constructible<
|
||||||
|
type_traits_internal::SingleMemberUnion<T>>::value &&
|
||||||
|
absl::is_trivially_destructible<T>::value> {};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct IsTriviallyMoveAssignableReference : std::false_type {};
|
struct IsTriviallyMoveAssignableReference : std::false_type {};
|
||||||
|
|
||||||
|
@ -323,7 +347,9 @@ struct is_trivially_default_constructible
|
||||||
: std::integral_constant<bool, __has_trivial_constructor(T) &&
|
: std::integral_constant<bool, __has_trivial_constructor(T) &&
|
||||||
std::is_default_constructible<T>::value &&
|
std::is_default_constructible<T>::value &&
|
||||||
is_trivially_destructible<T>::value> {
|
is_trivially_destructible<T>::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:
|
private:
|
||||||
static constexpr bool compliant =
|
static constexpr bool compliant =
|
||||||
std::is_trivially_default_constructible<T>::value ==
|
std::is_trivially_default_constructible<T>::value ==
|
||||||
|
@ -354,10 +380,11 @@ template <typename T>
|
||||||
struct is_trivially_move_constructible
|
struct is_trivially_move_constructible
|
||||||
: std::conditional<
|
: std::conditional<
|
||||||
std::is_object<T>::value && !std::is_array<T>::value,
|
std::is_object<T>::value && !std::is_array<T>::value,
|
||||||
std::is_move_constructible<
|
type_traits_internal::IsTriviallyMoveConstructibleObject<T>,
|
||||||
type_traits_internal::SingleMemberUnion<T>>,
|
|
||||||
std::is_reference<T>>::type::type {
|
std::is_reference<T>>::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:
|
private:
|
||||||
static constexpr bool compliant =
|
static constexpr bool compliant =
|
||||||
std::is_trivially_move_constructible<T>::value ==
|
std::is_trivially_move_constructible<T>::value ==
|
||||||
|
@ -388,10 +415,11 @@ template <typename T>
|
||||||
struct is_trivially_copy_constructible
|
struct is_trivially_copy_constructible
|
||||||
: std::conditional<
|
: std::conditional<
|
||||||
std::is_object<T>::value && !std::is_array<T>::value,
|
std::is_object<T>::value && !std::is_array<T>::value,
|
||||||
std::is_copy_constructible<
|
type_traits_internal::IsTriviallyCopyConstructibleObject<T>,
|
||||||
type_traits_internal::SingleMemberUnion<T>>,
|
|
||||||
std::is_lvalue_reference<T>>::type::type {
|
std::is_lvalue_reference<T>>::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:
|
private:
|
||||||
static constexpr bool compliant =
|
static constexpr bool compliant =
|
||||||
std::is_trivially_copy_constructible<T>::value ==
|
std::is_trivially_copy_constructible<T>::value ==
|
||||||
|
@ -423,7 +451,8 @@ struct is_trivially_copy_constructible
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_trivially_move_assignable
|
struct is_trivially_move_assignable
|
||||||
: std::conditional<
|
: std::conditional<
|
||||||
std::is_object<T>::value && !std::is_array<T>::value,
|
std::is_object<T>::value && !std::is_array<T>::value &&
|
||||||
|
std::is_move_assignable<T>::value,
|
||||||
std::is_move_assignable<type_traits_internal::SingleMemberUnion<T>>,
|
std::is_move_assignable<type_traits_internal::SingleMemberUnion<T>>,
|
||||||
type_traits_internal::IsTriviallyMoveAssignableReference<T>>::type::
|
type_traits_internal::IsTriviallyMoveAssignableReference<T>>::type::
|
||||||
type {
|
type {
|
||||||
|
|
|
@ -347,21 +347,6 @@ class Base {
|
||||||
virtual ~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
|
// 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
|
// as also being trivial. With the resolution of CWG 1928 and CWG 1734, this
|
||||||
// is no longer considered true and has thus been amended.
|
// is no longer considered true and has thus been amended.
|
||||||
|
@ -499,11 +484,9 @@ TEST(TypeTraitsTest, TestTrivialDefaultCtor) {
|
||||||
EXPECT_FALSE(
|
EXPECT_FALSE(
|
||||||
absl::is_trivially_default_constructible<DeletedDefaultCtor>::value);
|
absl::is_trivially_default_constructible<DeletedDefaultCtor>::value);
|
||||||
|
|
||||||
#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
|
|
||||||
// types with nontrivial destructor are nontrivial
|
// types with nontrivial destructor are nontrivial
|
||||||
EXPECT_FALSE(
|
EXPECT_FALSE(
|
||||||
absl::is_trivially_default_constructible<NontrivialDestructor>::value);
|
absl::is_trivially_default_constructible<NontrivialDestructor>::value);
|
||||||
#endif
|
|
||||||
|
|
||||||
// types with vtables
|
// types with vtables
|
||||||
EXPECT_FALSE(absl::is_trivially_default_constructible<Base>::value);
|
EXPECT_FALSE(absl::is_trivially_default_constructible<Base>::value);
|
||||||
|
@ -607,11 +590,9 @@ TEST(TypeTraitsTest, TestTrivialMoveCtor) {
|
||||||
EXPECT_FALSE(
|
EXPECT_FALSE(
|
||||||
absl::is_trivially_move_constructible<NonCopyableOrMovable>::value);
|
absl::is_trivially_move_constructible<NonCopyableOrMovable>::value);
|
||||||
|
|
||||||
#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
|
|
||||||
// type with nontrivial destructor are nontrivial move construbtible
|
// type with nontrivial destructor are nontrivial move construbtible
|
||||||
EXPECT_FALSE(
|
EXPECT_FALSE(
|
||||||
absl::is_trivially_move_constructible<NontrivialDestructor>::value);
|
absl::is_trivially_move_constructible<NontrivialDestructor>::value);
|
||||||
#endif
|
|
||||||
|
|
||||||
// types with vtables
|
// types with vtables
|
||||||
EXPECT_FALSE(absl::is_trivially_move_constructible<Base>::value);
|
EXPECT_FALSE(absl::is_trivially_move_constructible<Base>::value);
|
||||||
|
@ -682,11 +663,9 @@ TEST(TypeTraitsTest, TestTrivialCopyCtor) {
|
||||||
EXPECT_FALSE(
|
EXPECT_FALSE(
|
||||||
absl::is_trivially_copy_constructible<NonCopyableOrMovable>::value);
|
absl::is_trivially_copy_constructible<NonCopyableOrMovable>::value);
|
||||||
|
|
||||||
#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
|
|
||||||
// type with nontrivial destructor are nontrivial copy construbtible
|
// type with nontrivial destructor are nontrivial copy construbtible
|
||||||
EXPECT_FALSE(
|
EXPECT_FALSE(
|
||||||
absl::is_trivially_copy_constructible<NontrivialDestructor>::value);
|
absl::is_trivially_copy_constructible<NontrivialDestructor>::value);
|
||||||
#endif
|
|
||||||
|
|
||||||
// types with vtables
|
// types with vtables
|
||||||
EXPECT_FALSE(absl::is_trivially_copy_constructible<Base>::value);
|
EXPECT_FALSE(absl::is_trivially_copy_constructible<Base>::value);
|
||||||
|
|
|
@ -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(
|
cc_library(
|
||||||
name = "variant",
|
name = "variant",
|
||||||
srcs = ["internal/variant.h"],
|
srcs = ["internal/variant.h"],
|
||||||
|
|
|
@ -238,6 +238,52 @@ absl_cc_test(
|
||||||
gmock_main
|
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(
|
absl_cc_library(
|
||||||
NAME
|
NAME
|
||||||
variant
|
variant
|
||||||
|
|
445
absl/types/internal/conformance_aliases.h
Normal file
445
absl/types/internal/conformance_aliases.h
Normal file
|
@ -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<name##Profile>; \
|
||||||
|
\
|
||||||
|
template <class AbslInternalProfileTag> \
|
||||||
|
using name##Archetype##_ = ::absl::types_internal::Archetype< \
|
||||||
|
::absl::types_internal::StrongProfileTypedef<name##Profile, \
|
||||||
|
AbslInternalProfileTag>>
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasTrivialDefaultConstructor,
|
||||||
|
ConformanceProfile<default_constructible::trivial>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasNothrowDefaultConstructor,
|
||||||
|
ConformanceProfile<default_constructible::nothrow>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasDefaultConstructor, ConformanceProfile<default_constructible::yes>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasTrivialMoveConstructor, ConformanceProfile<default_constructible::maybe,
|
||||||
|
move_constructible::trivial>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasNothrowMoveConstructor, ConformanceProfile<default_constructible::maybe,
|
||||||
|
move_constructible::nothrow>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasMoveConstructor,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::yes>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasTrivialCopyConstructor,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::trivial>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasNothrowCopyConstructor,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::nothrow>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasCopyConstructor,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::yes>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasTrivialMoveAssign,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::trivial>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasNothrowMoveAssign,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::nothrow>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasMoveAssign,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::yes>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasTrivialCopyAssign,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::maybe,
|
||||||
|
copy_assignable::trivial>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasNothrowCopyAssign,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::maybe,
|
||||||
|
copy_assignable::nothrow>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasCopyAssign,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::maybe,
|
||||||
|
copy_assignable::yes>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasTrivialDestructor,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::maybe,
|
||||||
|
copy_assignable::maybe, destructible::trivial>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasNothrowDestructor,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::maybe,
|
||||||
|
copy_assignable::maybe, destructible::nothrow>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasDestructor,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::maybe,
|
||||||
|
copy_assignable::maybe, destructible::yes>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasNothrowEquality,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::maybe,
|
||||||
|
copy_assignable::maybe, destructible::maybe,
|
||||||
|
equality_comparable::nothrow>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasEquality,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::maybe,
|
||||||
|
copy_assignable::maybe, destructible::maybe,
|
||||||
|
equality_comparable::yes>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasNothrowInequality,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::maybe,
|
||||||
|
copy_assignable::maybe, destructible::maybe,
|
||||||
|
equality_comparable::maybe,
|
||||||
|
inequality_comparable::nothrow>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasInequality,
|
||||||
|
ConformanceProfile<default_constructible::maybe, move_constructible::maybe,
|
||||||
|
copy_constructible::maybe, move_assignable::maybe,
|
||||||
|
copy_assignable::maybe, destructible::maybe,
|
||||||
|
equality_comparable::maybe, inequality_comparable::yes>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasNothrowLessThan,
|
||||||
|
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::nothrow>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasLessThan,
|
||||||
|
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::yes>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasNothrowLessEqual,
|
||||||
|
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::nothrow>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HasLessEqual,
|
||||||
|
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::yes>);
|
||||||
|
|
||||||
|
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<HasEqualityProfile, HasInequalityProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
Comparable,
|
||||||
|
CombineProfiles<EquatableProfile, HasLessThanProfile, HasLessEqualProfile,
|
||||||
|
HasGreaterEqualProfile, HasGreaterThanProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
NothrowEquatable,
|
||||||
|
CombineProfiles<HasNothrowEqualityProfile, HasNothrowInequalityProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
NothrowComparable,
|
||||||
|
CombineProfiles<NothrowEquatableProfile, HasNothrowLessThanProfile,
|
||||||
|
HasNothrowLessEqualProfile, HasNothrowGreaterEqualProfile,
|
||||||
|
HasNothrowGreaterThanProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
Value,
|
||||||
|
CombineProfiles<HasNothrowMoveConstructorProfile, HasCopyConstructorProfile,
|
||||||
|
HasNothrowMoveAssignProfile, HasCopyAssignProfile,
|
||||||
|
HasNothrowDestructorProfile, HasNothrowSwapProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
EquatableValue, CombineProfiles<EquatableProfile, ValueProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
ComparableValue, CombineProfiles<ComparableProfile, ValueProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
DefaultConstructibleValue,
|
||||||
|
CombineProfiles<HasDefaultConstructorProfile, ValueProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
NothrowMoveConstructible, CombineProfiles<HasNothrowMoveConstructorProfile,
|
||||||
|
HasNothrowDestructorProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
EquatableNothrowMoveConstructible,
|
||||||
|
CombineProfiles<EquatableProfile, NothrowMoveConstructibleProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
ComparableNothrowMoveConstructible,
|
||||||
|
CombineProfiles<ComparableProfile, NothrowMoveConstructibleProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
DefaultConstructibleNothrowMoveConstructible,
|
||||||
|
CombineProfiles<HasDefaultConstructorProfile,
|
||||||
|
NothrowMoveConstructibleProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
CopyConstructible,
|
||||||
|
CombineProfiles<HasNothrowMoveConstructorProfile, HasCopyConstructorProfile,
|
||||||
|
HasNothrowDestructorProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
EquatableCopyConstructible,
|
||||||
|
CombineProfiles<EquatableProfile, CopyConstructibleProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
ComparableCopyConstructible,
|
||||||
|
CombineProfiles<ComparableProfile, CopyConstructibleProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
DefaultConstructibleCopyConstructible,
|
||||||
|
CombineProfiles<HasDefaultConstructorProfile, CopyConstructibleProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
NothrowMovable,
|
||||||
|
CombineProfiles<HasNothrowMoveConstructorProfile,
|
||||||
|
HasNothrowMoveAssignProfile, HasNothrowDestructorProfile,
|
||||||
|
HasNothrowSwapProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
EquatableNothrowMovable,
|
||||||
|
CombineProfiles<EquatableProfile, NothrowMovableProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
ComparableNothrowMovable,
|
||||||
|
CombineProfiles<ComparableProfile, NothrowMovableProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
DefaultConstructibleNothrowMovable,
|
||||||
|
CombineProfiles<HasDefaultConstructorProfile, NothrowMovableProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
TrivialSpecialMemberFunctions,
|
||||||
|
CombineProfiles<HasTrivialDefaultConstructorProfile,
|
||||||
|
HasTrivialMoveConstructorProfile,
|
||||||
|
HasTrivialCopyConstructorProfile,
|
||||||
|
HasTrivialMoveAssignProfile, HasTrivialCopyAssignProfile,
|
||||||
|
HasTrivialDestructorProfile, HasNothrowSwapProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
TriviallyComplete,
|
||||||
|
CombineProfiles<TrivialSpecialMemberFunctionsProfile, ComparableProfile,
|
||||||
|
HasStdHashSpecializationProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HashableNothrowMoveConstructible,
|
||||||
|
CombineProfiles<HasStdHashSpecializationProfile,
|
||||||
|
NothrowMoveConstructibleProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HashableCopyConstructible,
|
||||||
|
CombineProfiles<HasStdHashSpecializationProfile, CopyConstructibleProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HashableNothrowMovable,
|
||||||
|
CombineProfiles<HasStdHashSpecializationProfile, NothrowMovableProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
HashableValue,
|
||||||
|
CombineProfiles<HasStdHashSpecializationProfile, ValueProfile>);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(
|
||||||
|
ComparableHashableValue,
|
||||||
|
CombineProfiles<HashableValueProfile, ComparableProfile>);
|
||||||
|
|
||||||
|
// The "preferred" profiles that we support in Abseil.
|
||||||
|
template <template <class...> class Receiver>
|
||||||
|
using ExpandBasicProfiles =
|
||||||
|
Receiver<NothrowMoveConstructibleProfile, CopyConstructibleProfile,
|
||||||
|
NothrowMovableProfile, ValueProfile>;
|
||||||
|
|
||||||
|
// The basic profiles except that they are also all Equatable.
|
||||||
|
template <template <class...> class Receiver>
|
||||||
|
using ExpandBasicEquatableProfiles =
|
||||||
|
Receiver<EquatableNothrowMoveConstructibleProfile,
|
||||||
|
EquatableCopyConstructibleProfile, EquatableNothrowMovableProfile,
|
||||||
|
EquatableValueProfile>;
|
||||||
|
|
||||||
|
// The basic profiles except that they are also all Comparable.
|
||||||
|
template <template <class...> class Receiver>
|
||||||
|
using ExpandBasicComparableProfiles =
|
||||||
|
Receiver<ComparableNothrowMoveConstructibleProfile,
|
||||||
|
ComparableCopyConstructibleProfile,
|
||||||
|
ComparableNothrowMovableProfile, ComparableValueProfile>;
|
||||||
|
|
||||||
|
// The basic profiles except that they are also all Hashable.
|
||||||
|
template <template <class...> class Receiver>
|
||||||
|
using ExpandBasicHashableProfiles =
|
||||||
|
Receiver<HashableNothrowMoveConstructibleProfile,
|
||||||
|
HashableCopyConstructibleProfile, HashableNothrowMovableProfile,
|
||||||
|
HashableValueProfile>;
|
||||||
|
|
||||||
|
// The basic profiles except that they are also all DefaultConstructible.
|
||||||
|
template <template <class...> class Receiver>
|
||||||
|
using ExpandBasicDefaultConstructibleProfiles =
|
||||||
|
Receiver<DefaultConstructibleNothrowMoveConstructibleProfile,
|
||||||
|
DefaultConstructibleCopyConstructibleProfile,
|
||||||
|
DefaultConstructibleNothrowMovableProfile,
|
||||||
|
DefaultConstructibleValueProfile>;
|
||||||
|
|
||||||
|
// The type profiles that we support in Abseil (all of the previous lists).
|
||||||
|
template <template <class...> class Receiver>
|
||||||
|
using ExpandSupportedProfiles = Receiver<
|
||||||
|
NothrowMoveConstructibleProfile, CopyConstructibleProfile,
|
||||||
|
NothrowMovableProfile, ValueProfile,
|
||||||
|
EquatableNothrowMoveConstructibleProfile, EquatableCopyConstructibleProfile,
|
||||||
|
EquatableNothrowMovableProfile, EquatableValueProfile,
|
||||||
|
ComparableNothrowMoveConstructibleProfile,
|
||||||
|
ComparableCopyConstructibleProfile, ComparableNothrowMovableProfile,
|
||||||
|
ComparableValueProfile, DefaultConstructibleNothrowMoveConstructibleProfile,
|
||||||
|
DefaultConstructibleCopyConstructibleProfile,
|
||||||
|
DefaultConstructibleNothrowMovableProfile, DefaultConstructibleValueProfile,
|
||||||
|
HashableNothrowMoveConstructibleProfile, HashableCopyConstructibleProfile,
|
||||||
|
HashableNothrowMovableProfile, HashableValueProfile>;
|
||||||
|
|
||||||
|
// TODO(calabrese) Include types that have throwing move constructors, since in
|
||||||
|
// practice we still need to support them because of standard library types with
|
||||||
|
// (potentially) non-noexcept moves.
|
||||||
|
|
||||||
|
} // namespace types_internal
|
||||||
|
} // namespace absl
|
||||||
|
|
||||||
|
#undef ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS
|
||||||
|
|
||||||
|
#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_ALIASES_H_
|
976
absl/types/internal/conformance_archetype.h
Normal file
976
absl/types/internal/conformance_archetype.h
Normal file
|
@ -0,0 +1,976 @@
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// conformance_archetype.h
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file contains a facility for generating "archetypes" of out of
|
||||||
|
// "Conformance Profiles" (see "conformance_profiles.h" for more information
|
||||||
|
// about Conformance Profiles). An archetype is a type that aims to support the
|
||||||
|
// bare minimum requirements of a given Conformance Profile. For instance, an
|
||||||
|
// archetype that corresponds to an ImmutableProfile has exactly a nothrow
|
||||||
|
// move-constructor, a potentially-throwing copy constructor, a nothrow
|
||||||
|
// destructor, with all other special-member-functions deleted. These archetypes
|
||||||
|
// are useful for testing to make sure that templates are able to work with the
|
||||||
|
// kinds of types that they claim to support (i.e. that they do not accidentally
|
||||||
|
// under-constrain),
|
||||||
|
//
|
||||||
|
// The main type template in this file is the Archetype template, which takes
|
||||||
|
// a Conformance Profile as a template argument and its instantiations are a
|
||||||
|
// minimum-conforming model of that profile.
|
||||||
|
|
||||||
|
#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_ARCHETYPE_H_
|
||||||
|
#define ABSL_TYPES_INTERNAL_CONFORMANCE_ARCHETYPE_H_
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <functional>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "absl/meta/type_traits.h"
|
||||||
|
#include "absl/types/internal/conformance_profile.h"
|
||||||
|
|
||||||
|
namespace absl {
|
||||||
|
namespace types_internal {
|
||||||
|
|
||||||
|
// A minimum-conforming implementation of a type with properties specified in
|
||||||
|
// `Prof`, where `Prof` is a valid Conformance Profile.
|
||||||
|
template <class Prof, class /*Enabler*/ = void>
|
||||||
|
class Archetype;
|
||||||
|
|
||||||
|
// Given an Archetype, obtain the properties of the profile associated with that
|
||||||
|
// archetype.
|
||||||
|
template <class Archetype>
|
||||||
|
struct PropertiesOfArchetype;
|
||||||
|
|
||||||
|
template <class Prof>
|
||||||
|
struct PropertiesOfArchetype<Archetype<Prof>> {
|
||||||
|
using type = PropertiesOfT<Prof>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Archetype>
|
||||||
|
using PropertiesOfArchetypeT = typename PropertiesOfArchetype<Archetype>::type;
|
||||||
|
|
||||||
|
// A metafunction to determine if a type is an `Archetype`.
|
||||||
|
template <class T>
|
||||||
|
struct IsArchetype : std::false_type {};
|
||||||
|
|
||||||
|
template <class Prof>
|
||||||
|
struct IsArchetype<Archetype<Prof>> : std::true_type {};
|
||||||
|
|
||||||
|
// A constructor tag type used when creating an Archetype with internal state.
|
||||||
|
struct MakeArchetypeState {};
|
||||||
|
|
||||||
|
// Data stored within an archetype that is copied/compared/hashed when the
|
||||||
|
// corresponding operations are used.
|
||||||
|
using ArchetypeState = std::size_t;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// This section of the file defines a chain of base classes for Archetype, //
|
||||||
|
// where each base defines a specific special member function with the //
|
||||||
|
// appropriate properties (deleted, noexcept(false), noexcept, or trivial). //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// The bottom-most base, which contains the state and the default constructor.
|
||||||
|
template <default_constructible DefaultConstructibleValue>
|
||||||
|
struct ArchetypeStateBase {
|
||||||
|
static_assert(DefaultConstructibleValue == default_constructible::yes ||
|
||||||
|
DefaultConstructibleValue == default_constructible::nothrow,
|
||||||
|
"");
|
||||||
|
|
||||||
|
ArchetypeStateBase() noexcept(
|
||||||
|
DefaultConstructibleValue ==
|
||||||
|
default_constructible::
|
||||||
|
nothrow) /*Vacuous archetype_state initialization*/ {}
|
||||||
|
explicit ArchetypeStateBase(MakeArchetypeState, ArchetypeState state) noexcept
|
||||||
|
: archetype_state(state) {}
|
||||||
|
|
||||||
|
ArchetypeState archetype_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct ArchetypeStateBase<default_constructible::maybe> {
|
||||||
|
explicit ArchetypeStateBase() = delete;
|
||||||
|
explicit ArchetypeStateBase(MakeArchetypeState, ArchetypeState state) noexcept
|
||||||
|
: archetype_state(state) {}
|
||||||
|
|
||||||
|
ArchetypeState archetype_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct ArchetypeStateBase<default_constructible::trivial> {
|
||||||
|
ArchetypeStateBase() = default;
|
||||||
|
explicit ArchetypeStateBase(MakeArchetypeState, ArchetypeState state) noexcept
|
||||||
|
: archetype_state(state) {}
|
||||||
|
|
||||||
|
ArchetypeState archetype_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The move-constructor base
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue>
|
||||||
|
struct ArchetypeMoveConstructor
|
||||||
|
: ArchetypeStateBase<DefaultConstructibleValue> {
|
||||||
|
static_assert(MoveConstructibleValue == move_constructible::yes ||
|
||||||
|
MoveConstructibleValue == move_constructible::nothrow,
|
||||||
|
"");
|
||||||
|
|
||||||
|
explicit ArchetypeMoveConstructor(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeStateBase<DefaultConstructibleValue>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
ArchetypeMoveConstructor() = default;
|
||||||
|
ArchetypeMoveConstructor(ArchetypeMoveConstructor&& other) noexcept(
|
||||||
|
MoveConstructibleValue == move_constructible::nothrow)
|
||||||
|
: ArchetypeStateBase<DefaultConstructibleValue>(MakeArchetypeState(),
|
||||||
|
other.archetype_state) {}
|
||||||
|
ArchetypeMoveConstructor(const ArchetypeMoveConstructor&) = default;
|
||||||
|
ArchetypeMoveConstructor& operator=(ArchetypeMoveConstructor&&) = default;
|
||||||
|
ArchetypeMoveConstructor& operator=(const ArchetypeMoveConstructor&) =
|
||||||
|
default;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <default_constructible DefaultConstructibleValue>
|
||||||
|
struct ArchetypeMoveConstructor<DefaultConstructibleValue,
|
||||||
|
move_constructible::trivial>
|
||||||
|
: ArchetypeStateBase<DefaultConstructibleValue> {
|
||||||
|
explicit ArchetypeMoveConstructor(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeStateBase<DefaultConstructibleValue>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
ArchetypeMoveConstructor() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The copy-constructor base
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue,
|
||||||
|
copy_constructible CopyConstructibleValue>
|
||||||
|
struct ArchetypeCopyConstructor
|
||||||
|
: ArchetypeMoveConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue> {
|
||||||
|
static_assert(CopyConstructibleValue == copy_constructible::yes ||
|
||||||
|
CopyConstructibleValue == copy_constructible::nothrow,
|
||||||
|
"");
|
||||||
|
explicit ArchetypeCopyConstructor(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeMoveConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
ArchetypeCopyConstructor() = default;
|
||||||
|
ArchetypeCopyConstructor(ArchetypeCopyConstructor&&) = default;
|
||||||
|
ArchetypeCopyConstructor(const ArchetypeCopyConstructor& other) noexcept(
|
||||||
|
CopyConstructibleValue == copy_constructible::nothrow)
|
||||||
|
: ArchetypeMoveConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue>(
|
||||||
|
MakeArchetypeState(), other.archetype_state) {}
|
||||||
|
ArchetypeCopyConstructor& operator=(ArchetypeCopyConstructor&&) = default;
|
||||||
|
ArchetypeCopyConstructor& operator=(const ArchetypeCopyConstructor&) =
|
||||||
|
default;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue>
|
||||||
|
struct ArchetypeCopyConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue,
|
||||||
|
copy_constructible::maybe>
|
||||||
|
: ArchetypeMoveConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue> {
|
||||||
|
explicit ArchetypeCopyConstructor(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeMoveConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
ArchetypeCopyConstructor() = default;
|
||||||
|
ArchetypeCopyConstructor(ArchetypeCopyConstructor&&) = default;
|
||||||
|
ArchetypeCopyConstructor(const ArchetypeCopyConstructor&) = delete;
|
||||||
|
ArchetypeCopyConstructor& operator=(ArchetypeCopyConstructor&&) = default;
|
||||||
|
ArchetypeCopyConstructor& operator=(const ArchetypeCopyConstructor&) =
|
||||||
|
default;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue>
|
||||||
|
struct ArchetypeCopyConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue,
|
||||||
|
copy_constructible::trivial>
|
||||||
|
: ArchetypeMoveConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue> {
|
||||||
|
explicit ArchetypeCopyConstructor(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeMoveConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
ArchetypeCopyConstructor() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The move-assign base
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue,
|
||||||
|
copy_constructible CopyConstructibleValue,
|
||||||
|
move_assignable MoveAssignableValue>
|
||||||
|
struct ArchetypeMoveAssign
|
||||||
|
: ArchetypeCopyConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue, CopyConstructibleValue> {
|
||||||
|
static_assert(MoveAssignableValue == move_assignable::yes ||
|
||||||
|
MoveAssignableValue == move_assignable::nothrow,
|
||||||
|
"");
|
||||||
|
explicit ArchetypeMoveAssign(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeCopyConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
ArchetypeMoveAssign() = default;
|
||||||
|
ArchetypeMoveAssign(ArchetypeMoveAssign&&) = default;
|
||||||
|
ArchetypeMoveAssign(const ArchetypeMoveAssign&) = default;
|
||||||
|
ArchetypeMoveAssign& operator=(ArchetypeMoveAssign&& other) noexcept(
|
||||||
|
MoveAssignableValue == move_assignable::nothrow) {
|
||||||
|
this->archetype_state = other.archetype_state;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchetypeMoveAssign& operator=(const ArchetypeMoveAssign&) = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue,
|
||||||
|
copy_constructible CopyConstructibleValue>
|
||||||
|
struct ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, move_assignable::trivial>
|
||||||
|
: ArchetypeCopyConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue, CopyConstructibleValue> {
|
||||||
|
explicit ArchetypeMoveAssign(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeCopyConstructor<DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
ArchetypeMoveAssign() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The copy-assign base
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue,
|
||||||
|
copy_constructible CopyConstructibleValue,
|
||||||
|
move_assignable MoveAssignableValue,
|
||||||
|
copy_assignable CopyAssignableValue>
|
||||||
|
struct ArchetypeCopyAssign
|
||||||
|
: ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue> {
|
||||||
|
static_assert(CopyAssignableValue == copy_assignable::yes ||
|
||||||
|
CopyAssignableValue == copy_assignable::nothrow,
|
||||||
|
"");
|
||||||
|
explicit ArchetypeCopyAssign(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue>(
|
||||||
|
MakeArchetypeState(), state) {}
|
||||||
|
|
||||||
|
ArchetypeCopyAssign() = default;
|
||||||
|
ArchetypeCopyAssign(ArchetypeCopyAssign&&) = default;
|
||||||
|
ArchetypeCopyAssign(const ArchetypeCopyAssign&) = default;
|
||||||
|
ArchetypeCopyAssign& operator=(ArchetypeCopyAssign&&) = default;
|
||||||
|
|
||||||
|
ArchetypeCopyAssign& operator=(const ArchetypeCopyAssign& other) noexcept(
|
||||||
|
CopyAssignableValue == copy_assignable::nothrow) {
|
||||||
|
this->archetype_state = other.archetype_state;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue,
|
||||||
|
copy_constructible CopyConstructibleValue,
|
||||||
|
move_assignable MoveAssignableValue>
|
||||||
|
struct ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue,
|
||||||
|
copy_assignable::maybe>
|
||||||
|
: ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue> {
|
||||||
|
explicit ArchetypeCopyAssign(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue>(
|
||||||
|
MakeArchetypeState(), state) {}
|
||||||
|
|
||||||
|
ArchetypeCopyAssign() = default;
|
||||||
|
ArchetypeCopyAssign(ArchetypeCopyAssign&&) = default;
|
||||||
|
ArchetypeCopyAssign(const ArchetypeCopyAssign&) = default;
|
||||||
|
ArchetypeCopyAssign& operator=(ArchetypeCopyAssign&&) = default;
|
||||||
|
ArchetypeCopyAssign& operator=(const ArchetypeCopyAssign&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue,
|
||||||
|
copy_constructible CopyConstructibleValue,
|
||||||
|
move_assignable MoveAssignableValue>
|
||||||
|
struct ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue,
|
||||||
|
copy_assignable::trivial>
|
||||||
|
: ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue> {
|
||||||
|
explicit ArchetypeCopyAssign(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue>(
|
||||||
|
MakeArchetypeState(), state) {}
|
||||||
|
|
||||||
|
ArchetypeCopyAssign() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The destructor base
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue,
|
||||||
|
copy_constructible CopyConstructibleValue,
|
||||||
|
move_assignable MoveAssignableValue,
|
||||||
|
copy_assignable CopyAssignableValue, destructible DestructibleValue>
|
||||||
|
struct ArchetypeDestructor
|
||||||
|
: ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue,
|
||||||
|
CopyAssignableValue> {
|
||||||
|
static_assert(DestructibleValue == destructible::yes ||
|
||||||
|
DestructibleValue == destructible::nothrow,
|
||||||
|
"");
|
||||||
|
|
||||||
|
explicit ArchetypeDestructor(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue,
|
||||||
|
CopyAssignableValue>(MakeArchetypeState(), state) {}
|
||||||
|
|
||||||
|
ArchetypeDestructor() = default;
|
||||||
|
ArchetypeDestructor(ArchetypeDestructor&&) = default;
|
||||||
|
ArchetypeDestructor(const ArchetypeDestructor&) = default;
|
||||||
|
ArchetypeDestructor& operator=(ArchetypeDestructor&&) = default;
|
||||||
|
ArchetypeDestructor& operator=(const ArchetypeDestructor&) = default;
|
||||||
|
~ArchetypeDestructor() noexcept(DestructibleValue == destructible::nothrow) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue,
|
||||||
|
copy_constructible CopyConstructibleValue,
|
||||||
|
move_assignable MoveAssignableValue,
|
||||||
|
copy_assignable CopyAssignableValue>
|
||||||
|
struct ArchetypeDestructor<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue,
|
||||||
|
CopyAssignableValue, destructible::trivial>
|
||||||
|
: ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue,
|
||||||
|
CopyAssignableValue> {
|
||||||
|
explicit ArchetypeDestructor(MakeArchetypeState,
|
||||||
|
ArchetypeState state) noexcept
|
||||||
|
: ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue,
|
||||||
|
CopyConstructibleValue, MoveAssignableValue,
|
||||||
|
CopyAssignableValue>(MakeArchetypeState(), state) {}
|
||||||
|
|
||||||
|
ArchetypeDestructor() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// An alias to the top of the chain of bases for special-member functions.
|
||||||
|
// NOTE: move_constructible::maybe, move_assignable::maybe, and
|
||||||
|
// destructible::maybe are handled in the top-level type by way of SFINAE.
|
||||||
|
// Because of this, we never instantiate the base classes with
|
||||||
|
// move_constructible::maybe, move_assignable::maybe, or destructible::maybe so
|
||||||
|
// that we minimize the number of different possible type-template
|
||||||
|
// instantiations.
|
||||||
|
template <default_constructible DefaultConstructibleValue,
|
||||||
|
move_constructible MoveConstructibleValue,
|
||||||
|
copy_constructible CopyConstructibleValue,
|
||||||
|
move_assignable MoveAssignableValue,
|
||||||
|
copy_assignable CopyAssignableValue, destructible DestructibleValue>
|
||||||
|
using ArchetypeSpecialMembersBase = ArchetypeDestructor<
|
||||||
|
DefaultConstructibleValue,
|
||||||
|
MoveConstructibleValue != move_constructible::maybe
|
||||||
|
? MoveConstructibleValue
|
||||||
|
: move_constructible::nothrow,
|
||||||
|
CopyConstructibleValue,
|
||||||
|
MoveAssignableValue != move_assignable::maybe ? MoveAssignableValue
|
||||||
|
: move_assignable::nothrow,
|
||||||
|
CopyAssignableValue,
|
||||||
|
DestructibleValue != destructible::maybe ? DestructibleValue
|
||||||
|
: destructible::nothrow>;
|
||||||
|
|
||||||
|
// A function that is used to create an archetype with some associated state.
|
||||||
|
template <class Arch>
|
||||||
|
Arch MakeArchetype(ArchetypeState state) noexcept {
|
||||||
|
static_assert(IsArchetype<Arch>::value,
|
||||||
|
"The explicit template argument to MakeArchetype is required "
|
||||||
|
"to be an Archetype.");
|
||||||
|
return Arch(MakeArchetypeState(), state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is used to conditionally delete "copy" and "move" constructors in a way
|
||||||
|
// that is consistent with what the ConformanceProfile requires and that also
|
||||||
|
// strictly enforces the arguments to the copy/move to not come from implicit
|
||||||
|
// conversions when dealing with the Archetype.
|
||||||
|
template <class Prof, class T>
|
||||||
|
constexpr bool ShouldDeleteConstructor() {
|
||||||
|
return !((PropertiesOfT<Prof>::move_constructible_support !=
|
||||||
|
move_constructible::maybe &&
|
||||||
|
std::is_same<T, Archetype<Prof>>::value) ||
|
||||||
|
(PropertiesOfT<Prof>::copy_constructible_support !=
|
||||||
|
copy_constructible::maybe &&
|
||||||
|
(std::is_same<T, const Archetype<Prof>&>::value ||
|
||||||
|
std::is_same<T, Archetype<Prof>&>::value ||
|
||||||
|
std::is_same<T, const Archetype<Prof>>::value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is used to conditionally delete "copy" and "move" assigns in a way
|
||||||
|
// that is consistent with what the ConformanceProfile requires and that also
|
||||||
|
// strictly enforces the arguments to the copy/move to not come from implicit
|
||||||
|
// conversions when dealing with the Archetype.
|
||||||
|
template <class Prof, class T>
|
||||||
|
constexpr bool ShouldDeleteAssign() {
|
||||||
|
return !(
|
||||||
|
(PropertiesOfT<Prof>::move_assignable_support != move_assignable::maybe &&
|
||||||
|
std::is_same<T, Archetype<Prof>>::value) ||
|
||||||
|
(PropertiesOfT<Prof>::copy_assignable_support != copy_assignable::maybe &&
|
||||||
|
(std::is_same<T, const Archetype<Prof>&>::value ||
|
||||||
|
std::is_same<T, Archetype<Prof>&>::value ||
|
||||||
|
std::is_same<T, const Archetype<Prof>>::value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(calabrese) Inherit from a chain of secondary bases to pull in the
|
||||||
|
// associated functions of other concepts.
|
||||||
|
template <class Prof, class Enabler>
|
||||||
|
class Archetype : ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support> {
|
||||||
|
static_assert(std::is_same<Enabler, void>::value,
|
||||||
|
"An explicit type must not be passed as the second template "
|
||||||
|
"argument to 'Archetype`.");
|
||||||
|
|
||||||
|
// The cases mentioned in these static_asserts are expected to be handled in
|
||||||
|
// the partial template specializations of Archetype that follow this
|
||||||
|
// definition.
|
||||||
|
static_assert(PropertiesOfT<Prof>::destructible_support !=
|
||||||
|
destructible::maybe,
|
||||||
|
"");
|
||||||
|
static_assert(PropertiesOfT<Prof>::move_constructible_support !=
|
||||||
|
move_constructible::maybe ||
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support ==
|
||||||
|
copy_constructible::maybe,
|
||||||
|
"");
|
||||||
|
static_assert(PropertiesOfT<Prof>::move_assignable_support !=
|
||||||
|
move_assignable::maybe ||
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support ==
|
||||||
|
copy_assignable::maybe,
|
||||||
|
"");
|
||||||
|
|
||||||
|
public:
|
||||||
|
Archetype() = default;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteConstructor<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype(T&&) = delete;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteAssign<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype& operator=(T&&) = delete;
|
||||||
|
|
||||||
|
using ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>::archetype_state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Prof>
|
||||||
|
class Archetype<Prof, typename std::enable_if<
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support !=
|
||||||
|
move_constructible::maybe &&
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support ==
|
||||||
|
move_assignable::maybe &&
|
||||||
|
PropertiesOfT<Prof>::destructible_support !=
|
||||||
|
destructible::maybe>::type>
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support> {
|
||||||
|
public:
|
||||||
|
Archetype() = default;
|
||||||
|
Archetype(Archetype&&) = default;
|
||||||
|
Archetype(const Archetype&) = default;
|
||||||
|
Archetype& operator=(Archetype&&) = delete;
|
||||||
|
Archetype& operator=(const Archetype&) = default;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteConstructor<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype(T&&) = delete;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteAssign<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype& operator=(T&&) = delete;
|
||||||
|
|
||||||
|
using ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>::archetype_state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Prof>
|
||||||
|
class Archetype<Prof, typename std::enable_if<
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support ==
|
||||||
|
move_constructible::maybe &&
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support ==
|
||||||
|
move_assignable::maybe &&
|
||||||
|
PropertiesOfT<Prof>::destructible_support !=
|
||||||
|
destructible::maybe>::type>
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support> {
|
||||||
|
public:
|
||||||
|
Archetype() = default;
|
||||||
|
Archetype(Archetype&&) = delete;
|
||||||
|
Archetype(const Archetype&) = default;
|
||||||
|
Archetype& operator=(Archetype&&) = delete;
|
||||||
|
Archetype& operator=(const Archetype&) = default;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteConstructor<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype(T&&) = delete;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteAssign<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype& operator=(T&&) = delete;
|
||||||
|
|
||||||
|
using ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>::archetype_state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Prof>
|
||||||
|
class Archetype<Prof, typename std::enable_if<
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support ==
|
||||||
|
move_constructible::maybe &&
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support !=
|
||||||
|
move_assignable::maybe &&
|
||||||
|
PropertiesOfT<Prof>::destructible_support !=
|
||||||
|
destructible::maybe>::type>
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support> {
|
||||||
|
public:
|
||||||
|
Archetype() = default;
|
||||||
|
Archetype(Archetype&&) = delete;
|
||||||
|
Archetype(const Archetype&) = default;
|
||||||
|
Archetype& operator=(Archetype&&) = default;
|
||||||
|
Archetype& operator=(const Archetype&) = default;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteConstructor<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype(T&&) = delete;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteAssign<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype& operator=(T&&) = delete;
|
||||||
|
|
||||||
|
using ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>::archetype_state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Prof>
|
||||||
|
class Archetype<Prof, typename std::enable_if<
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support !=
|
||||||
|
move_constructible::maybe &&
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support ==
|
||||||
|
move_assignable::maybe &&
|
||||||
|
PropertiesOfT<Prof>::destructible_support ==
|
||||||
|
destructible::maybe>::type>
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support> {
|
||||||
|
public:
|
||||||
|
Archetype() = default;
|
||||||
|
Archetype(Archetype&&) = default;
|
||||||
|
Archetype(const Archetype&) = default;
|
||||||
|
Archetype& operator=(Archetype&&) = delete;
|
||||||
|
Archetype& operator=(const Archetype&) = default;
|
||||||
|
~Archetype() = delete;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteConstructor<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype(T&&) = delete;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteAssign<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype& operator=(T&&) = delete;
|
||||||
|
|
||||||
|
using ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>::archetype_state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Prof>
|
||||||
|
class Archetype<Prof, typename std::enable_if<
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support ==
|
||||||
|
move_constructible::maybe &&
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support ==
|
||||||
|
move_assignable::maybe &&
|
||||||
|
PropertiesOfT<Prof>::destructible_support ==
|
||||||
|
destructible::maybe>::type>
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support> {
|
||||||
|
public:
|
||||||
|
Archetype() = default;
|
||||||
|
Archetype(Archetype&&) = delete;
|
||||||
|
Archetype(const Archetype&) = default;
|
||||||
|
Archetype& operator=(Archetype&&) = delete;
|
||||||
|
Archetype& operator=(const Archetype&) = default;
|
||||||
|
~Archetype() = delete;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteConstructor<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype(T&&) = delete;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteAssign<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype& operator=(T&&) = delete;
|
||||||
|
|
||||||
|
using ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>::archetype_state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Prof>
|
||||||
|
class Archetype<Prof, typename std::enable_if<
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support ==
|
||||||
|
move_constructible::maybe &&
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support !=
|
||||||
|
move_assignable::maybe &&
|
||||||
|
PropertiesOfT<Prof>::destructible_support ==
|
||||||
|
destructible::maybe>::type>
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support> {
|
||||||
|
public:
|
||||||
|
Archetype() = default;
|
||||||
|
Archetype(Archetype&&) = delete;
|
||||||
|
Archetype(const Archetype&) = default;
|
||||||
|
Archetype& operator=(Archetype&&) = default;
|
||||||
|
Archetype& operator=(const Archetype&) = default;
|
||||||
|
~Archetype() = delete;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteConstructor<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype(T&&) = delete;
|
||||||
|
|
||||||
|
// Disallow moves when requested, and disallow implicit conversions.
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
ShouldDeleteAssign<Prof, T>()>::type* = nullptr>
|
||||||
|
Archetype& operator=(T&&) = delete;
|
||||||
|
|
||||||
|
using ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>::archetype_state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept
|
||||||
|
: ArchetypeSpecialMembersBase<
|
||||||
|
PropertiesOfT<Prof>::default_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::copy_constructible_support,
|
||||||
|
PropertiesOfT<Prof>::move_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::copy_assignable_support,
|
||||||
|
PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(),
|
||||||
|
state) {}
|
||||||
|
|
||||||
|
friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Explicitly deleted swap for Archetype if the profile does not require swap.
|
||||||
|
// It is important to delete it rather than simply leave it out so that the
|
||||||
|
// "using std::swap;" idiom will result in this deleted overload being picked.
|
||||||
|
template <class Prof,
|
||||||
|
absl::enable_if_t<!PropertiesOfT<Prof>::is_swappable, int> = 0>
|
||||||
|
void swap(Archetype<Prof>&, Archetype<Prof>&) = delete; // NOLINT
|
||||||
|
|
||||||
|
// A conditionally-noexcept swap implementation for Archetype when the profile
|
||||||
|
// supports swap.
|
||||||
|
template <class Prof,
|
||||||
|
absl::enable_if_t<PropertiesOfT<Prof>::is_swappable, int> = 0>
|
||||||
|
void swap(Archetype<Prof>& lhs, Archetype<Prof>& rhs) // NOLINT
|
||||||
|
noexcept(PropertiesOfT<Prof>::swappable_support != swappable::yes) {
|
||||||
|
std::swap(lhs.archetype_state, rhs.archetype_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A convertible-to-bool type that is used as the return type of comparison
|
||||||
|
// operators since the standard doesn't always require exactly bool.
|
||||||
|
struct NothrowBool {
|
||||||
|
explicit NothrowBool() = delete;
|
||||||
|
~NothrowBool() = default;
|
||||||
|
|
||||||
|
// TODO(calabrese) Delete the copy constructor in C++17 mode since guaranteed
|
||||||
|
// elision makes it not required when returning from a function.
|
||||||
|
// NothrowBool(NothrowBool const&) = delete;
|
||||||
|
|
||||||
|
NothrowBool& operator=(NothrowBool const&) = delete;
|
||||||
|
|
||||||
|
explicit operator bool() const noexcept { return value; }
|
||||||
|
|
||||||
|
static NothrowBool make(bool const value) noexcept {
|
||||||
|
return NothrowBool(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit NothrowBool(bool const value) noexcept : value(value) {}
|
||||||
|
|
||||||
|
bool value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A convertible-to-bool type that is used as the return type of comparison
|
||||||
|
// operators since the standard doesn't always require exactly bool.
|
||||||
|
// Note: ExceptionalBool has a conversion operator that is not noexcept, so
|
||||||
|
// that even when a comparison operator is noexcept, that operation may still
|
||||||
|
// potentially throw when converted to bool.
|
||||||
|
struct ExceptionalBool {
|
||||||
|
explicit ExceptionalBool() = delete;
|
||||||
|
~ExceptionalBool() = default;
|
||||||
|
|
||||||
|
// TODO(calabrese) Delete the copy constructor in C++17 mode since guaranteed
|
||||||
|
// elision makes it not required when returning from a function.
|
||||||
|
// ExceptionalBool(ExceptionalBool const&) = delete;
|
||||||
|
|
||||||
|
ExceptionalBool& operator=(ExceptionalBool const&) = delete;
|
||||||
|
|
||||||
|
explicit operator bool() const { return value; } // NOLINT
|
||||||
|
|
||||||
|
static ExceptionalBool make(bool const value) noexcept {
|
||||||
|
return ExceptionalBool(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit ExceptionalBool(bool const value) noexcept : value(value) {}
|
||||||
|
|
||||||
|
bool value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The following macro is only used as a helper in this file to stamp out
|
||||||
|
// comparison operator definitions. It is undefined after usage.
|
||||||
|
//
|
||||||
|
// NOTE: Non-nothrow operators throw via their result's conversion to bool even
|
||||||
|
// though the operation itself is noexcept.
|
||||||
|
#define ABSL_TYPES_INTERNAL_OP(enum_name, op) \
|
||||||
|
template <class Prof> \
|
||||||
|
absl::enable_if_t<!PropertiesOfT<Prof>::is_##enum_name, bool> operator op( \
|
||||||
|
const Archetype<Prof>&, const Archetype<Prof>&) = delete; \
|
||||||
|
\
|
||||||
|
template <class Prof> \
|
||||||
|
typename absl::enable_if_t< \
|
||||||
|
PropertiesOfT<Prof>::is_##enum_name, \
|
||||||
|
std::conditional<PropertiesOfT<Prof>::enum_name##_support == \
|
||||||
|
enum_name::nothrow, \
|
||||||
|
NothrowBool, ExceptionalBool>>::type \
|
||||||
|
operator op(const Archetype<Prof>& lhs, \
|
||||||
|
const Archetype<Prof>& rhs) noexcept { \
|
||||||
|
return absl::conditional_t< \
|
||||||
|
PropertiesOfT<Prof>::enum_name##_support == enum_name::nothrow, \
|
||||||
|
NothrowBool, ExceptionalBool>::make(lhs.archetype_state op \
|
||||||
|
rhs.archetype_state); \
|
||||||
|
}
|
||||||
|
|
||||||
|
ABSL_TYPES_INTERNAL_OP(equality_comparable, ==);
|
||||||
|
ABSL_TYPES_INTERNAL_OP(inequality_comparable, !=);
|
||||||
|
ABSL_TYPES_INTERNAL_OP(less_than_comparable, <);
|
||||||
|
ABSL_TYPES_INTERNAL_OP(less_equal_comparable, <=);
|
||||||
|
ABSL_TYPES_INTERNAL_OP(greater_equal_comparable, >=);
|
||||||
|
ABSL_TYPES_INTERNAL_OP(greater_than_comparable, >);
|
||||||
|
|
||||||
|
#undef ABSL_TYPES_INTERNAL_OP
|
||||||
|
|
||||||
|
// Base class for std::hash specializations when an Archetype doesn't support
|
||||||
|
// hashing.
|
||||||
|
struct PoisonedHash {
|
||||||
|
PoisonedHash() = delete;
|
||||||
|
PoisonedHash(const PoisonedHash&) = delete;
|
||||||
|
PoisonedHash& operator=(const PoisonedHash&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Base class for std::hash specializations when an Archetype supports hashing.
|
||||||
|
template <class Prof>
|
||||||
|
struct EnabledHash {
|
||||||
|
using argument_type = Archetype<Prof>;
|
||||||
|
using result_type = std::size_t;
|
||||||
|
result_type operator()(const argument_type& arg) const {
|
||||||
|
return std::hash<ArchetypeState>()(arg.archetype_state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace types_internal
|
||||||
|
} // namespace absl
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
template <class Prof> // NOLINT
|
||||||
|
struct hash<::absl::types_internal::Archetype<Prof>>
|
||||||
|
: conditional<::absl::types_internal::PropertiesOfT<Prof>::is_hashable,
|
||||||
|
::absl::types_internal::EnabledHash<Prof>,
|
||||||
|
::absl::types_internal::PoisonedHash>::type {};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_ARCHETYPE_H_
|
374
absl/types/internal/conformance_profile.h
Normal file
374
absl/types/internal/conformance_profile.h
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// conformance_profiles.h
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file contains templates for representing "Regularity Profiles" and
|
||||||
|
// concisely-named versions of commonly used Regularity Profiles.
|
||||||
|
//
|
||||||
|
// A Regularity Profile is a compile-time description of the types of operations
|
||||||
|
// that a given type supports, along with properties of those operations when
|
||||||
|
// they do exist. For instance, a Regularity Profile may describe a type that
|
||||||
|
// has a move-constructor that is noexcept and a copy constructor that is not
|
||||||
|
// noexcept. This description can then be examined and passed around to other
|
||||||
|
// templates for the purposes of asserting expectations on user-defined types
|
||||||
|
// via a series trait checks, or for determining what kinds of run-time tests
|
||||||
|
// are able to be performed.
|
||||||
|
//
|
||||||
|
// Regularity Profiles are also used when creating "archetypes," which are
|
||||||
|
// minimum-conforming types that meet all of the requirements of a given
|
||||||
|
// Regularity Profile. For more information regarding archetypes, see
|
||||||
|
// "conformance_archetypes.h".
|
||||||
|
|
||||||
|
#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_PROFILE_H_
|
||||||
|
#define ABSL_TYPES_INTERNAL_CONFORMANCE_PROFILE_H_
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "absl/meta/type_traits.h"
|
||||||
|
|
||||||
|
// TODO(calabrese) Add support for extending profiles.
|
||||||
|
|
||||||
|
namespace absl {
|
||||||
|
namespace types_internal {
|
||||||
|
|
||||||
|
template <class T, class /*Enabler*/ = void>
|
||||||
|
struct PropertiesOfImpl {};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct PropertiesOfImpl<T, absl::void_t<typename T::properties>> {
|
||||||
|
using type = typename T::properties;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct PropertiesOfImpl<T, absl::void_t<typename T::profile_alias_of>> {
|
||||||
|
using type = typename PropertiesOfImpl<typename T::profile_alias_of>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct PropertiesOf : PropertiesOfImpl<T> {};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
using PropertiesOfT = typename PropertiesOf<T>::type;
|
||||||
|
|
||||||
|
// NOTE: These enums use this naming convention to be consistent with the
|
||||||
|
// standard trait names, which is useful since it allows us to match up each
|
||||||
|
// enum name with a corresponding trait name in macro definitions.
|
||||||
|
|
||||||
|
enum class function_kind { maybe, yes, nothrow, trivial };
|
||||||
|
|
||||||
|
#define ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM(name) \
|
||||||
|
enum class name { maybe, yes, nothrow, trivial }
|
||||||
|
|
||||||
|
ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM(default_constructible);
|
||||||
|
ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM(move_constructible);
|
||||||
|
ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM(copy_constructible);
|
||||||
|
ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM(move_assignable);
|
||||||
|
ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM(copy_assignable);
|
||||||
|
ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM(destructible);
|
||||||
|
|
||||||
|
#undef ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM
|
||||||
|
|
||||||
|
#define ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM(name) \
|
||||||
|
enum class name { maybe, yes, nothrow }
|
||||||
|
|
||||||
|
ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM(equality_comparable);
|
||||||
|
ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM(inequality_comparable);
|
||||||
|
ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM(less_than_comparable);
|
||||||
|
ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM(less_equal_comparable);
|
||||||
|
ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM(greater_equal_comparable);
|
||||||
|
ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM(greater_than_comparable);
|
||||||
|
|
||||||
|
ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM(swappable);
|
||||||
|
|
||||||
|
#undef ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM
|
||||||
|
|
||||||
|
enum class hashable { maybe, yes };
|
||||||
|
|
||||||
|
constexpr const char* PropertyName(hashable v) {
|
||||||
|
return "support for std::hash";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
default_constructible DefaultConstructibleValue =
|
||||||
|
default_constructible::maybe,
|
||||||
|
move_constructible MoveConstructibleValue = move_constructible::maybe,
|
||||||
|
copy_constructible CopyConstructibleValue = copy_constructible::maybe,
|
||||||
|
move_assignable MoveAssignableValue = move_assignable::maybe,
|
||||||
|
copy_assignable CopyAssignableValue = copy_assignable::maybe,
|
||||||
|
destructible DestructibleValue = destructible::maybe,
|
||||||
|
equality_comparable EqualityComparableValue = equality_comparable::maybe,
|
||||||
|
inequality_comparable InequalityComparableValue =
|
||||||
|
inequality_comparable::maybe,
|
||||||
|
less_than_comparable LessThanComparableValue = less_than_comparable::maybe,
|
||||||
|
less_equal_comparable LessEqualComparableValue =
|
||||||
|
less_equal_comparable::maybe,
|
||||||
|
greater_equal_comparable GreaterEqualComparableValue =
|
||||||
|
greater_equal_comparable::maybe,
|
||||||
|
greater_than_comparable GreaterThanComparableValue =
|
||||||
|
greater_than_comparable::maybe,
|
||||||
|
swappable SwappableValue = swappable::maybe,
|
||||||
|
hashable HashableValue = hashable::maybe>
|
||||||
|
struct ConformanceProfile {
|
||||||
|
using properties = ConformanceProfile;
|
||||||
|
|
||||||
|
static constexpr default_constructible
|
||||||
|
default_constructible_support = // NOLINT
|
||||||
|
DefaultConstructibleValue;
|
||||||
|
|
||||||
|
static constexpr move_constructible move_constructible_support = // NOLINT
|
||||||
|
MoveConstructibleValue;
|
||||||
|
|
||||||
|
static constexpr copy_constructible copy_constructible_support = // NOLINT
|
||||||
|
CopyConstructibleValue;
|
||||||
|
|
||||||
|
static constexpr move_assignable move_assignable_support = // NOLINT
|
||||||
|
MoveAssignableValue;
|
||||||
|
|
||||||
|
static constexpr copy_assignable copy_assignable_support = // NOLINT
|
||||||
|
CopyAssignableValue;
|
||||||
|
|
||||||
|
static constexpr destructible destructible_support = // NOLINT
|
||||||
|
DestructibleValue;
|
||||||
|
|
||||||
|
static constexpr equality_comparable equality_comparable_support = // NOLINT
|
||||||
|
EqualityComparableValue;
|
||||||
|
|
||||||
|
static constexpr inequality_comparable
|
||||||
|
inequality_comparable_support = // NOLINT
|
||||||
|
InequalityComparableValue;
|
||||||
|
|
||||||
|
static constexpr less_than_comparable
|
||||||
|
less_than_comparable_support = // NOLINT
|
||||||
|
LessThanComparableValue;
|
||||||
|
|
||||||
|
static constexpr less_equal_comparable
|
||||||
|
less_equal_comparable_support = // NOLINT
|
||||||
|
LessEqualComparableValue;
|
||||||
|
|
||||||
|
static constexpr greater_equal_comparable
|
||||||
|
greater_equal_comparable_support = // NOLINT
|
||||||
|
GreaterEqualComparableValue;
|
||||||
|
|
||||||
|
static constexpr greater_than_comparable
|
||||||
|
greater_than_comparable_support = // NOLINT
|
||||||
|
GreaterThanComparableValue;
|
||||||
|
|
||||||
|
static constexpr swappable swappable_support = SwappableValue; // NOLINT
|
||||||
|
|
||||||
|
static constexpr hashable hashable_support = HashableValue; // NOLINT
|
||||||
|
|
||||||
|
static constexpr bool is_default_constructible = // NOLINT
|
||||||
|
DefaultConstructibleValue != default_constructible::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_move_constructible = // NOLINT
|
||||||
|
MoveConstructibleValue != move_constructible::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_copy_constructible = // NOLINT
|
||||||
|
CopyConstructibleValue != copy_constructible::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_move_assignable = // NOLINT
|
||||||
|
MoveAssignableValue != move_assignable::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_copy_assignable = // NOLINT
|
||||||
|
CopyAssignableValue != copy_assignable::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_destructible = // NOLINT
|
||||||
|
DestructibleValue != destructible::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_equality_comparable = // NOLINT
|
||||||
|
EqualityComparableValue != equality_comparable::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_inequality_comparable = // NOLINT
|
||||||
|
InequalityComparableValue != inequality_comparable::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_less_than_comparable = // NOLINT
|
||||||
|
LessThanComparableValue != less_than_comparable::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_less_equal_comparable = // NOLINT
|
||||||
|
LessEqualComparableValue != less_equal_comparable::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_greater_equal_comparable = // NOLINT
|
||||||
|
GreaterEqualComparableValue != greater_equal_comparable::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_greater_than_comparable = // NOLINT
|
||||||
|
GreaterThanComparableValue != greater_than_comparable::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_swappable = // NOLINT
|
||||||
|
SwappableValue != swappable::maybe;
|
||||||
|
|
||||||
|
static constexpr bool is_hashable = // NOLINT
|
||||||
|
HashableValue != hashable::maybe;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL(type, name) \
|
||||||
|
template <default_constructible DefaultConstructibleValue, \
|
||||||
|
move_constructible MoveConstructibleValue, \
|
||||||
|
copy_constructible CopyConstructibleValue, \
|
||||||
|
move_assignable MoveAssignableValue, \
|
||||||
|
copy_assignable CopyAssignableValue, \
|
||||||
|
destructible DestructibleValue, \
|
||||||
|
equality_comparable EqualityComparableValue, \
|
||||||
|
inequality_comparable InequalityComparableValue, \
|
||||||
|
less_than_comparable LessThanComparableValue, \
|
||||||
|
less_equal_comparable LessEqualComparableValue, \
|
||||||
|
greater_equal_comparable GreaterEqualComparableValue, \
|
||||||
|
greater_than_comparable GreaterThanComparableValue, \
|
||||||
|
swappable SwappableValue, hashable HashableValue> \
|
||||||
|
constexpr type ConformanceProfile< \
|
||||||
|
DefaultConstructibleValue, MoveConstructibleValue, \
|
||||||
|
CopyConstructibleValue, MoveAssignableValue, CopyAssignableValue, \
|
||||||
|
DestructibleValue, EqualityComparableValue, InequalityComparableValue, \
|
||||||
|
LessThanComparableValue, LessEqualComparableValue, \
|
||||||
|
GreaterEqualComparableValue, GreaterThanComparableValue, SwappableValue, \
|
||||||
|
HashableValue>::name
|
||||||
|
|
||||||
|
#define ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(type) \
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL(type, \
|
||||||
|
type##_support); \
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL(bool, is_##type)
|
||||||
|
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(default_constructible);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(move_constructible);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(copy_constructible);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(move_assignable);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(copy_assignable);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(destructible);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(equality_comparable);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(inequality_comparable);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(less_than_comparable);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(less_equal_comparable);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(greater_equal_comparable);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(greater_than_comparable);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(swappable);
|
||||||
|
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(hashable);
|
||||||
|
|
||||||
|
#undef ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF
|
||||||
|
#undef ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL
|
||||||
|
|
||||||
|
// Converts an enum to its underlying integral value.
|
||||||
|
template <class Enum>
|
||||||
|
constexpr absl::underlying_type_t<Enum> UnderlyingValue(Enum value) {
|
||||||
|
return static_cast<absl::underlying_type_t<Enum>>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the enum with the greatest underlying value.
|
||||||
|
// Note: std::max is not constexpr in C++11, which is why this is necessary.
|
||||||
|
template <class H>
|
||||||
|
constexpr H MaxEnum(H head) {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class H, class N, class... T>
|
||||||
|
constexpr H MaxEnum(H head, N next, T... tail) {
|
||||||
|
return (UnderlyingValue)(next) < (UnderlyingValue)(head)
|
||||||
|
? (MaxEnum)(head, tail...)
|
||||||
|
: (MaxEnum)(next, tail...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Profs>
|
||||||
|
struct CombineProfilesImpl {
|
||||||
|
static constexpr default_constructible
|
||||||
|
default_constructible_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::default_constructible_support...);
|
||||||
|
|
||||||
|
static constexpr move_constructible move_constructible_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::move_constructible_support...);
|
||||||
|
|
||||||
|
static constexpr copy_constructible copy_constructible_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::copy_constructible_support...);
|
||||||
|
|
||||||
|
static constexpr move_assignable move_assignable_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::move_assignable_support...);
|
||||||
|
|
||||||
|
static constexpr copy_assignable copy_assignable_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::copy_assignable_support...);
|
||||||
|
|
||||||
|
static constexpr destructible destructible_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::destructible_support...);
|
||||||
|
|
||||||
|
static constexpr equality_comparable equality_comparable_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::equality_comparable_support...);
|
||||||
|
|
||||||
|
static constexpr inequality_comparable
|
||||||
|
inequality_comparable_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::inequality_comparable_support...);
|
||||||
|
|
||||||
|
static constexpr less_than_comparable
|
||||||
|
less_than_comparable_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::less_than_comparable_support...);
|
||||||
|
|
||||||
|
static constexpr less_equal_comparable
|
||||||
|
less_equal_comparable_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::less_equal_comparable_support...);
|
||||||
|
|
||||||
|
static constexpr greater_equal_comparable
|
||||||
|
greater_equal_comparable_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::greater_equal_comparable_support...);
|
||||||
|
|
||||||
|
static constexpr greater_than_comparable
|
||||||
|
greater_than_comparable_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::greater_than_comparable_support...);
|
||||||
|
|
||||||
|
static constexpr swappable swappable_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::swappable_support...);
|
||||||
|
|
||||||
|
static constexpr hashable hashable_support = // NOLINT
|
||||||
|
(MaxEnum)(PropertiesOfT<Profs>::hashable_support...);
|
||||||
|
|
||||||
|
using properties = ConformanceProfile<
|
||||||
|
default_constructible_support, move_constructible_support,
|
||||||
|
copy_constructible_support, move_assignable_support,
|
||||||
|
copy_assignable_support, destructible_support,
|
||||||
|
equality_comparable_support, inequality_comparable_support,
|
||||||
|
less_than_comparable_support, less_equal_comparable_support,
|
||||||
|
greater_equal_comparable_support, greater_than_comparable_support,
|
||||||
|
swappable_support, hashable_support>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOTE: We use this as opposed to a direct alias of CombineProfilesImpl so that
|
||||||
|
// when named aliases of CombineProfiles are created (such as in
|
||||||
|
// conformance_aliases.h), we only pay for the combination algorithm on the
|
||||||
|
// profiles that are actually used.
|
||||||
|
template <class... Profs>
|
||||||
|
struct CombineProfiles {
|
||||||
|
using profile_alias_of = CombineProfilesImpl<Profs...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct CombineProfiles<> {
|
||||||
|
using properties = ConformanceProfile<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Profile, class Tag>
|
||||||
|
struct StrongProfileTypedef {
|
||||||
|
using properties = PropertiesOfT<Profile>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class /*Enabler*/ = void>
|
||||||
|
struct IsProfileImpl : std::false_type {};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct IsProfileImpl<T, absl::void_t<PropertiesOfT<T>>> : std::true_type {};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct IsProfile : IsProfileImpl<T>::type {};
|
||||||
|
|
||||||
|
} // namespace types_internal
|
||||||
|
} // namespace absl
|
||||||
|
|
||||||
|
#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_PROFILE_H_
|
1186
absl/types/internal/conformance_testing_test.cc
Normal file
1186
absl/types/internal/conformance_testing_test.cc
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue