aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--WORKSPACE8
-rw-r--r--absl/BUILD.bazel19
-rw-r--r--absl/base/BUILD.bazel4
-rw-r--r--absl/base/config.h35
-rw-r--r--absl/base/internal/throw_delegate.cc55
-rw-r--r--absl/debugging/BUILD.bazel4
-rw-r--r--absl/flags/internal/parse.h2
-rw-r--r--absl/flags/parse.cc15
-rw-r--r--absl/flags/parse_test.cc67
-rw-r--r--absl/functional/internal/any_invocable.h15
-rw-r--r--absl/meta/type_traits.h386
-rw-r--r--absl/meta/type_traits_test.cc655
-rw-r--r--absl/numeric/int128.cc12
-rw-r--r--absl/synchronization/internal/futex.h70
-rw-r--r--absl/synchronization/internal/waiter.cc106
-rw-r--r--absl/synchronization/internal/waiter.h3
-rw-r--r--absl/synchronization/mutex.cc45
-rw-r--r--ci/cmake_common.sh2
18 files changed, 151 insertions, 1352 deletions
diff --git a/WORKSPACE b/WORKSPACE
index 1a050544..ce8e8596 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -20,11 +20,11 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# GoogleTest/GoogleMock framework. Used by most unit-tests.
http_archive(
- name = "com_google_googletest", # 2023-01-05T19:15:29Z
- sha256 = "1c805208d019aabb8be3cddbc6098be8815ee5cf0a7baf526102528fd624c422",
- strip_prefix = "googletest-934542165899c786cb5d8a710529c37184730183",
+ name = "com_google_googletest", # 2023-02-28T13:15:29Z
+ sha256 = "82ad62a4e26c199de52a707778334e80f6b195dd298d48d520d8507d2bcb88c4",
+ strip_prefix = "googletest-2d4f208765af7fa376b878860a7677ecc0bc390a",
# Keep this URL in sync with ABSL_GOOGLETEST_COMMIT in ci/cmake_common.sh.
- urls = ["https://github.com/google/googletest/archive/934542165899c786cb5d8a710529c37184730183.zip"],
+ urls = ["https://github.com/google/googletest/archive/2d4f208765af7fa376b878860a7677ecc0bc390a.zip"],
)
# RE2 (the regular expression library used by GoogleTest)
diff --git a/absl/BUILD.bazel b/absl/BUILD.bazel
index 69bdbf14..b2300ba9 100644
--- a/absl/BUILD.bazel
+++ b/absl/BUILD.bazel
@@ -36,7 +36,7 @@ config_setting(
)
config_setting(
- name = "mingw_compiler",
+ name = "mingw_unspecified_compiler",
flag_values = {
"@bazel_tools//tools/cpp:compiler": "mingw",
},
@@ -44,6 +44,14 @@ config_setting(
)
config_setting(
+ name = "mingw-gcc_compiler",
+ flag_values = {
+ "@bazel_tools//tools/cpp:compiler": "mingw-gcc",
+ },
+ visibility = [":__subpackages__"],
+)
+
+config_setting(
name = "msvc_compiler",
flag_values = {
"@bazel_tools//tools/cpp:compiler": "msvc-cl",
@@ -131,3 +139,12 @@ config_setting(
},
visibility = [":__subpackages__"],
)
+
+selects.config_setting_group(
+ name = "mingw_compiler",
+ match_any = [
+ ":mingw_unspecified_compiler",
+ ":mingw-gcc_compiler",
+ ],
+ visibility = [":__subpackages__"],
+)
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index dd29daf6..28cbf28f 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -246,6 +246,10 @@ cc_library(
"//absl:clang-cl_compiler": [
"-DEFAULTLIB:advapi32.lib",
],
+ "//absl:mingw_compiler": [
+ "-DEFAULTLIB:advapi32.lib",
+ "-ladvapi32",
+ ],
"//absl:wasm": [],
"//conditions:default": ["-pthread"],
}) + ABSL_DEFAULT_LINKOPTS,
diff --git a/absl/base/config.h b/absl/base/config.h
index e8605ab3..2929aa15 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -237,15 +237,8 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
// ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
//
// Checks whether `std::is_trivially_destructible<T>` is supported.
-//
-// Notes: All supported compilers using libc++ support this feature, as does
-// gcc >= 4.8.1 using libstdc++, and Visual Studio.
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
#error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set
-#elif defined(_LIBCPP_VERSION) || defined(_MSC_VER) || \
- (defined(__clang__) && __clang_major__ >= 15) || \
- (!defined(__clang__) && defined(__GLIBCXX__) && \
- ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(4, 8))
#define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1
#endif
@@ -253,36 +246,26 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
//
// Checks whether `std::is_trivially_default_constructible<T>` and
// `std::is_trivially_copy_constructible<T>` are supported.
+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
+#error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set
+#else
+#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1
+#endif
// ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
//
// Checks whether `std::is_trivially_copy_assignable<T>` is supported.
-
-// Notes: Clang with libc++ supports these features, as does gcc >= 7.4 with
-// libstdc++, or gcc >= 8.2 with libc++, and Visual Studio (but not NVCC).
-#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE)
-#error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set
-#elif defined(ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE)
-#error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set
-#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \
- (defined(__clang__) && __clang_major__ >= 15) || \
- (!defined(__clang__) && \
- ((ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(7, 4) && defined(__GLIBCXX__)) || \
- (ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(8, 2) && \
- defined(_LIBCPP_VERSION)))) || \
- (defined(_MSC_VER) && !defined(__NVCC__) && !defined(__clang__))
-#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1
+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
+#error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot be directly set
+#else
#define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1
#endif
// ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE
//
// Checks whether `std::is_trivially_copyable<T>` is supported.
-//
-// Notes: Clang 15+ with libc++ supports these features, GCC hasn't been tested.
-#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE)
+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE
#error ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE cannot be directly set
-#elif defined(__clang__) && (__clang_major__ >= 15)
#define ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE 1
#endif
diff --git a/absl/base/internal/throw_delegate.cc b/absl/base/internal/throw_delegate.cc
index c260ff1e..337e870c 100644
--- a/absl/base/internal/throw_delegate.cc
+++ b/absl/base/internal/throw_delegate.cc
@@ -26,22 +26,13 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
-// NOTE: The various STL exception throwing functions are placed within the
-// #ifdef blocks so the symbols aren't exposed on platforms that don't support
-// them, such as the Android NDK. For example, ANGLE fails to link when building
-// within AOSP without them, since the STL functions don't exist.
-namespace {
-#ifdef ABSL_HAVE_EXCEPTIONS
-template <typename T>
-[[noreturn]] void Throw(const T& error) {
- throw error;
-}
-#endif
-} // namespace
+// NOTE: The exception types, like `std::logic_error`, do not exist on all
+// platforms. (For example, the Android NDK does not have them.)
+// Therefore, their use must be guarded by `#ifdef` or equivalent.
void ThrowStdLogicError(const std::string& what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::logic_error(what_arg));
+ throw std::logic_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
std::abort();
@@ -49,7 +40,7 @@ void ThrowStdLogicError(const std::string& what_arg) {
}
void ThrowStdLogicError(const char* what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::logic_error(what_arg));
+ throw std::logic_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg);
std::abort();
@@ -57,7 +48,7 @@ void ThrowStdLogicError(const char* what_arg) {
}
void ThrowStdInvalidArgument(const std::string& what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::invalid_argument(what_arg));
+ throw std::invalid_argument(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
std::abort();
@@ -65,7 +56,7 @@ void ThrowStdInvalidArgument(const std::string& what_arg) {
}
void ThrowStdInvalidArgument(const char* what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::invalid_argument(what_arg));
+ throw std::invalid_argument(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg);
std::abort();
@@ -74,7 +65,7 @@ void ThrowStdInvalidArgument(const char* what_arg) {
void ThrowStdDomainError(const std::string& what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::domain_error(what_arg));
+ throw std::domain_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
std::abort();
@@ -82,7 +73,7 @@ void ThrowStdDomainError(const std::string& what_arg) {
}
void ThrowStdDomainError(const char* what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::domain_error(what_arg));
+ throw std::domain_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg);
std::abort();
@@ -91,7 +82,7 @@ void ThrowStdDomainError(const char* what_arg) {
void ThrowStdLengthError(const std::string& what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::length_error(what_arg));
+ throw std::length_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
std::abort();
@@ -99,7 +90,7 @@ void ThrowStdLengthError(const std::string& what_arg) {
}
void ThrowStdLengthError(const char* what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::length_error(what_arg));
+ throw std::length_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg);
std::abort();
@@ -108,7 +99,7 @@ void ThrowStdLengthError(const char* what_arg) {
void ThrowStdOutOfRange(const std::string& what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::out_of_range(what_arg));
+ throw std::out_of_range(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
std::abort();
@@ -116,7 +107,7 @@ void ThrowStdOutOfRange(const std::string& what_arg) {
}
void ThrowStdOutOfRange(const char* what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::out_of_range(what_arg));
+ throw std::out_of_range(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg);
std::abort();
@@ -125,7 +116,7 @@ void ThrowStdOutOfRange(const char* what_arg) {
void ThrowStdRuntimeError(const std::string& what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::runtime_error(what_arg));
+ throw std::runtime_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
std::abort();
@@ -133,7 +124,7 @@ void ThrowStdRuntimeError(const std::string& what_arg) {
}
void ThrowStdRuntimeError(const char* what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::runtime_error(what_arg));
+ throw std::runtime_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg);
std::abort();
@@ -142,7 +133,7 @@ void ThrowStdRuntimeError(const char* what_arg) {
void ThrowStdRangeError(const std::string& what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::range_error(what_arg));
+ throw std::range_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
std::abort();
@@ -150,7 +141,7 @@ void ThrowStdRangeError(const std::string& what_arg) {
}
void ThrowStdRangeError(const char* what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::range_error(what_arg));
+ throw std::range_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg);
std::abort();
@@ -159,7 +150,7 @@ void ThrowStdRangeError(const char* what_arg) {
void ThrowStdOverflowError(const std::string& what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::overflow_error(what_arg));
+ throw std::overflow_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
std::abort();
@@ -167,7 +158,7 @@ void ThrowStdOverflowError(const std::string& what_arg) {
}
void ThrowStdOverflowError(const char* what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::overflow_error(what_arg));
+ throw std::overflow_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg);
std::abort();
@@ -176,7 +167,7 @@ void ThrowStdOverflowError(const char* what_arg) {
void ThrowStdUnderflowError(const std::string& what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::underflow_error(what_arg));
+ throw std::underflow_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str());
std::abort();
@@ -184,7 +175,7 @@ void ThrowStdUnderflowError(const std::string& what_arg) {
}
void ThrowStdUnderflowError(const char* what_arg) {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::underflow_error(what_arg));
+ throw std::underflow_error(what_arg);
#else
ABSL_RAW_LOG(FATAL, "%s", what_arg);
std::abort();
@@ -193,7 +184,7 @@ void ThrowStdUnderflowError(const char* what_arg) {
void ThrowStdBadFunctionCall() {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::bad_function_call());
+ throw std::bad_function_call();
#else
std::abort();
#endif
@@ -201,7 +192,7 @@ void ThrowStdBadFunctionCall() {
void ThrowStdBadAlloc() {
#ifdef ABSL_HAVE_EXCEPTIONS
- Throw(std::bad_alloc());
+ throw std::bad_alloc();
#else
std::abort();
#endif
diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel
index edbb3698..86063da2 100644
--- a/absl/debugging/BUILD.bazel
+++ b/absl/debugging/BUILD.bazel
@@ -83,6 +83,10 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS + select({
"//absl:msvc_compiler": ["-DEFAULTLIB:dbghelp.lib"],
"//absl:clang-cl_compiler": ["-DEFAULTLIB:dbghelp.lib"],
+ "//absl:mingw_compiler": [
+ "-DEFAULTLIB:dbghelp.lib",
+ "-ldbghelp",
+ ],
"//conditions:default": [],
}),
deps = [
diff --git a/absl/flags/internal/parse.h b/absl/flags/internal/parse.h
index 0a7012fc..145e591d 100644
--- a/absl/flags/internal/parse.h
+++ b/absl/flags/internal/parse.h
@@ -32,7 +32,6 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace flags_internal {
-enum class ArgvListAction { kRemoveParsedArgs, kKeepParsedArgs };
enum class UsageFlagsAction { kHandleUsage, kIgnoreUsage };
enum class OnUndefinedFlag {
kIgnoreUndefined,
@@ -41,7 +40,6 @@ enum class OnUndefinedFlag {
};
std::vector<char*> ParseCommandLineImpl(int argc, char* argv[],
- ArgvListAction arg_list_act,
UsageFlagsAction usage_flag_act,
OnUndefinedFlag on_undef_flag);
diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc
index 368248e3..768652d8 100644
--- a/absl/flags/parse.cc
+++ b/absl/flags/parse.cc
@@ -664,7 +664,6 @@ std::vector<std::string> GetMisspellingHints(const absl::string_view flag) {
// --------------------------------------------------------------------
std::vector<char*> ParseCommandLineImpl(int argc, char* argv[],
- ArgvListAction arg_list_act,
UsageFlagsAction usage_flag_act,
OnUndefinedFlag on_undef_flag) {
ABSL_INTERNAL_CHECK(argc > 0, "Missing argv[0]");
@@ -740,10 +739,6 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[],
continue;
}
- if (arg_from_argv && (arg_list_act == ArgvListAction::kKeepParsedArgs)) {
- output_args.push_back(argv[curr_list.FrontIndex()]);
- }
-
// 60. Split the current argument on '=' to figure out the argument
// name and value. If flag name is empty it means we've got "--". value
// can be empty either if there were no '=' in argument string at all or
@@ -784,18 +779,11 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[],
}
// 90. Deduce flag's value (from this or next argument)
- auto curr_index = curr_list.FrontIndex();
bool value_success = true;
std::tie(value_success, value) =
DeduceFlagValue(*flag, value, is_negative, is_empty_value, &curr_list);
success &= value_success;
- // If above call consumed an argument, it was a standalone value
- if (arg_from_argv && (arg_list_act == ArgvListAction::kKeepParsedArgs) &&
- (curr_index != curr_list.FrontIndex())) {
- output_args.push_back(argv[curr_list.FrontIndex()]);
- }
-
// 100. Set the located flag to a new new value, unless it is retired.
// Setting retired flag fails, but we ignoring it here while also reporting
// access to retired flag.
@@ -881,8 +869,7 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[],
std::vector<char*> ParseCommandLine(int argc, char* argv[]) {
return flags_internal::ParseCommandLineImpl(
- argc, argv, flags_internal::ArgvListAction::kRemoveParsedArgs,
- flags_internal::UsageFlagsAction::kHandleUsage,
+ argc, argv, flags_internal::UsageFlagsAction::kHandleUsage,
flags_internal::OnUndefinedFlag::kAbortIfUndefined);
}
diff --git a/absl/flags/parse_test.cc b/absl/flags/parse_test.cc
index 418b0e55..18a01377 100644
--- a/absl/flags/parse_test.cc
+++ b/absl/flags/parse_test.cc
@@ -854,41 +854,6 @@ TEST_F(ParseTest, TestReadingFlagsFromEnvMoxedWithRegularFlags) {
// --------------------------------------------------------------------
-TEST_F(ParseTest, TestKeepParsedArgs) {
- const char* in_args1[] = {
- "testbin", "arg1", "--bool_flag",
- "--int_flag=211", "arg2", "--double_flag=1.1",
- "--string_flag", "asd", "--",
- "arg3", "arg4",
- };
-
- auto out_args1 = InvokeParse(in_args1);
-
- EXPECT_THAT(
- out_args1,
- ElementsAreArray({absl::string_view("testbin"), absl::string_view("arg1"),
- absl::string_view("arg2"), absl::string_view("arg3"),
- absl::string_view("arg4")}));
-
- auto out_args2 = flags::ParseCommandLineImpl(
- 11, const_cast<char**>(in_args1), flags::ArgvListAction::kKeepParsedArgs,
- flags::UsageFlagsAction::kHandleUsage,
- flags::OnUndefinedFlag::kAbortIfUndefined);
-
- EXPECT_THAT(
- out_args2,
- ElementsAreArray({absl::string_view("testbin"),
- absl::string_view("--bool_flag"),
- absl::string_view("--int_flag=211"),
- absl::string_view("--double_flag=1.1"),
- absl::string_view("--string_flag"),
- absl::string_view("asd"), absl::string_view("--"),
- absl::string_view("arg1"), absl::string_view("arg2"),
- absl::string_view("arg3"), absl::string_view("arg4")}));
-}
-
-// --------------------------------------------------------------------
-
TEST_F(ParseTest, TestIgnoreUndefinedFlags) {
const char* in_args1[] = {
"testbin",
@@ -898,34 +863,13 @@ TEST_F(ParseTest, TestIgnoreUndefinedFlags) {
};
auto out_args1 = flags::ParseCommandLineImpl(
- 4, const_cast<char**>(in_args1), flags::ArgvListAction::kRemoveParsedArgs,
- flags::UsageFlagsAction::kHandleUsage,
+ 4, const_cast<char**>(in_args1), flags::UsageFlagsAction::kHandleUsage,
flags::OnUndefinedFlag::kIgnoreUndefined);
EXPECT_THAT(out_args1, ElementsAreArray({absl::string_view("testbin"),
absl::string_view("arg1")}));
EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 21);
-
- const char* in_args2[] = {
- "testbin",
- "arg1",
- "--undef_flag=aa",
- "--string_flag=AA",
- };
-
- auto out_args2 = flags::ParseCommandLineImpl(
- 4, const_cast<char**>(in_args2), flags::ArgvListAction::kKeepParsedArgs,
- flags::UsageFlagsAction::kHandleUsage,
- flags::OnUndefinedFlag::kIgnoreUndefined);
-
- EXPECT_THAT(
- out_args2,
- ElementsAreArray(
- {absl::string_view("testbin"), absl::string_view("--undef_flag=aa"),
- absl::string_view("--string_flag=AA"), absl::string_view("arg1")}));
-
- EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "AA");
}
// --------------------------------------------------------------------
@@ -945,8 +889,7 @@ TEST_F(ParseDeathTest, TestSimpleHelpFlagHandling) {
};
auto out_args2 = flags::ParseCommandLineImpl(
- 3, const_cast<char**>(in_args2), flags::ArgvListAction::kRemoveParsedArgs,
- flags::UsageFlagsAction::kIgnoreUsage,
+ 3, const_cast<char**>(in_args2), flags::UsageFlagsAction::kIgnoreUsage,
flags::OnUndefinedFlag::kAbortIfUndefined);
EXPECT_EQ(flags::GetFlagsHelpMode(), flags::HelpMode::kImportant);
@@ -962,8 +905,7 @@ TEST_F(ParseDeathTest, TestSubstringHelpFlagHandling) {
};
auto out_args1 = flags::ParseCommandLineImpl(
- 2, const_cast<char**>(in_args1), flags::ArgvListAction::kRemoveParsedArgs,
- flags::UsageFlagsAction::kIgnoreUsage,
+ 2, const_cast<char**>(in_args1), flags::UsageFlagsAction::kIgnoreUsage,
flags::OnUndefinedFlag::kAbortIfUndefined);
EXPECT_EQ(flags::GetFlagsHelpMode(), flags::HelpMode::kMatch);
@@ -972,8 +914,7 @@ TEST_F(ParseDeathTest, TestSubstringHelpFlagHandling) {
const char* in_args2[] = {"testbin", "--help", "some_positional_arg"};
auto out_args2 = flags::ParseCommandLineImpl(
- 3, const_cast<char**>(in_args2), flags::ArgvListAction::kRemoveParsedArgs,
- flags::UsageFlagsAction::kIgnoreUsage,
+ 3, const_cast<char**>(in_args2), flags::UsageFlagsAction::kIgnoreUsage,
flags::OnUndefinedFlag::kAbortIfUndefined);
EXPECT_EQ(flags::GetFlagsHelpMode(), flags::HelpMode::kImportant);
diff --git a/absl/functional/internal/any_invocable.h b/absl/functional/internal/any_invocable.h
index 6bfbda18..7845e17a 100644
--- a/absl/functional/internal/any_invocable.h
+++ b/absl/functional/internal/any_invocable.h
@@ -810,6 +810,14 @@ using CanAssignReferenceWrapper = TrueAlias<
: Core(absl::in_place_type<absl::decay_t<T> inv_quals>, \
std::forward<Args>(args)...) {} \
\
+ /*Raises a fatal error when the AnyInvocable is invoked after a move*/ \
+ static ReturnType InvokedAfterMove( \
+ TypeErasedState*, \
+ ForwardedParameterType<P>...) noexcept(noex) { \
+ ABSL_HARDENING_ASSERT(false && "AnyInvocable use-after-move"); \
+ std::terminate(); \
+ } \
+ \
InvokerType<noex, ReturnType, P...>* ExtractInvoker() cv { \
using QualifiedTestType = int cv ref; \
auto* invoker = this->invoker_; \
@@ -817,12 +825,7 @@ using CanAssignReferenceWrapper = TrueAlias<
std::is_rvalue_reference<QualifiedTestType>::value) { \
ABSL_HARDENING_ASSERT([this]() { \
/* We checked that this isn't const above, so const_cast is safe */ \
- const_cast<Impl*>(this)->invoker_ = \
- [](TypeErasedState*, \
- ForwardedParameterType<P>...) noexcept(noex) -> ReturnType { \
- ABSL_HARDENING_ASSERT(false && "AnyInvocable use-after-move"); \
- std::terminate(); \
- }; \
+ const_cast<Impl*>(this)->invoker_ = InvokedAfterMove; \
return this->HasValue(); \
}()); \
} \
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index b1656c39..fb12ba4a 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -41,12 +41,6 @@
#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
-
// Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is a C++17
// feature.
#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
@@ -58,57 +52,8 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
-// Defined and documented later on in this file.
-template <typename T>
-struct is_trivially_destructible;
-
-// Defined and documented later on in this file.
-template <typename T>
-struct is_trivially_move_assignable;
-
namespace type_traits_internal {
-// Silence MSVC warnings about the destructor being defined as deleted.
-#if defined(_MSC_VER) && !defined(__GNUC__)
-#pragma warning(push)
-#pragma warning(disable : 4624)
-#endif // defined(_MSC_VER) && !defined(__GNUC__)
-
-template <class T>
-union SingleMemberUnion {
- T t;
-};
-
-// Restore the state of the destructor warning that was silenced above.
-#if defined(_MSC_VER) && !defined(__GNUC__)
-#pragma warning(pop)
-#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>
-struct IsTriviallyMoveAssignableReference : std::false_type {};
-
-template <class T>
-struct IsTriviallyMoveAssignableReference<T&>
- : absl::is_trivially_move_assignable<T>::type {};
-
-template <class T>
-struct IsTriviallyMoveAssignableReference<T&&>
- : absl::is_trivially_move_assignable<T>::type {};
-
template <typename... Ts>
struct VoidTImpl {
using type = void;
@@ -157,39 +102,8 @@ template <class To, template <class...> class Op, class... Args>
struct is_detected_convertible
: is_detected_convertible_impl<void, To, Op, Args...>::type {};
-template <typename T>
-using IsCopyAssignableImpl =
- decltype(std::declval<T&>() = std::declval<const T&>());
-
-template <typename T>
-using IsMoveAssignableImpl = decltype(std::declval<T&>() = std::declval<T&&>());
-
} // namespace type_traits_internal
-// MSVC 19.20 has a regression that causes our workarounds to fail, but their
-// std forms now appear to be compliant.
-#if defined(_MSC_VER) && !defined(__clang__) && (_MSC_VER >= 1920)
-
-template <typename T>
-using is_copy_assignable = std::is_copy_assignable<T>;
-
-template <typename T>
-using is_move_assignable = std::is_move_assignable<T>;
-
-#else
-
-template <typename T>
-struct is_copy_assignable : type_traits_internal::is_detected<
- type_traits_internal::IsCopyAssignableImpl, T> {
-};
-
-template <typename T>
-struct is_move_assignable : type_traits_internal::is_detected<
- type_traits_internal::IsMoveAssignableImpl, T> {
-};
-
-#endif
-
// void_t()
//
// Ignores the type of any its arguments and returns `void`. In general, this
@@ -270,246 +184,29 @@ struct is_function
bool, !(std::is_reference<T>::value ||
std::is_const<typename std::add_const<T>::type>::value)> {};
+// is_copy_assignable()
+// is_move_assignable()
// is_trivially_destructible()
-//
-// Determines whether the passed type `T` is trivially destructible.
-//
-// This metafunction is designed to be a drop-in replacement for the C++11
-// `std::is_trivially_destructible()` metafunction for platforms that have
-// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
-// fully support C++11, we check whether this yields the same result as the std
-// implementation.
-//
-// NOTE: the extensions (__has_trivial_xxx) are implemented in gcc (version >=
-// 4.3) and clang. Since we are supporting libstdc++ > 4.7, they should always
-// be present. These extensions are documented at
-// https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html#Type-Traits.
-template <typename T>
-struct is_trivially_destructible
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
- : std::is_trivially_destructible<T> {
-#else
- : std::integral_constant<bool, __has_trivial_destructor(T) &&
- std::is_destructible<T>::value> {
-#endif
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
- private:
- static constexpr bool compliant = std::is_trivially_destructible<T>::value ==
- is_trivially_destructible::value;
- static_assert(compliant || std::is_trivially_destructible<T>::value,
- "Not compliant with std::is_trivially_destructible; "
- "Standard: false, Implementation: true");
- static_assert(compliant || !std::is_trivially_destructible<T>::value,
- "Not compliant with std::is_trivially_destructible; "
- "Standard: true, Implementation: false");
-#endif // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
-};
-
// is_trivially_default_constructible()
-//
-// Determines whether the passed type `T` is trivially default constructible.
-//
-// This metafunction is designed to be a drop-in replacement for the C++11
-// `std::is_trivially_default_constructible()` metafunction for platforms that
-// have incomplete C++11 support (such as libstdc++ 4.x). On any platforms that
-// do fully support C++11, we check whether this yields the same result as the
-// std implementation.
-//
-// NOTE: according to the C++ standard, Section: 20.15.4.3 [meta.unary.prop]
-// "The predicate condition for a template specialization is_constructible<T,
-// Args...> shall be satisfied if and only if the following variable
-// definition would be well-formed for some invented variable t:
-//
-// T t(declval<Args>()...);
-//
-// is_trivially_constructible<T, Args...> additionally requires that the
-// variable definition does not call any operation that is not trivial.
-// For the purposes of this check, the call to std::declval is considered
-// trivial."
-//
-// Notes from https://en.cppreference.com/w/cpp/types/is_constructible:
-// In many implementations, is_nothrow_constructible also checks if the
-// destructor throws because it is effectively noexcept(T(arg)). Same
-// applies to is_trivially_constructible, which, in these implementations, also
-// requires that the destructor is trivial.
-// 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.
-//
-// "T obj();" need to be well-formed and not call any nontrivial operation.
-// Nontrivially destructible types will cause the expression to be nontrivial.
-template <typename T>
-struct is_trivially_default_constructible
-#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE)
- : std::is_trivially_default_constructible<T> {
-#else
- : std::integral_constant<bool, __has_trivial_constructor(T) &&
- std::is_default_constructible<T>::value &&
- is_trivially_destructible<T>::value> {
-#endif
-#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
- !defined( \
- ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
- private:
- static constexpr bool compliant =
- std::is_trivially_default_constructible<T>::value ==
- is_trivially_default_constructible::value;
- static_assert(compliant || std::is_trivially_default_constructible<T>::value,
- "Not compliant with std::is_trivially_default_constructible; "
- "Standard: false, Implementation: true");
- static_assert(compliant || !std::is_trivially_default_constructible<T>::value,
- "Not compliant with std::is_trivially_default_constructible; "
- "Standard: true, Implementation: false");
-#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
-};
-
// is_trivially_move_constructible()
-//
-// Determines whether the passed type `T` is trivially move constructible.
-//
-// This metafunction is designed to be a drop-in replacement for the C++11
-// `std::is_trivially_move_constructible()` metafunction for platforms that have
-// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
-// fully support C++11, we check whether this yields the same result as the std
-// implementation.
-//
-// NOTE: `T obj(declval<T>());` needs to be well-formed and not call any
-// nontrivial operation. Nontrivially destructible types will cause the
-// expression to be nontrivial.
-template <typename T>
-struct is_trivially_move_constructible
-#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE)
- : std::is_trivially_move_constructible<T> {
-#else
- : std::conditional<
- std::is_object<T>::value && !std::is_array<T>::value,
- type_traits_internal::IsTriviallyMoveConstructibleObject<T>,
- std::is_reference<T>>::type::type {
-#endif
-#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
- !defined( \
- ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
- private:
- static constexpr bool compliant =
- std::is_trivially_move_constructible<T>::value ==
- is_trivially_move_constructible::value;
- static_assert(compliant || std::is_trivially_move_constructible<T>::value,
- "Not compliant with std::is_trivially_move_constructible; "
- "Standard: false, Implementation: true");
- static_assert(compliant || !std::is_trivially_move_constructible<T>::value,
- "Not compliant with std::is_trivially_move_constructible; "
- "Standard: true, Implementation: false");
-#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
-};
-
// is_trivially_copy_constructible()
-//
-// Determines whether the passed type `T` is trivially copy constructible.
-//
-// This metafunction is designed to be a drop-in replacement for the C++11
-// `std::is_trivially_copy_constructible()` metafunction for platforms that have
-// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
-// fully support C++11, we check whether this yields the same result as the std
-// implementation.
-//
-// NOTE: `T obj(declval<const T&>());` needs to be well-formed and not call any
-// nontrivial operation. Nontrivially destructible types will cause the
-// expression to be nontrivial.
-template <typename T>
-struct is_trivially_copy_constructible
- : std::conditional<
- std::is_object<T>::value && !std::is_array<T>::value,
- type_traits_internal::IsTriviallyCopyConstructibleObject<T>,
- std::is_lvalue_reference<T>>::type::type {
-#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
- !defined( \
- ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
- private:
- static constexpr bool compliant =
- std::is_trivially_copy_constructible<T>::value ==
- is_trivially_copy_constructible::value;
- static_assert(compliant || std::is_trivially_copy_constructible<T>::value,
- "Not compliant with std::is_trivially_copy_constructible; "
- "Standard: false, Implementation: true");
- static_assert(compliant || !std::is_trivially_copy_constructible<T>::value,
- "Not compliant with std::is_trivially_copy_constructible; "
- "Standard: true, Implementation: false");
-#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
-};
-
// is_trivially_move_assignable()
-//
-// Determines whether the passed type `T` is trivially move assignable.
-//
-// This metafunction is designed to be a drop-in replacement for the C++11
-// `std::is_trivially_move_assignable()` metafunction for platforms that have
-// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
-// fully support C++11, we check whether this yields the same result as the std
-// implementation.
-//
-// NOTE: `is_assignable<T, U>::value` is `true` if the expression
-// `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated
-// operand. `is_trivially_assignable<T, U>` requires the assignment to call no
-// operation that is not trivial. `is_trivially_copy_assignable<T>` is simply
-// `is_trivially_assignable<T&, T>`.
-template <typename T>
-struct is_trivially_move_assignable
- : std::conditional<
- 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>>,
- type_traits_internal::IsTriviallyMoveAssignableReference<T>>::type::
- type {
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
- private:
- static constexpr bool compliant =
- std::is_trivially_move_assignable<T>::value ==
- is_trivially_move_assignable::value;
- static_assert(compliant || std::is_trivially_move_assignable<T>::value,
- "Not compliant with std::is_trivially_move_assignable; "
- "Standard: false, Implementation: true");
- static_assert(compliant || !std::is_trivially_move_assignable<T>::value,
- "Not compliant with std::is_trivially_move_assignable; "
- "Standard: true, Implementation: false");
-#endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
-};
-
// is_trivially_copy_assignable()
//
-// Determines whether the passed type `T` is trivially copy assignable.
-//
-// This metafunction is designed to be a drop-in replacement for the C++11
-// `std::is_trivially_copy_assignable()` metafunction for platforms that have
-// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
-// fully support C++11, we check whether this yields the same result as the std
-// implementation.
-//
-// NOTE: `is_assignable<T, U>::value` is `true` if the expression
-// `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated
-// operand. `is_trivially_assignable<T, U>` requires the assignment to call no
-// operation that is not trivial. `is_trivially_copy_assignable<T>` is simply
-// `is_trivially_assignable<T&, const T&>`.
-template <typename T>
-struct is_trivially_copy_assignable
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
- : std::is_trivially_copy_assignable<T> {
-#else
- : std::integral_constant<
- bool, __has_trivial_assign(typename std::remove_reference<T>::type) &&
- absl::is_copy_assignable<T>::value> {
-#endif
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
- private:
- static constexpr bool compliant =
- std::is_trivially_copy_assignable<T>::value ==
- is_trivially_copy_assignable::value;
- static_assert(compliant || std::is_trivially_copy_assignable<T>::value,
- "Not compliant with std::is_trivially_copy_assignable; "
- "Standard: false, Implementation: true");
- static_assert(compliant || !std::is_trivially_copy_assignable<T>::value,
- "Not compliant with std::is_trivially_copy_assignable; "
- "Standard: true, Implementation: false");
-#endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
-};
+// Historical note: Abseil once provided implementations of these type traits
+// for platforms that lacked full support. New code should prefer to use the
+// std variants.
+//
+// See the documentation for the STL <type_traits> header for more information:
+// https://en.cppreference.com/w/cpp/header/type_traits
+using std::is_copy_assignable;
+using std::is_move_assignable;
+using std::is_trivially_copy_assignable;
+using std::is_trivially_copy_constructible;
+using std::is_trivially_default_constructible;
+using std::is_trivially_destructible;
+using std::is_trivially_move_assignable;
+using std::is_trivially_move_constructible;
#if defined(__cpp_lib_remove_cvref) && __cpp_lib_remove_cvref >= 201711L
template <typename T>
@@ -533,52 +230,11 @@ using remove_cvref_t = typename remove_cvref<T>::type;
#endif
namespace type_traits_internal {
-// is_trivially_copyable()
-//
-// Determines whether the passed type `T` is trivially copyable.
-//
-// This metafunction is designed to be a drop-in replacement for the C++11
-// `std::is_trivially_copyable()` metafunction for platforms that have
-// incomplete C++11 support (such as libstdc++ 4.x). We use the C++17 definition
-// of TriviallyCopyable.
-//
-// NOTE: `is_trivially_copyable<T>::value` is `true` if all of T's copy/move
-// constructors/assignment operators are trivial or deleted, T has at least
-// one non-deleted copy/move constructor/assignment operator, and T is trivially
-// destructible. Arrays of trivially copyable types are trivially copyable.
-//
-// We expose this metafunction only for internal use within absl.
-
-#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE)
-template <typename T>
-struct is_trivially_copyable : std::is_trivially_copyable<T> {};
-#else
-template <typename T>
-class is_trivially_copyable_impl {
- using ExtentsRemoved = typename std::remove_all_extents<T>::type;
- static constexpr bool kIsCopyOrMoveConstructible =
- std::is_copy_constructible<ExtentsRemoved>::value ||
- std::is_move_constructible<ExtentsRemoved>::value;
- static constexpr bool kIsCopyOrMoveAssignable =
- absl::is_copy_assignable<ExtentsRemoved>::value ||
- absl::is_move_assignable<ExtentsRemoved>::value;
-
- public:
- static constexpr bool kValue =
- (__has_trivial_copy(ExtentsRemoved) || !kIsCopyOrMoveConstructible) &&
- (__has_trivial_assign(ExtentsRemoved) || !kIsCopyOrMoveAssignable) &&
- (kIsCopyOrMoveConstructible || kIsCopyOrMoveAssignable) &&
- is_trivially_destructible<ExtentsRemoved>::value &&
- // We need to check for this explicitly because otherwise we'll say
- // references are trivial copyable when compiled by MSVC.
- !std::is_reference<ExtentsRemoved>::value;
-};
-
-template <typename T>
-struct is_trivially_copyable
- : std::integral_constant<
- bool, type_traits_internal::is_trivially_copyable_impl<T>::kValue> {};
-#endif
+// An implementation of std::is_trivially_copyable was once provided for
+// internal use within absl.
+// TODO(absl-team): Replace absl::type_traits_internal::is_trivially_copyable
+// with std::is_trivially_copyable and delete this using declaration.
+using std::is_trivially_copyable;
} // namespace type_traits_internal
// -----------------------------------------------------------------------------
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc
index b2a7a67b..4165fef5 100644
--- a/absl/meta/type_traits_test.cc
+++ b/absl/meta/type_traits_test.cc
@@ -352,29 +352,6 @@ class Base {
virtual ~Base() {}
};
-// Old versions of libc++, around Clang 3.5 to 3.6, consider deleted destructors
-// as also being trivial. With the resolution of CWG 1928 and CWG 1734, this
-// is no longer considered true and has thus been amended.
-// Compiler Explorer: https://godbolt.org/g/zT59ZL
-// CWG issue 1734: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1734
-// CWG issue 1928: http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1928
-#if !defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 3700
-#define ABSL_TRIVIALLY_DESTRUCTIBLE_CONSIDER_DELETED_DESTRUCTOR_NOT_TRIVIAL 1
-#endif
-
-// As of the moment, GCC versions >5.1 have a problem compiling for
-// std::is_trivially_default_constructible<NontrivialDestructor[10]>, where
-// NontrivialDestructor is a struct with a custom nontrivial destructor. Note
-// that this problem only occurs for arrays of a known size, so something like
-// std::is_trivially_default_constructible<NontrivialDestructor[]> does not
-// have any problems.
-// Compiler Explorer: https://godbolt.org/g/dXRbdK
-// GCC bug 83689: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83689
-#if defined(__clang__) || defined(_MSC_VER) || \
- (defined(__GNUC__) && __GNUC__ < 5)
-#define ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL 1
-#endif
-
TEST(TypeTraitsTest, TestIsFunction) {
struct Callable {
void operator()() {}
@@ -391,562 +368,6 @@ TEST(TypeTraitsTest, TestIsFunction) {
EXPECT_FALSE(absl::is_function<Callable>::value);
}
-TEST(TypeTraitsTest, TestTrivialDestructor) {
- // Verify that arithmetic types and pointers have trivial destructors.
- EXPECT_TRUE(absl::is_trivially_destructible<bool>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<char>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<unsigned char>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<signed char>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<wchar_t>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<int>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<unsigned int>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<int16_t>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<uint16_t>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<int64_t>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<uint64_t>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<float>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<double>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<long double>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<Trivial*>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<const std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<const Trivial*>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<std::string**>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<Trivial**>::value);
-
- // classes with destructors
- EXPECT_TRUE(absl::is_trivially_destructible<Trivial>::value);
- EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor>::value);
-
- // Verify that types with a nontrivial or deleted destructor
- // are marked as such.
- EXPECT_FALSE(absl::is_trivially_destructible<NontrivialDestructor>::value);
-#ifdef ABSL_TRIVIALLY_DESTRUCTIBLE_CONSIDER_DELETED_DESTRUCTOR_NOT_TRIVIAL
- EXPECT_FALSE(absl::is_trivially_destructible<DeletedDestructor>::value);
-#endif
-
- // simple_pair of such types is trivial
- EXPECT_TRUE((absl::is_trivially_destructible<simple_pair<int, int>>::value));
- EXPECT_TRUE((absl::is_trivially_destructible<
- simple_pair<Trivial, TrivialDestructor>>::value));
-
- // Verify that types without trivial destructors are correctly marked as such.
- EXPECT_FALSE(absl::is_trivially_destructible<std::string>::value);
- EXPECT_FALSE(absl::is_trivially_destructible<std::vector<int>>::value);
-
- // Verify that simple_pairs of types without trivial destructors
- // are not marked as trivial.
- EXPECT_FALSE((absl::is_trivially_destructible<
- simple_pair<int, std::string>>::value));
- EXPECT_FALSE((absl::is_trivially_destructible<
- simple_pair<std::string, int>>::value));
-
- // array of such types is trivial
- using int10 = int[10];
- EXPECT_TRUE(absl::is_trivially_destructible<int10>::value);
- using Trivial10 = Trivial[10];
- EXPECT_TRUE(absl::is_trivially_destructible<Trivial10>::value);
- using TrivialDestructor10 = TrivialDestructor[10];
- EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor10>::value);
-
- // Conversely, the opposite also holds.
- using NontrivialDestructor10 = NontrivialDestructor[10];
- EXPECT_FALSE(absl::is_trivially_destructible<NontrivialDestructor10>::value);
-}
-
-TEST(TypeTraitsTest, TestTrivialDefaultCtor) {
- // arithmetic types and pointers have trivial default constructors.
- EXPECT_TRUE(absl::is_trivially_default_constructible<bool>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<char>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<unsigned char>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<signed char>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<wchar_t>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<int>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<unsigned int>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<int16_t>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<uint16_t>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<int64_t>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<uint64_t>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<float>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<double>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<long double>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial*>::value);
- EXPECT_TRUE(
- absl::is_trivially_default_constructible<const std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<const Trivial*>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<std::string**>::value);
- EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial**>::value);
-
- // types with compiler generated default ctors
- EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial>::value);
- EXPECT_TRUE(
- absl::is_trivially_default_constructible<TrivialDefaultCtor>::value);
-
- // Verify that types without them are not.
- EXPECT_FALSE(
- absl::is_trivially_default_constructible<NontrivialDefaultCtor>::value);
- EXPECT_FALSE(
- absl::is_trivially_default_constructible<DeletedDefaultCtor>::value);
-
- // types with nontrivial destructor are nontrivial
- EXPECT_FALSE(
- absl::is_trivially_default_constructible<NontrivialDestructor>::value);
-
- // types with vtables
- EXPECT_FALSE(absl::is_trivially_default_constructible<Base>::value);
-
- // Verify that simple_pair has trivial constructors where applicable.
- EXPECT_TRUE((absl::is_trivially_default_constructible<
- simple_pair<int, char*>>::value));
- EXPECT_TRUE((absl::is_trivially_default_constructible<
- simple_pair<int, Trivial>>::value));
- EXPECT_TRUE((absl::is_trivially_default_constructible<
- simple_pair<int, TrivialDefaultCtor>>::value));
-
- // Verify that types without trivial constructors are
- // correctly marked as such.
- EXPECT_FALSE(absl::is_trivially_default_constructible<std::string>::value);
- EXPECT_FALSE(
- absl::is_trivially_default_constructible<std::vector<int>>::value);
-
- // Verify that simple_pairs of types without trivial constructors
- // are not marked as trivial.
- EXPECT_FALSE((absl::is_trivially_default_constructible<
- simple_pair<int, std::string>>::value));
- EXPECT_FALSE((absl::is_trivially_default_constructible<
- simple_pair<std::string, int>>::value));
-
- // Verify that arrays of such types are trivially default constructible
- using int10 = int[10];
- EXPECT_TRUE(absl::is_trivially_default_constructible<int10>::value);
- using Trivial10 = Trivial[10];
- EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial10>::value);
- using TrivialDefaultCtor10 = TrivialDefaultCtor[10];
- EXPECT_TRUE(
- absl::is_trivially_default_constructible<TrivialDefaultCtor10>::value);
-
- // Conversely, the opposite also holds.
-#ifdef ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL
- using NontrivialDefaultCtor10 = NontrivialDefaultCtor[10];
- EXPECT_FALSE(
- absl::is_trivially_default_constructible<NontrivialDefaultCtor10>::value);
-#endif
-}
-
-// GCC prior to 7.4 had a bug in its trivially-constructible traits
-// (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80654).
-// This test makes sure that we do not depend on the trait in these cases when
-// implementing absl triviality traits.
-
-template <class T>
-struct BadConstructors {
- BadConstructors() { static_assert(T::value, ""); }
-
- BadConstructors(BadConstructors&&) { static_assert(T::value, ""); }
-
- BadConstructors(const BadConstructors&) { static_assert(T::value, ""); }
-};
-
-TEST(TypeTraitsTest, TestTrivialityBadConstructors) {
- using BadType = BadConstructors<int>;
-
- EXPECT_FALSE(absl::is_trivially_default_constructible<BadType>::value);
- EXPECT_FALSE(absl::is_trivially_move_constructible<BadType>::value);
- EXPECT_FALSE(absl::is_trivially_copy_constructible<BadType>::value);
-}
-
-TEST(TypeTraitsTest, TestTrivialMoveCtor) {
- // Verify that arithmetic types and pointers have trivial move
- // constructors.
- EXPECT_TRUE(absl::is_trivially_move_constructible<bool>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<char>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<unsigned char>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<signed char>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<wchar_t>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<int>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<unsigned int>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<int16_t>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<uint16_t>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<int64_t>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<uint64_t>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<float>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<double>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<long double>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial*>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<const std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<const Trivial*>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<std::string**>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial**>::value);
-
- // Reference types
- EXPECT_TRUE(absl::is_trivially_move_constructible<int&>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<int&&>::value);
-
- // types with compiler generated move ctors
- EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial>::value);
- EXPECT_TRUE(absl::is_trivially_move_constructible<TrivialMoveCtor>::value);
-
- // Verify that types without them (i.e. nontrivial or deleted) are not.
- EXPECT_FALSE(
- absl::is_trivially_move_constructible<NontrivialCopyCtor>::value);
- EXPECT_FALSE(absl::is_trivially_move_constructible<DeletedCopyCtor>::value);
- EXPECT_FALSE(
- absl::is_trivially_move_constructible<NonCopyableOrMovable>::value);
-
- // type with nontrivial destructor are nontrivial move construbtible
- EXPECT_FALSE(
- absl::is_trivially_move_constructible<NontrivialDestructor>::value);
-
- // types with vtables
- EXPECT_FALSE(absl::is_trivially_move_constructible<Base>::value);
-
- // Verify that simple_pair of such types is trivially move constructible
- EXPECT_TRUE(
- (absl::is_trivially_move_constructible<simple_pair<int, char*>>::value));
- EXPECT_TRUE((
- absl::is_trivially_move_constructible<simple_pair<int, Trivial>>::value));
- EXPECT_TRUE((absl::is_trivially_move_constructible<
- simple_pair<int, TrivialMoveCtor>>::value));
-
- // Verify that types without trivial move constructors are
- // correctly marked as such.
- EXPECT_FALSE(absl::is_trivially_move_constructible<std::string>::value);
- EXPECT_FALSE(absl::is_trivially_move_constructible<std::vector<int>>::value);
-
- // Verify that simple_pairs of types without trivial move constructors
- // are not marked as trivial.
- EXPECT_FALSE((absl::is_trivially_move_constructible<
- simple_pair<int, std::string>>::value));
- EXPECT_FALSE((absl::is_trivially_move_constructible<
- simple_pair<std::string, int>>::value));
-
- // Verify that arrays are not
- using int10 = int[10];
- EXPECT_FALSE(absl::is_trivially_move_constructible<int10>::value);
-}
-
-TEST(TypeTraitsTest, TestTrivialCopyCtor) {
- // Verify that arithmetic types and pointers have trivial copy
- // constructors.
- EXPECT_TRUE(absl::is_trivially_copy_constructible<bool>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<char>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<unsigned char>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<signed char>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<wchar_t>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<int>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<unsigned int>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<int16_t>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<uint16_t>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<int64_t>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<uint64_t>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<float>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<double>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<long double>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial*>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<const std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<const Trivial*>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string**>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial**>::value);
-
- // Reference types
- EXPECT_TRUE(absl::is_trivially_copy_constructible<int&>::value);
- EXPECT_FALSE(absl::is_trivially_copy_constructible<int&&>::value);
-
- // types with compiler generated copy ctors
- EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial>::value);
- EXPECT_TRUE(absl::is_trivially_copy_constructible<TrivialCopyCtor>::value);
-
- // Verify that types without them (i.e. nontrivial or deleted) are not.
- EXPECT_FALSE(
- absl::is_trivially_copy_constructible<NontrivialCopyCtor>::value);
- EXPECT_FALSE(absl::is_trivially_copy_constructible<DeletedCopyCtor>::value);
- EXPECT_FALSE(
- absl::is_trivially_copy_constructible<MovableNonCopyable>::value);
- EXPECT_FALSE(
- absl::is_trivially_copy_constructible<NonCopyableOrMovable>::value);
-
- // type with nontrivial destructor are nontrivial copy construbtible
- EXPECT_FALSE(
- absl::is_trivially_copy_constructible<NontrivialDestructor>::value);
-
- // types with vtables
- EXPECT_FALSE(absl::is_trivially_copy_constructible<Base>::value);
-
- // Verify that simple_pair of such types is trivially copy constructible
- EXPECT_TRUE(
- (absl::is_trivially_copy_constructible<simple_pair<int, char*>>::value));
- EXPECT_TRUE((
- absl::is_trivially_copy_constructible<simple_pair<int, Trivial>>::value));
- EXPECT_TRUE((absl::is_trivially_copy_constructible<
- simple_pair<int, TrivialCopyCtor>>::value));
-
- // Verify that types without trivial copy constructors are
- // correctly marked as such.
- EXPECT_FALSE(absl::is_trivially_copy_constructible<std::string>::value);
- EXPECT_FALSE(absl::is_trivially_copy_constructible<std::vector<int>>::value);
-
- // Verify that simple_pairs of types without trivial copy constructors
- // are not marked as trivial.
- EXPECT_FALSE((absl::is_trivially_copy_constructible<
- simple_pair<int, std::string>>::value));
- EXPECT_FALSE((absl::is_trivially_copy_constructible<
- simple_pair<std::string, int>>::value));
-
- // Verify that arrays are not
- using int10 = int[10];
- EXPECT_FALSE(absl::is_trivially_copy_constructible<int10>::value);
-}
-
-TEST(TypeTraitsTest, TestTrivialMoveAssign) {
- // Verify that arithmetic types and pointers have trivial move
- // assignment operators.
- EXPECT_TRUE(absl::is_trivially_move_assignable<bool>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<char>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<unsigned char>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<signed char>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<wchar_t>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<int>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<unsigned int>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<int16_t>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<uint16_t>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<int64_t>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<uint64_t>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<float>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<double>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<long double>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial*>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<const std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<const Trivial*>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<std::string**>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial**>::value);
-
- // const qualified types are not assignable
- EXPECT_FALSE(absl::is_trivially_move_assignable<const int>::value);
-
- // types with compiler generated move assignment
- EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<TrivialMoveAssign>::value);
-
- // Verify that types without them (i.e. nontrivial or deleted) are not.
- EXPECT_FALSE(absl::is_trivially_move_assignable<NontrivialCopyAssign>::value);
- EXPECT_FALSE(absl::is_trivially_move_assignable<DeletedCopyAssign>::value);
- EXPECT_FALSE(absl::is_trivially_move_assignable<NonCopyableOrMovable>::value);
-
- // types with vtables
- EXPECT_FALSE(absl::is_trivially_move_assignable<Base>::value);
-
- // Verify that simple_pair is trivially assignable
- EXPECT_TRUE(
- (absl::is_trivially_move_assignable<simple_pair<int, char*>>::value));
- EXPECT_TRUE(
- (absl::is_trivially_move_assignable<simple_pair<int, Trivial>>::value));
- EXPECT_TRUE((absl::is_trivially_move_assignable<
- simple_pair<int, TrivialMoveAssign>>::value));
-
- // Verify that types not trivially move assignable are
- // correctly marked as such.
- EXPECT_FALSE(absl::is_trivially_move_assignable<std::string>::value);
- EXPECT_FALSE(absl::is_trivially_move_assignable<std::vector<int>>::value);
-
- // Verify that simple_pairs of types not trivially move assignable
- // are not marked as trivial.
- EXPECT_FALSE((absl::is_trivially_move_assignable<
- simple_pair<int, std::string>>::value));
- EXPECT_FALSE((absl::is_trivially_move_assignable<
- simple_pair<std::string, int>>::value));
-
- // Verify that arrays are not trivially move assignable
- using int10 = int[10];
- EXPECT_FALSE(absl::is_trivially_move_assignable<int10>::value);
-
- // Verify that references are handled correctly
- EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial&&>::value);
- EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial&>::value);
-}
-
-TEST(TypeTraitsTest, TestTrivialCopyAssign) {
- // Verify that arithmetic types and pointers have trivial copy
- // assignment operators.
- EXPECT_TRUE(absl::is_trivially_copy_assignable<bool>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<char>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<unsigned char>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<signed char>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<wchar_t>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<int>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<unsigned int>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<int16_t>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<uint16_t>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<int64_t>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<uint64_t>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<float>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<double>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<long double>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial*>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<const std::string*>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<const Trivial*>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<std::string**>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial**>::value);
-
- // const qualified types are not assignable
- EXPECT_FALSE(absl::is_trivially_copy_assignable<const int>::value);
-
- // types with compiler generated copy assignment
- EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<TrivialCopyAssign>::value);
-
- // Verify that types without them (i.e. nontrivial or deleted) are not.
- EXPECT_FALSE(absl::is_trivially_copy_assignable<NontrivialCopyAssign>::value);
- EXPECT_FALSE(absl::is_trivially_copy_assignable<DeletedCopyAssign>::value);
- EXPECT_FALSE(absl::is_trivially_copy_assignable<MovableNonCopyable>::value);
- EXPECT_FALSE(absl::is_trivially_copy_assignable<NonCopyableOrMovable>::value);
-
- // types with vtables
- EXPECT_FALSE(absl::is_trivially_copy_assignable<Base>::value);
-
- // Verify that simple_pair is trivially assignable
- EXPECT_TRUE(
- (absl::is_trivially_copy_assignable<simple_pair<int, char*>>::value));
- EXPECT_TRUE(
- (absl::is_trivially_copy_assignable<simple_pair<int, Trivial>>::value));
- EXPECT_TRUE((absl::is_trivially_copy_assignable<
- simple_pair<int, TrivialCopyAssign>>::value));
-
- // Verify that types not trivially copy assignable are
- // correctly marked as such.
- EXPECT_FALSE(absl::is_trivially_copy_assignable<std::string>::value);
- EXPECT_FALSE(absl::is_trivially_copy_assignable<std::vector<int>>::value);
-
- // Verify that simple_pairs of types not trivially copy assignable
- // are not marked as trivial.
- EXPECT_FALSE((absl::is_trivially_copy_assignable<
- simple_pair<int, std::string>>::value));
- EXPECT_FALSE((absl::is_trivially_copy_assignable<
- simple_pair<std::string, int>>::value));
-
- // Verify that arrays are not trivially copy assignable
- using int10 = int[10];
- EXPECT_FALSE(absl::is_trivially_copy_assignable<int10>::value);
-
- // Verify that references are handled correctly
- EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial&&>::value);
- EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial&>::value);
-}
-
-TEST(TypeTraitsTest, TestTriviallyCopyable) {
- // Verify that arithmetic types and pointers are trivially copyable.
- EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<bool>::value);
- EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<char>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<unsigned char>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<signed char>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<wchar_t>::value);
- EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<int>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<unsigned int>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<int16_t>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<uint16_t>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<int64_t>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<uint64_t>::value);
- EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<float>::value);
- EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<double>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<long double>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<std::string*>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<Trivial*>::value);
- EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<
- const std::string*>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<const Trivial*>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<std::string**>::value);
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<Trivial**>::value);
-
- // const qualified types are not assignable but are constructible
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<const int>::value);
-
- // Trivial copy constructor/assignment and destructor.
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<Trivial>::value);
- // Trivial copy assignment, but non-trivial copy constructor/destructor.
- EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
- TrivialCopyAssign>::value);
- // Trivial copy constructor, but non-trivial assignment.
- EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
- TrivialCopyCtor>::value);
-
- // Types with a non-trivial copy constructor/assignment
- EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
- NontrivialCopyCtor>::value);
- EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
- NontrivialCopyAssign>::value);
-
- // Types without copy constructor/assignment, but with move
- // MSVC disagrees with other compilers about this:
- // EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<
- // MovableNonCopyable>::value);
-
- // Types without copy/move constructor/assignment
- EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
- NonCopyableOrMovable>::value);
-
- // No copy assign, but has trivial copy constructor.
- EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<
- DeletedCopyAssign>::value);
-
- // types with vtables
- EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<Base>::value);
-
- // Verify that simple_pair is trivially copyable if members are
- EXPECT_TRUE((absl::type_traits_internal::is_trivially_copyable<
- simple_pair<int, char*>>::value));
- EXPECT_TRUE((absl::type_traits_internal::is_trivially_copyable<
- simple_pair<int, Trivial>>::value));
-
- // Verify that types not trivially copyable are
- // correctly marked as such.
- EXPECT_FALSE(
- absl::type_traits_internal::is_trivially_copyable<std::string>::value);
- EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
- std::vector<int>>::value);
-
- // Verify that simple_pairs of types not trivially copyable
- // are not marked as trivial.
- EXPECT_FALSE((absl::type_traits_internal::is_trivially_copyable<
- simple_pair<int, std::string>>::value));
- EXPECT_FALSE((absl::type_traits_internal::is_trivially_copyable<
- simple_pair<std::string, int>>::value));
- EXPECT_FALSE((absl::type_traits_internal::is_trivially_copyable<
- simple_pair<int, TrivialCopyAssign>>::value));
-
- // Verify that arrays of trivially copyable types are trivially copyable
- using int10 = int[10];
- EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<int10>::value);
- using int10x10 = int[10][10];
- EXPECT_TRUE(
- absl::type_traits_internal::is_trivially_copyable<int10x10>::value);
-
- // Verify that references are handled correctly
- EXPECT_FALSE(
- absl::type_traits_internal::is_trivially_copyable<Trivial&&>::value);
- EXPECT_FALSE(
- absl::type_traits_internal::is_trivially_copyable<Trivial&>::value);
-}
-
TEST(TypeTraitsTest, TestRemoveCVRef) {
EXPECT_TRUE(
(std::is_same<typename absl::remove_cvref<int>::type, int>::value));
@@ -1241,82 +662,6 @@ TEST(TypeTraitsTest, TestResultOf) {
EXPECT_EQ(TypeEnum::D, GetTypeExt(Wrap<TypeD>()));
}
-template <typename T>
-bool TestCopyAssign() {
- return absl::is_copy_assignable<T>::value ==
- std::is_copy_assignable<T>::value;
-}
-
-TEST(TypeTraitsTest, IsCopyAssignable) {
- EXPECT_TRUE(TestCopyAssign<int>());
- EXPECT_TRUE(TestCopyAssign<int&>());
- EXPECT_TRUE(TestCopyAssign<int&&>());
-
- struct S {};
- EXPECT_TRUE(TestCopyAssign<S>());
- EXPECT_TRUE(TestCopyAssign<S&>());
- EXPECT_TRUE(TestCopyAssign<S&&>());
-
- class C {
- public:
- explicit C(C* c) : c_(c) {}
- ~C() { delete c_; }
-
- private:
- C* c_;
- };
- EXPECT_TRUE(TestCopyAssign<C>());
- EXPECT_TRUE(TestCopyAssign<C&>());
- EXPECT_TRUE(TestCopyAssign<C&&>());
-
- // Reason for ifndef: add_lvalue_reference<T> in libc++ breaks for these cases
-#ifndef _LIBCPP_VERSION
- EXPECT_TRUE(TestCopyAssign<int()>());
- EXPECT_TRUE(TestCopyAssign<int(int) const>());
- EXPECT_TRUE(TestCopyAssign<int(...) volatile&>());
- EXPECT_TRUE(TestCopyAssign<int(int, ...) const volatile&&>());
-#endif // _LIBCPP_VERSION
-}
-
-template <typename T>
-bool TestMoveAssign() {
- return absl::is_move_assignable<T>::value ==
- std::is_move_assignable<T>::value;
-}
-
-TEST(TypeTraitsTest, IsMoveAssignable) {
- EXPECT_TRUE(TestMoveAssign<int>());
- EXPECT_TRUE(TestMoveAssign<int&>());
- EXPECT_TRUE(TestMoveAssign<int&&>());
-
- struct S {};
- EXPECT_TRUE(TestMoveAssign<S>());
- EXPECT_TRUE(TestMoveAssign<S&>());
- EXPECT_TRUE(TestMoveAssign<S&&>());
-
- class C {
- public:
- explicit C(C* c) : c_(c) {}
- ~C() { delete c_; }
- void operator=(const C&) = delete;
- void operator=(C&&) = delete;
-
- private:
- C* c_;
- };
- EXPECT_TRUE(TestMoveAssign<C>());
- EXPECT_TRUE(TestMoveAssign<C&>());
- EXPECT_TRUE(TestMoveAssign<C&&>());
-
- // Reason for ifndef: add_lvalue_reference<T> in libc++ breaks for these cases
-#ifndef _LIBCPP_VERSION
- EXPECT_TRUE(TestMoveAssign<int()>());
- EXPECT_TRUE(TestMoveAssign<int(int) const>());
- EXPECT_TRUE(TestMoveAssign<int(...) volatile&>());
- EXPECT_TRUE(TestMoveAssign<int(int, ...) const volatile&&>());
-#endif // _LIBCPP_VERSION
-}
-
namespace adl_namespace {
struct DeletedSwap {
diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc
index f09fcca3..6ffe43d5 100644
--- a/absl/numeric/int128.cc
+++ b/absl/numeric/int128.cc
@@ -216,9 +216,9 @@ std::ostream& operator<<(std::ostream& os, uint128 v) {
} else if (adjustfield == std::ios::internal &&
(flags & std::ios::showbase) &&
(flags & std::ios::basefield) == std::ios::hex && v != 0) {
- rep.insert((size_t)2, count, os.fill());
+ rep.insert(size_t{2}, count, os.fill());
} else {
- rep.insert((size_t)0, count, os.fill());
+ rep.insert(size_t{0}, count, os.fill());
}
}
@@ -314,16 +314,16 @@ std::ostream& operator<<(std::ostream& os, int128 v) {
break;
case std::ios::internal:
if (print_as_decimal && (rep[0] == '+' || rep[0] == '-')) {
- rep.insert(1u, count, os.fill());
+ rep.insert(size_t{1}, count, os.fill());
} else if ((flags & std::ios::basefield) == std::ios::hex &&
(flags & std::ios::showbase) && v != 0) {
- rep.insert((size_t)2, count, os.fill());
+ rep.insert(size_t{2}, count, os.fill());
} else {
- rep.insert((size_t)0, count, os.fill());
+ rep.insert(size_t{0}, count, os.fill());
}
break;
default: // std::ios::right
- rep.insert((size_t)0, count, os.fill());
+ rep.insert(size_t{0}, count, os.fill());
break;
}
}
diff --git a/absl/synchronization/internal/futex.h b/absl/synchronization/internal/futex.h
index 62bb40f7..9cf9841d 100644
--- a/absl/synchronization/internal/futex.h
+++ b/absl/synchronization/internal/futex.h
@@ -16,7 +16,9 @@
#include "absl/base/config.h"
-#ifndef _WIN32
+#ifdef _WIN32
+#include <windows.h>
+#else
#include <sys/time.h>
#include <unistd.h>
#endif
@@ -83,60 +85,34 @@ namespace synchronization_internal {
class FutexImpl {
public:
- // Atomically check that `*v == val`, and if it is, then sleep until the
- // timeout `t` has been reached, or until woken by `Wake()`.
- static int WaitUntil(std::atomic<int32_t>* v, int32_t val,
+ static int WaitUntil(std::atomic<int32_t> *v, int32_t val,
KernelTimeout t) {
- if (!t.has_timeout()) {
- return Wait(v, val);
- } else if (t.is_absolute_timeout()) {
- auto abs_timespec = t.MakeAbsTimespec();
- return WaitAbsoluteTimeout(v, val, &abs_timespec);
+ long err = 0; // NOLINT(runtime/int)
+ if (t.has_timeout()) {
+ // https://locklessinc.com/articles/futex_cheat_sheet/
+ // Unlike FUTEX_WAIT, FUTEX_WAIT_BITSET uses absolute time.
+ struct timespec abs_timeout = t.MakeAbsTimespec();
+ // Atomically check that the futex value is still 0, and if it
+ // is, sleep until abs_timeout or until woken by FUTEX_WAKE.
+ err = syscall(
+ SYS_futex, reinterpret_cast<int32_t *>(v),
+ FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME, val,
+ &abs_timeout, nullptr, FUTEX_BITSET_MATCH_ANY);
} else {
- auto rel_timespec = t.MakeRelativeTimespec();
- return WaitRelativeTimeout(v, val, &rel_timespec);
+ // Atomically check that the futex value is still 0, and if it
+ // is, sleep until woken by FUTEX_WAKE.
+ err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v),
+ FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, nullptr);
}
- }
-
- // Atomically check that `*v == val`, and if it is, then sleep until the until
- // woken by `Wake()`.
- static int Wait(std::atomic<int32_t>* v, int32_t val) {
- return WaitAbsoluteTimeout(v, val, nullptr);
- }
-
- // Atomically check that `*v == val`, and if it is, then sleep until
- // CLOCK_REALTIME reaches `*abs_timeout`, or until woken by `Wake()`.
- static int WaitAbsoluteTimeout(std::atomic<int32_t>* v, int32_t val,
- const struct timespec* abs_timeout) {
- // https://locklessinc.com/articles/futex_cheat_sheet/
- // Unlike FUTEX_WAIT, FUTEX_WAIT_BITSET uses absolute time.
- auto err =
- syscall(SYS_futex, reinterpret_cast<int32_t*>(v),
- FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME,
- val, abs_timeout, nullptr, FUTEX_BITSET_MATCH_ANY);
- if (err != 0) {
- return -errno;
- }
- return 0;
- }
-
- // Atomically check that `*v == val`, and if it is, then sleep until
- // `*rel_timeout` has elapsed, or until woken by `Wake()`.
- static int WaitRelativeTimeout(std::atomic<int32_t>* v, int32_t val,
- const struct timespec* rel_timeout) {
- // Atomically check that the futex value is still 0, and if it
- // is, sleep until abs_timeout or until woken by FUTEX_WAKE.
- auto err = syscall(SYS_futex, reinterpret_cast<int32_t*>(v),
- FUTEX_PRIVATE_FLAG, val, rel_timeout);
- if (err != 0) {
+ if (ABSL_PREDICT_FALSE(err != 0)) {
return -errno;
}
return 0;
}
- // Wakes at most `count` waiters that have entered the sleep state on `v`.
- static int Wake(std::atomic<int32_t>* v, int32_t count) {
- auto err = syscall(SYS_futex, reinterpret_cast<int32_t*>(v),
+ static int Wake(std::atomic<int32_t> *v, int32_t count) {
+ // NOLINTNEXTLINE(runtime/int)
+ long err = syscall(SYS_futex, reinterpret_cast<int32_t*>(v),
FUTEX_WAKE | FUTEX_PRIVATE_FLAG, count);
if (ABSL_PREDICT_FALSE(err < 0)) {
return -errno;
diff --git a/absl/synchronization/internal/waiter.cc b/absl/synchronization/internal/waiter.cc
index 4eee1298..f2051d67 100644
--- a/absl/synchronization/internal/waiter.cc
+++ b/absl/synchronization/internal/waiter.cc
@@ -67,74 +67,11 @@ static void MaybeBecomeIdle() {
#if ABSL_WAITER_MODE == ABSL_WAITER_MODE_FUTEX
-Waiter::Waiter() : futex_(0) {}
-
-bool Waiter::WaitAbsoluteTimeout(KernelTimeout t) {
- // Loop until we can atomically decrement futex from a positive
- // value, waiting on a futex while we believe it is zero.
- // Note that, since the thread ticker is just reset, we don't need to check
- // whether the thread is idle on the very first pass of the loop.
- bool first_pass = true;
-
- while (true) {
- int32_t x = futex_.load(std::memory_order_relaxed);
- while (x != 0) {
- if (!futex_.compare_exchange_weak(x, x - 1,
- std::memory_order_acquire,
- std::memory_order_relaxed)) {
- continue; // Raced with someone, retry.
- }
- return true; // Consumed a wakeup, we are done.
- }
-
- if (!first_pass) MaybeBecomeIdle();
- auto abs_timeout = t.MakeAbsTimespec();
- const int err = Futex::WaitAbsoluteTimeout(&futex_, 0, &abs_timeout);
- if (err != 0) {
- if (err == -EINTR || err == -EWOULDBLOCK) {
- // Do nothing, the loop will retry.
- } else if (err == -ETIMEDOUT) {
- return false;
- } else {
- ABSL_RAW_LOG(FATAL, "Futex operation failed with error %d\n", err);
- }
- }
- first_pass = false;
- }
-}
-
-#ifdef CLOCK_MONOTONIC
-
-// Subtracts the timespec `sub` from `in` if the result would not be negative,
-// and returns true. Returns false if the result would be negative, and leaves
-// `in` unchanged.
-static bool TimespecSubtract(struct timespec& in, const struct timespec& sub) {
- if (in.tv_sec < sub.tv_sec) {
- return false;
- }
- if (in.tv_nsec < sub.tv_nsec) {
- if (in.tv_sec == sub.tv_sec) {
- return false;
- }
- // Borrow from tv_sec.
- in.tv_sec -= 1;
- in.tv_nsec += 1'000'000'000;
- }
- in.tv_sec -= sub.tv_sec;
- in.tv_nsec -= sub.tv_nsec;
- return true;
+Waiter::Waiter() {
+ futex_.store(0, std::memory_order_relaxed);
}
-// On some platforms a background thread periodically calls `Poke()` to briefly
-// wake waiter threads so that they may call `MaybeBecomeIdle()`. This means
-// that `WaitRelativeTimeout()` differs slightly from `WaitAbsoluteTimeout()`
-// because it must adjust the timeout by the amount of time that it has already
-// slept.
-bool Waiter::WaitRelativeTimeout(KernelTimeout t) {
- struct timespec start;
- ABSL_RAW_CHECK(clock_gettime(CLOCK_MONOTONIC, &start) == 0,
- "clock_gettime() failed");
-
+bool Waiter::Wait(KernelTimeout t) {
// Loop until we can atomically decrement futex from a positive
// value, waiting on a futex while we believe it is zero.
// Note that, since the thread ticker is just reset, we don't need to check
@@ -152,24 +89,8 @@ bool Waiter::WaitRelativeTimeout(KernelTimeout t) {
return true; // Consumed a wakeup, we are done.
}
- auto relative_timeout = t.MakeRelativeTimespec();
- if (!first_pass) {
- MaybeBecomeIdle();
-
- // Adjust relative_timeout for `Poke()`s.
- struct timespec now;
- ABSL_RAW_CHECK(clock_gettime(CLOCK_MONOTONIC, &now) == 0,
- "clock_gettime() failed");
- // If TimespecSubstract(now, start) returns false, then the clock isn't
- // truly monotonic.
- if (TimespecSubtract(now, start)) {
- if (!TimespecSubtract(relative_timeout, now)) {
- return false; // Timeout.
- }
- }
- }
-
- const int err = Futex::WaitRelativeTimeout(&futex_, 0, &relative_timeout);
+ if (!first_pass) MaybeBecomeIdle();
+ const int err = Futex::WaitUntil(&futex_, 0, t);
if (err != 0) {
if (err == -EINTR || err == -EWOULDBLOCK) {
// Do nothing, the loop will retry.
@@ -183,23 +104,6 @@ bool Waiter::WaitRelativeTimeout(KernelTimeout t) {
}
}
-#else // CLOCK_MONOTONIC
-
-// No support for CLOCK_MONOTONIC.
-// KernelTimeout will automatically convert to an absolute timeout.
-bool Waiter::WaitRelativeTimeout(KernelTimeout t) {
- return WaitAbsoluteTimeout(t);
-}
-
-#endif // CLOCK_MONOTONIC
-
-bool Waiter::Wait(KernelTimeout t) {
- if (t.is_absolute_timeout()) {
- return WaitAbsoluteTimeout(t);
- }
- return WaitRelativeTimeout(t);
-}
-
void Waiter::Post() {
if (futex_.fetch_add(1, std::memory_order_release) == 0) {
// We incremented from 0, need to wake a potential waiter.
diff --git a/absl/synchronization/internal/waiter.h b/absl/synchronization/internal/waiter.h
index c206cc3f..b8adfeb5 100644
--- a/absl/synchronization/internal/waiter.h
+++ b/absl/synchronization/internal/waiter.h
@@ -110,9 +110,6 @@ class Waiter {
~Waiter() = delete;
#if ABSL_WAITER_MODE == ABSL_WAITER_MODE_FUTEX
- bool WaitAbsoluteTimeout(KernelTimeout t);
- bool WaitRelativeTimeout(KernelTimeout t);
-
// Futexes are defined by specification to be 32-bits.
// Thus std::atomic<int32_t> must be just an int32_t with lockfree methods.
std::atomic<int32_t> futex_;
diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc
index a8911614..ef6d063e 100644
--- a/absl/synchronization/mutex.cc
+++ b/absl/synchronization/mutex.cc
@@ -635,6 +635,21 @@ void Mutex::InternalAttemptToUseMutexInFatalSignalHandler() {
std::memory_order_release);
}
+// --------------------------time support
+
+// Return the current time plus the timeout. Use the same clock as
+// PerThreadSem::Wait() for consistency. Unfortunately, we don't have
+// such a choice when a deadline is given directly.
+static absl::Time DeadlineFromTimeout(absl::Duration timeout) {
+#ifndef _WIN32
+ struct timeval tv;
+ gettimeofday(&tv, nullptr);
+ return absl::TimeFromTimeval(tv) + timeout;
+#else
+ return absl::Now() + timeout;
+#endif
+}
+
// --------------------------Mutexes
// In the layout below, the msb of the bottom byte is currently unused. Also,
@@ -1534,13 +1549,7 @@ void Mutex::LockWhen(const Condition &cond) {
}
bool Mutex::LockWhenWithTimeout(const Condition &cond, absl::Duration timeout) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
- GraphId id = DebugOnlyDeadlockCheck(this);
- bool res = LockSlowWithDeadline(kExclusive, &cond,
- KernelTimeout(timeout), 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
- return res;
+ return LockWhenWithDeadline(cond, DeadlineFromTimeout(timeout));
}
bool Mutex::LockWhenWithDeadline(const Condition &cond, absl::Time deadline) {
@@ -1563,12 +1572,7 @@ void Mutex::ReaderLockWhen(const Condition &cond) {
bool Mutex::ReaderLockWhenWithTimeout(const Condition &cond,
absl::Duration timeout) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
- GraphId id = DebugOnlyDeadlockCheck(this);
- bool res = LockSlowWithDeadline(kShared, &cond, KernelTimeout(timeout), 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
- return res;
+ return ReaderLockWhenWithDeadline(cond, DeadlineFromTimeout(timeout));
}
bool Mutex::ReaderLockWhenWithDeadline(const Condition &cond,
@@ -1593,18 +1597,7 @@ void Mutex::Await(const Condition &cond) {
}
bool Mutex::AwaitWithTimeout(const Condition &cond, absl::Duration timeout) {
- if (cond.Eval()) { // condition already true; nothing to do
- if (kDebugMode) {
- this->AssertReaderHeld();
- }
- return true;
- }
-
- KernelTimeout t{timeout};
- bool res = this->AwaitCommon(cond, t);
- ABSL_RAW_CHECK(res || t.has_timeout(),
- "condition untrue on return from Await");
- return res;
+ return AwaitWithDeadline(cond, DeadlineFromTimeout(timeout));
}
bool Mutex::AwaitWithDeadline(const Condition &cond, absl::Time deadline) {
@@ -2670,7 +2663,7 @@ bool CondVar::WaitCommon(Mutex *mutex, KernelTimeout t) {
}
bool CondVar::WaitWithTimeout(Mutex *mu, absl::Duration timeout) {
- return WaitCommon(mu, KernelTimeout(timeout));
+ return WaitWithDeadline(mu, DeadlineFromTimeout(timeout));
}
bool CondVar::WaitWithDeadline(Mutex *mu, absl::Time deadline) {
diff --git a/ci/cmake_common.sh b/ci/cmake_common.sh
index 64317425..f62bb8a1 100644
--- a/ci/cmake_common.sh
+++ b/ci/cmake_common.sh
@@ -14,7 +14,7 @@
# The commit of GoogleTest to be used in the CMake tests in this directory.
# Keep this in sync with the commit in the WORKSPACE file.
-readonly ABSL_GOOGLETEST_COMMIT="934542165899c786cb5d8a710529c37184730183"
+readonly ABSL_GOOGLETEST_COMMIT="2d4f208765af7fa376b878860a7677ecc0bc390a"
# Avoid depending on GitHub by looking for a cached copy of the commit first.
if [[ -r "${KOKORO_GFILE_DIR:-}/distdir/${ABSL_GOOGLETEST_COMMIT}.zip" ]]; then