Roll abseil_revision 4b4f9aae75..f3f785ab59
Change Log:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+log/4b4f9aae75..f3f785ab59
Full diff:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+/4b4f9aae75..f3f785ab59
No .def file changes.
Bug: None
Change-Id: I257c47c54566b2fb08cfe1318fc3460b97beb4c2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2472398
Commit-Queue: Mirko Bonadei <mbonadei@chromium.org>
Auto-Submit: Danil Chapovalov <danilchap@chromium.org>
Reviewed-by: Mirko Bonadei <mbonadei@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817430}
GitOrigin-RevId: d69ccae700ae265a11111a7be1de451e72930bbd
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index cf6a8c9..d67c439 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -250,6 +250,7 @@
"synchronization/notification.h"
"synchronization/internal/create_thread_identity.cc"
"synchronization/internal/create_thread_identity.h"
+ "synchronization/internal/futex.h"
"synchronization/internal/graphcycles.cc"
"synchronization/internal/graphcycles.h"
"synchronization/internal/kernel_timeout.h"
diff --git a/README.chromium b/README.chromium
index 288e986..fda9472 100644
--- a/README.chromium
+++ b/README.chromium
@@ -4,7 +4,7 @@
License: Apache 2.0
License File: LICENSE
Version: 0
-Revision: 4b4f9aae75d3c85bdc07b0575de5d4db40cea439
+Revision: f3f785ab59478dd0312bf1b5df65d380650bf0dc
Security Critical: yes
Description:
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h
index 3c4fd73..09b91f7 100644
--- a/absl/algorithm/container.h
+++ b/absl/algorithm/container.h
@@ -93,7 +93,7 @@
// std::foo(begin(c), end(c));
// becomes
// std::foo(container_algorithm_internal::begin(c),
-// container_algorithm_internal::end(c));
+// container_algorithm_internal::end(c));
// These are meant for internal use only.
template <typename C>
@@ -351,7 +351,9 @@
auto last2 = container_algorithm_internal::c_end(c2);
for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
- if (*first1 != *first2) {
+ // Negates equality because Cpp17EqualityComparable doesn't require clients
+ // to overload both `operator==` and `operator!=`.
+ if (!(*first1 == *first2)) {
break;
}
}
diff --git a/absl/algorithm/container_test.cc b/absl/algorithm/container_test.cc
index fb94056..605afc8 100644
--- a/absl/algorithm/container_test.cc
+++ b/absl/algorithm/container_test.cc
@@ -183,6 +183,17 @@
EXPECT_EQ(result.first, sequence_.end());
EXPECT_EQ(result.second, std::prev(vector_.end()));
}
+ {
+ struct NoNotEquals {
+ constexpr bool operator==(NoNotEquals) const { return true; }
+ constexpr bool operator!=(NoNotEquals) const = delete;
+ };
+ std::vector<NoNotEquals> first;
+ std::list<NoNotEquals> second;
+
+ // Check this still compiles.
+ absl::c_mismatch(first, second);
+ }
}
TEST_F(NonMutatingTest, MismatchWithPredicate) {
diff --git a/absl/base/internal/exponential_biased_test.cc b/absl/base/internal/exponential_biased_test.cc
index 90a482d..075583c 100644
--- a/absl/base/internal/exponential_biased_test.cc
+++ b/absl/base/internal/exponential_biased_test.cc
@@ -185,7 +185,7 @@
ABSL_CONST_INIT static ExponentialBiased eb_static;
EXPECT_THAT(eb_static.GetSkipCount(2), Ge(0));
-#if ABSL_HAVE_THREAD_LOCAL
+#ifdef ABSL_HAVE_THREAD_LOCAL
thread_local ExponentialBiased eb_thread;
EXPECT_THAT(eb_thread.GetSkipCount(2), Ge(0));
#endif
diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc
index 349d926..4a3b205 100644
--- a/absl/base/internal/sysinfo.cc
+++ b/absl/base/internal/sysinfo.cc
@@ -426,7 +426,7 @@
// userspace construct) to avoid unnecessary system calls. Without this caching,
// it can take roughly 98ns, while it takes roughly 1ns with this caching.
pid_t GetCachedTID() {
-#if ABSL_HAVE_THREAD_LOCAL
+#ifdef ABSL_HAVE_THREAD_LOCAL
static thread_local pid_t thread_id = GetTID();
return thread_id;
#else
diff --git a/absl/base/internal/unaligned_access.h b/absl/base/internal/unaligned_access.h
index dd5250d..080c197 100644
--- a/absl/base/internal/unaligned_access.h
+++ b/absl/base/internal/unaligned_access.h
@@ -45,17 +45,7 @@
// For all three tools, replacing an unaligned access with a tool-specific
// callback solves the problem.
-// Make sure uint16_t/uint32_t/uint64_t are defined.
-#include <stdint.h>
-
-extern "C" {
-uint16_t __sanitizer_unaligned_load16(const void *p);
-uint32_t __sanitizer_unaligned_load32(const void *p);
-uint64_t __sanitizer_unaligned_load64(const void *p);
-void __sanitizer_unaligned_store16(void *p, uint16_t v);
-void __sanitizer_unaligned_store32(void *p, uint32_t v);
-void __sanitizer_unaligned_store64(void *p, uint64_t v);
-} // extern "C"
+#include <sanitizer/common_interface_defs.h>
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/absl/base/internal/unscaledcycleclock.cc b/absl/base/internal/unscaledcycleclock.cc
index f1e7bbe..1545288 100644
--- a/absl/base/internal/unscaledcycleclock.cc
+++ b/absl/base/internal/unscaledcycleclock.cc
@@ -123,9 +123,7 @@
#pragma intrinsic(__rdtsc)
-int64_t UnscaledCycleClock::Now() {
- return __rdtsc();
-}
+int64_t UnscaledCycleClock::Now() { return __rdtsc(); }
double UnscaledCycleClock::Frequency() {
return base_internal::NominalCPUFrequency();
diff --git a/absl/container/internal/layout_test.cc b/absl/container/internal/layout_test.cc
index 757272f..1d7158f 100644
--- a/absl/container/internal/layout_test.cc
+++ b/absl/container/internal/layout_test.cc
@@ -128,8 +128,10 @@
{
using L = Layout<int32_t, int32_t>;
SameType<std::tuple<int32_t, int32_t>, L::ElementTypes>();
- SameType<std::tuple<int32_t, int32_t>, decltype(L::Partial())::ElementTypes>();
- SameType<std::tuple<int32_t, int32_t>, decltype(L::Partial(0))::ElementTypes>();
+ SameType<std::tuple<int32_t, int32_t>,
+ decltype(L::Partial())::ElementTypes>();
+ SameType<std::tuple<int32_t, int32_t>,
+ decltype(L::Partial(0))::ElementTypes>();
}
{
using L = Layout<int8_t, int32_t, Int128>;
@@ -368,18 +370,21 @@
{
using L = Layout<int32_t>;
EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
- EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<0>(p))));
}
{
using L = Layout<int32_t, int32_t>;
EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
- EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
- EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<1>(p))));
EXPECT_EQ(0,
- Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
+ Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
EXPECT_EQ(12,
- Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
+ Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<1>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
+ EXPECT_EQ(
+ 12, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<0>(p))));
EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<1>(p))));
}
@@ -387,39 +392,44 @@
using L = Layout<int8_t, int32_t, Int128>;
EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<0>(p))));
EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<0>(p))));
- EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<1>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<0>(p))));
- EXPECT_EQ(4, Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<1>(p))));
+ EXPECT_EQ(4,
+ Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<0>(p))));
- EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<1>(p))));
+ EXPECT_EQ(8,
+ Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<1>(p))));
EXPECT_EQ(0,
Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
EXPECT_EQ(0,
Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<2>(p))));
EXPECT_EQ(0,
Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
- EXPECT_EQ(4,
- Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
+ EXPECT_EQ(
+ 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
EXPECT_EQ(8,
Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<2>(p))));
EXPECT_EQ(0,
Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
- EXPECT_EQ(8,
- Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
+ EXPECT_EQ(
+ 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
EXPECT_EQ(24,
Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<2>(p))));
EXPECT_EQ(
0, Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
EXPECT_EQ(
- 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
+ 0,
+ Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
EXPECT_EQ(
0, Distance(p, Type<const Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
EXPECT_EQ(
0, Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
EXPECT_EQ(
- 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
+ 4,
+ Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
EXPECT_EQ(
8, Distance(p, Type<const Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
EXPECT_EQ(
@@ -428,7 +438,8 @@
24,
Distance(p, Type<const Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
EXPECT_EQ(
- 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
+ 8,
+ Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L(5, 3, 1).Pointer<0>(p))));
EXPECT_EQ(24, Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<2>(p))));
EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<1>(p))));
@@ -439,75 +450,78 @@
alignas(max_align_t) const unsigned char p[100] = {};
{
using L = Layout<int32_t>;
- EXPECT_EQ(0,
- Distance(p, Type<const int32_t*>(L::Partial().Pointer<int32_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<int32_t>(p))));
}
{
using L = Layout<int8_t, int32_t, Int128>;
- EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<int8_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
- EXPECT_EQ(4,
- Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
- EXPECT_EQ(8,
- Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
EXPECT_EQ(
- 0, Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
+ 0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<int8_t>(p))));
EXPECT_EQ(
- 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
+ 0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 4,
+ Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 8,
+ Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(0, Distance(p, Type<const int32_t*>(
+ L::Partial(0, 0).Pointer<int32_t>(p))));
EXPECT_EQ(
0,
Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
EXPECT_EQ(
- 0, Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
- EXPECT_EQ(
- 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
+ 0,
+ Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(4, Distance(p, Type<const int32_t*>(
+ L::Partial(1, 0).Pointer<int32_t>(p))));
EXPECT_EQ(
8,
Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
EXPECT_EQ(
- 0, Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
- EXPECT_EQ(
- 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
+ 0,
+ Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
+ EXPECT_EQ(8, Distance(p, Type<const int32_t*>(
+ L::Partial(5, 3).Pointer<int32_t>(p))));
EXPECT_EQ(
24,
Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
- EXPECT_EQ(
- 0,
- Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
- EXPECT_EQ(
- 0,
- Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
+ L::Partial(0, 0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(0, Distance(p, Type<const int32_t*>(
+ L::Partial(0, 0, 0).Pointer<int32_t>(p))));
EXPECT_EQ(0, Distance(p, Type<const Int128*>(
L::Partial(0, 0, 0).Pointer<Int128>(p))));
- EXPECT_EQ(
- 0,
- Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
- EXPECT_EQ(
- 4,
- Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
+ L::Partial(1, 0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(4, Distance(p, Type<const int32_t*>(
+ L::Partial(1, 0, 0).Pointer<int32_t>(p))));
EXPECT_EQ(8, Distance(p, Type<const Int128*>(
L::Partial(1, 0, 0).Pointer<Int128>(p))));
- EXPECT_EQ(
- 0,
- Distance(p, Type<const int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
+ EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
+ L::Partial(5, 3, 1).Pointer<int8_t>(p))));
EXPECT_EQ(24, Distance(p, Type<const Int128*>(
L::Partial(5, 3, 1).Pointer<Int128>(p))));
- EXPECT_EQ(
- 8,
- Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
+ EXPECT_EQ(8, Distance(p, Type<const int32_t*>(
+ L::Partial(5, 3, 1).Pointer<int32_t>(p))));
EXPECT_EQ(24,
Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
- EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
}
}
@@ -548,15 +562,18 @@
EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
EXPECT_EQ(24, Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<2>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
- EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
- EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
+ EXPECT_EQ(4,
+ Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
EXPECT_EQ(24,
Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
- EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
+ EXPECT_EQ(8,
+ Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<0>(p))));
EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<2>(p))));
EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<1>(p))));
@@ -568,48 +585,61 @@
{
using L = Layout<int32_t>;
EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<int32_t>(p))));
- EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<int32_t>(p))));
}
{
using L = Layout<int8_t, int32_t, Int128>;
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<int8_t>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
- EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
- EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
+ EXPECT_EQ(4,
+ Distance(p, Type<int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
- EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
- EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
- EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(8,
+ Distance(p, Type<int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
EXPECT_EQ(0,
Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
- EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
- EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
EXPECT_EQ(8,
Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
- EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
- EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
EXPECT_EQ(24,
Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
EXPECT_EQ(
0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<Int128>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
- EXPECT_EQ(4,
- Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 4,
+ Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
EXPECT_EQ(
8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<Int128>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
EXPECT_EQ(
24, Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<Int128>(p))));
- EXPECT_EQ(8,
- Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 8,
+ Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<int8_t>(p))));
EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
@@ -790,67 +820,72 @@
{
using L = Layout<int32_t>;
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int32_t>>(L::Partial(0).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<const int32_t>>(L::Partial(0).Slice<0>(p)).data()));
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
- EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(L(3).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
+ EXPECT_EQ(0,
+ Distance(p, Type<Span<const int32_t>>(L(3).Slice<0>(p)).data()));
}
{
using L = Layout<int32_t, int32_t>;
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
EXPECT_EQ(
0,
- Distance(p,
- Type<Span<const int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
+ Distance(
+ p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
EXPECT_EQ(
12,
- Distance(p,
- Type<Span<const int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
- EXPECT_EQ(0,
- Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<0>(p)).data()));
- EXPECT_EQ(12,
- Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<1>(p)).data()));
+ Distance(
+ p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 12, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<1>(p)).data()));
}
{
using L = Layout<int8_t, int32_t, Int128>;
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int8_t>>(L::Partial(0).Slice<0>(p)).data()));
- EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int8_t>>(L::Partial(1).Slice<0>(p)).data()));
- EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int8_t>>(L::Partial(5).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<const int8_t>>(L::Partial(0).Slice<0>(p)).data()));
EXPECT_EQ(
0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
- EXPECT_EQ(
- 0,
- Distance(p,
- Type<Span<const int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
+ p, Type<Span<const int8_t>>(L::Partial(1).Slice<0>(p)).data()));
EXPECT_EQ(
0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
- EXPECT_EQ(
- 4,
- Distance(p,
- Type<Span<const int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
- EXPECT_EQ(
- 0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
- EXPECT_EQ(
- 8,
- Distance(p,
- Type<Span<const int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
+ p, Type<Span<const int8_t>>(L::Partial(5).Slice<0>(p)).data()));
EXPECT_EQ(
0,
Distance(
- p, Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
+ p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(
+ p, Type<Span<const int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(
+ p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 4,
+ Distance(
+ p, Type<Span<const int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(
+ p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 8,
+ Distance(
+ p, Type<Span<const int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(
+ p,
+ Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
EXPECT_EQ(
0,
Distance(
@@ -864,7 +899,8 @@
EXPECT_EQ(
0,
Distance(
- p, Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
+ p,
+ Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
EXPECT_EQ(
4,
Distance(
@@ -878,7 +914,8 @@
EXPECT_EQ(
0,
Distance(
- p, Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
+ p,
+ Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
EXPECT_EQ(
24,
Distance(
@@ -890,12 +927,14 @@
p,
Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
+ 0,
+ Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
EXPECT_EQ(
24,
Distance(p, Type<Span<const Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
EXPECT_EQ(
- 8, Distance(p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
+ 8,
+ Distance(p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
}
}
@@ -906,98 +945,94 @@
EXPECT_EQ(
0,
Distance(
- p, Type<Span<const int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
+ p,
+ Type<Span<const int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
EXPECT_EQ(
0,
Distance(
- p, Type<Span<const int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
+ p,
+ Type<Span<const int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<const int32_t>>(L(3).Slice<int32_t>(p)).data()));
+ 0,
+ Distance(p, Type<Span<const int32_t>>(L(3).Slice<int32_t>(p)).data()));
}
{
using L = Layout<int8_t, int32_t, Int128>;
EXPECT_EQ(
- 0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
0,
Distance(
- p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data()));
+ p,
+ Type<Span<const int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
Distance(
p,
- Type<Span<const int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data()));
- EXPECT_EQ(
- 0,
- Distance(
- p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 4,
- Distance(
- p,
- Type<Span<const int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data()));
- EXPECT_EQ(
- 0,
- Distance(
- p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 8,
- Distance(
- p,
- Type<Span<const int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data()));
+ Type<Span<const int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
Distance(
p,
- Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data()));
+ Type<Span<const int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<const int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p))
+ Distance(p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<int8_t>(p))
.data()));
+ EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(0, 0).Slice<int32_t>(p))
+ .data()));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<int8_t>(p))
+ .data()));
+ EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(1, 0).Slice<int32_t>(p))
+ .data()));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<int8_t>(p))
+ .data()));
+ EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(5, 3).Slice<int32_t>(p))
+ .data()));
+ EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
+ L::Partial(0, 0, 0).Slice<int8_t>(p))
+ .data()));
+ EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(0, 0, 0).Slice<int32_t>(p))
+ .data()));
EXPECT_EQ(0, Distance(p, Type<Span<const Int128>>(
L::Partial(0, 0, 0).Slice<Int128>(p))
.data()));
- EXPECT_EQ(
- 0,
- Distance(
- p,
- Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 4,
- Distance(p, Type<Span<const int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p))
- .data()));
+ EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
+ L::Partial(1, 0, 0).Slice<int8_t>(p))
+ .data()));
+ EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(1, 0, 0).Slice<int32_t>(p))
+ .data()));
EXPECT_EQ(8, Distance(p, Type<Span<const Int128>>(
L::Partial(1, 0, 0).Slice<Int128>(p))
.data()));
- EXPECT_EQ(
- 0,
- Distance(
- p,
- Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data()));
+ EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
+ L::Partial(5, 3, 1).Slice<int8_t>(p))
+ .data()));
EXPECT_EQ(24, Distance(p, Type<Span<const Int128>>(
L::Partial(5, 3, 1).Slice<Int128>(p))
.data()));
- EXPECT_EQ(
- 8,
- Distance(p, Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p))
- .data()));
+ EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(5, 3, 1).Slice<int32_t>(p))
+ .data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
+ Distance(p,
+ Type<Span<const int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
EXPECT_EQ(
24,
Distance(p,
Type<Span<const Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
EXPECT_EQ(
- 8, Distance(
- p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
+ 8,
+ Distance(
+ p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
}
}
@@ -1005,18 +1040,19 @@
alignas(max_align_t) unsigned char p[100];
{
using L = Layout<int32_t>;
- EXPECT_EQ(0,
- Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<0>(p)).data()));
- EXPECT_EQ(0,
- Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<0>(p)).data()));
}
{
using L = Layout<int32_t, int32_t>;
- EXPECT_EQ(0,
- Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
+ 0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
EXPECT_EQ(
12,
Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
@@ -1025,55 +1061,63 @@
}
{
using L = Layout<int8_t, int32_t, Int128>;
- EXPECT_EQ(0,
- Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<0>(p)).data()));
- EXPECT_EQ(0,
- Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<0>(p)).data()));
- EXPECT_EQ(0,
- Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<0>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
+ 0, Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<0>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
+ 0, Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<0>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
- EXPECT_EQ(
- 4, Distance(p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
- EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
- EXPECT_EQ(
- 8, Distance(p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
+ 0, Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<0>(p)).data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
+ Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
+ Distance(p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 4,
+ Distance(p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 8,
+ Distance(p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(
+ p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(
+ p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
EXPECT_EQ(
0, Distance(
p, Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data()));
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
EXPECT_EQ(
- 4,
- Distance(p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
+ 4, Distance(
+ p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
EXPECT_EQ(
8, Distance(
p, Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data()));
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
EXPECT_EQ(
24, Distance(
p, Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data()));
EXPECT_EQ(
- 8,
- Distance(p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
- EXPECT_EQ(0, Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
+ 8, Distance(
+ p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
+ EXPECT_EQ(0,
+ Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
EXPECT_EQ(24,
Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
- EXPECT_EQ(8, Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
+ EXPECT_EQ(8,
+ Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
}
}
@@ -1082,66 +1126,84 @@
{
using L = Layout<int32_t>;
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
+ 0, Distance(
+ p, Type<Span<int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
- EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<int32_t>(p)).data()));
+ 0, Distance(
+ p, Type<Span<int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
+ EXPECT_EQ(0,
+ Distance(p, Type<Span<int32_t>>(L(3).Slice<int32_t>(p)).data()));
}
{
using L = Layout<int8_t, int32_t, Int128>;
EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
+ 0,
+ Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 0, Distance(
- p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data()));
+ Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 4, Distance(
- p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data()));
+ Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 8, Distance(
- p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data()));
- EXPECT_EQ(
- 0, Distance(
- p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data()));
+ Distance(p,
+ Type<Span<int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
Distance(
- p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p)).data()));
+ p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(p,
+ Type<Span<int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data()));
+ EXPECT_EQ(
+ 4,
+ Distance(
+ p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(p,
+ Type<Span<int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data()));
+ EXPECT_EQ(
+ 8,
+ Distance(
+ p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(
+ p,
+ Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(
+ p,
+ Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p)).data()));
EXPECT_EQ(
0,
Distance(
p,
Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<Int128>(p)).data()));
EXPECT_EQ(
- 0, Distance(
- p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data()));
+ 0,
+ Distance(
+ p,
+ Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data()));
EXPECT_EQ(
4,
Distance(
- p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p)).data()));
+ p,
+ Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p)).data()));
EXPECT_EQ(
8,
Distance(
p,
Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<Int128>(p)).data()));
EXPECT_EQ(
- 0, Distance(
- p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data()));
+ 0,
+ Distance(
+ p,
+ Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data()));
EXPECT_EQ(
24,
Distance(
@@ -1150,14 +1212,16 @@
EXPECT_EQ(
8,
Distance(
- p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p)).data()));
- EXPECT_EQ(0,
- Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
+ p,
+ Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
EXPECT_EQ(
24,
Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
EXPECT_EQ(
- 8, Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
+ 8,
+ Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
}
}
@@ -1256,17 +1320,17 @@
}
{
const auto x = L::Partial(1, 2, 3);
- EXPECT_THAT(
- (Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(x.Slices(p))),
- Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
- IsSameSlice(x.Slice<2>(p))));
+ EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
+ x.Slices(p))),
+ Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
+ IsSameSlice(x.Slice<2>(p))));
}
{
const L x(1, 2, 3);
- EXPECT_THAT(
- (Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(x.Slices(p))),
- Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
- IsSameSlice(x.Slice<2>(p))));
+ EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
+ x.Slices(p))),
+ Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
+ IsSameSlice(x.Slice<2>(p))));
}
}
@@ -1398,7 +1462,8 @@
x.DebugString());
}
{
- constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3);
+ constexpr auto x =
+ Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3);
EXPECT_EQ(
"@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
"@16" +
@@ -1406,7 +1471,8 @@
x.DebugString());
}
{
- constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3, 4);
+ constexpr auto x =
+ Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3, 4);
EXPECT_EQ(
"@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
"@16" +
diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc
index 919ac07..2f744a6 100644
--- a/absl/container/internal/raw_hash_set.cc
+++ b/absl/container/internal/raw_hash_set.cc
@@ -27,7 +27,7 @@
// Returns "random" seed.
inline size_t RandomSeed() {
-#if ABSL_HAVE_THREAD_LOCAL
+#ifdef ABSL_HAVE_THREAD_LOCAL
static thread_local size_t counter = 0;
size_t value = ++counter;
#else // ABSL_HAVE_THREAD_LOCAL
diff --git a/absl/container/internal/raw_hash_set_allocator_test.cc b/absl/container/internal/raw_hash_set_allocator_test.cc
index 1a03608..e73f53f 100644
--- a/absl/container/internal/raw_hash_set_allocator_test.cc
+++ b/absl/container/internal/raw_hash_set_allocator_test.cc
@@ -466,6 +466,9 @@
size_t id_ = std::numeric_limits<size_t>::max();
};
+// This doesn't compile with GCC 5.4 and 5.5 due to a bug in noexcept handing.
+#if !defined(__GNUC__) || __GNUC__ != 5 || (__GNUC_MINOR__ != 4 && \
+ __GNUC_MINOR__ != 5)
TEST(NoPropagateOn, Swap) {
using PA = PAlloc<char>;
using Table = raw_hash_set<Policy, Identity, std::equal_to<int32_t>, PA>;
@@ -475,6 +478,7 @@
EXPECT_EQ(t1.get_allocator(), PA(1));
EXPECT_EQ(t2.get_allocator(), PA(2));
}
+#endif
TEST(NoPropagateOn, CopyConstruct) {
using PA = PAlloc<char>;
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index f5ae83c..6210eb6 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -847,7 +847,8 @@
std::vector<int64_t> CollectBadMergeKeys(size_t N) {
static constexpr int kGroupSize = Group::kWidth - 1;
- auto topk_range = [](size_t b, size_t e, IntTable* t) -> std::vector<int64_t> {
+ auto topk_range = [](size_t b, size_t e,
+ IntTable* t) -> std::vector<int64_t> {
for (size_t i = b; i != e; ++i) {
t->emplace(i);
}
@@ -1001,8 +1002,8 @@
// 1. Create new table and reserve it to keys.size() * 2
// 2. Insert all keys xored with seed
// 3. Collect ProbeStats from final table.
-ProbeStats CollectProbeStatsOnKeysXoredWithSeed(const std::vector<int64_t>& keys,
- size_t num_iters) {
+ProbeStats CollectProbeStatsOnKeysXoredWithSeed(
+ const std::vector<int64_t>& keys, size_t num_iters) {
const size_t reserve_size = keys.size() * 2;
ProbeStats stats;
diff --git a/absl/debugging/internal/address_is_readable.cc b/absl/debugging/internal/address_is_readable.cc
index 6537606..329c285 100644
--- a/absl/debugging/internal/address_is_readable.cc
+++ b/absl/debugging/internal/address_is_readable.cc
@@ -68,6 +68,7 @@
// unimplemented.
// This is a namespace-scoped variable for correct zero-initialization.
static std::atomic<uint64_t> pid_and_fds; // initially 0, an invalid pid.
+
bool AddressIsReadable(const void *addr) {
absl::base_internal::ErrnoSaver errno_saver;
// We test whether a byte is readable by using write(). Normally, this would
@@ -86,7 +87,7 @@
int pid;
int read_fd;
int write_fd;
- uint64_t local_pid_and_fds = pid_and_fds.load(std::memory_order_relaxed);
+ uint64_t local_pid_and_fds = pid_and_fds.load(std::memory_order_acquire);
Unpack(local_pid_and_fds, &pid, &read_fd, &write_fd);
while (current_pid != pid) {
int p[2];
@@ -98,13 +99,13 @@
fcntl(p[1], F_SETFD, FD_CLOEXEC);
uint64_t new_pid_and_fds = Pack(current_pid, p[0], p[1]);
if (pid_and_fds.compare_exchange_strong(
- local_pid_and_fds, new_pid_and_fds, std::memory_order_relaxed,
+ local_pid_and_fds, new_pid_and_fds, std::memory_order_release,
std::memory_order_relaxed)) {
local_pid_and_fds = new_pid_and_fds; // fds exposed to other threads
} else { // fds not exposed to other threads; we can close them.
close(p[0]);
close(p[1]);
- local_pid_and_fds = pid_and_fds.load(std::memory_order_relaxed);
+ local_pid_and_fds = pid_and_fds.load(std::memory_order_acquire);
}
Unpack(local_pid_and_fds, &pid, &read_fd, &write_fd);
}
@@ -124,7 +125,7 @@
// If pid_and_fds contains the problematic file descriptors we just used,
// this call will forget them, and the loop will try again.
pid_and_fds.compare_exchange_strong(local_pid_and_fds, 0,
- std::memory_order_relaxed,
+ std::memory_order_release,
std::memory_order_relaxed);
}
} while (errno == EBADF);
diff --git a/absl/debugging/internal/symbolize.h b/absl/debugging/internal/symbolize.h
index b3729af..4f26130 100644
--- a/absl/debugging/internal/symbolize.h
+++ b/absl/debugging/internal/symbolize.h
@@ -118,16 +118,14 @@
// filename != nullptr
//
// Returns true if the file was successfully registered.
-bool RegisterFileMappingHint(
- const void* start, const void* end, uint64_t offset, const char* filename);
+bool RegisterFileMappingHint(const void* start, const void* end,
+ uint64_t offset, const char* filename);
// Looks up the file mapping registered by RegisterFileMappingHint for an
// address range. If there is one, the file name is stored in *filename and
// *start and *end are modified to reflect the registered mapping. Returns
// whether any hint was found.
-bool GetFileMappingHint(const void** start,
- const void** end,
- uint64_t * offset,
+bool GetFileMappingHint(const void** start, const void** end, uint64_t* offset,
const char** filename);
} // namespace debugging_internal
diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel
index 9de9e22..2bd9478 100644
--- a/absl/flags/BUILD.bazel
+++ b/absl/flags/BUILD.bazel
@@ -381,6 +381,8 @@
deps = [
":flag",
":marshalling",
+ ":parse",
+ ":reflection",
"//absl/strings",
"//absl/time",
"//absl/types:optional",
diff --git a/absl/flags/flag_benchmark.cc b/absl/flags/flag_benchmark.cc
index 7b52c9b..9982b60 100644
--- a/absl/flags/flag_benchmark.cc
+++ b/absl/flags/flag_benchmark.cc
@@ -20,6 +20,8 @@
#include "absl/flags/flag.h"
#include "absl/flags/marshalling.h"
+#include "absl/flags/parse.h"
+#include "absl/flags/reflection.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/optional.h"
@@ -103,6 +105,23 @@
BENCHMARKED_TYPES(FLAG_DEF)
+// Register thousands of flags to bloat up the size of the registry.
+// This mimics real life production binaries.
+#define DEFINE_FLAG_0(name) ABSL_FLAG(int, name, 0, "");
+#define DEFINE_FLAG_1(name) DEFINE_FLAG_0(name##0) DEFINE_FLAG_0(name##1)
+#define DEFINE_FLAG_2(name) DEFINE_FLAG_1(name##0) DEFINE_FLAG_1(name##1)
+#define DEFINE_FLAG_3(name) DEFINE_FLAG_2(name##0) DEFINE_FLAG_2(name##1)
+#define DEFINE_FLAG_4(name) DEFINE_FLAG_3(name##0) DEFINE_FLAG_3(name##1)
+#define DEFINE_FLAG_5(name) DEFINE_FLAG_4(name##0) DEFINE_FLAG_4(name##1)
+#define DEFINE_FLAG_6(name) DEFINE_FLAG_5(name##0) DEFINE_FLAG_5(name##1)
+#define DEFINE_FLAG_7(name) DEFINE_FLAG_6(name##0) DEFINE_FLAG_6(name##1)
+#define DEFINE_FLAG_8(name) DEFINE_FLAG_7(name##0) DEFINE_FLAG_7(name##1)
+#define DEFINE_FLAG_9(name) DEFINE_FLAG_8(name##0) DEFINE_FLAG_8(name##1)
+#define DEFINE_FLAG_10(name) DEFINE_FLAG_9(name##0) DEFINE_FLAG_9(name##1)
+#define DEFINE_FLAG_11(name) DEFINE_FLAG_10(name##0) DEFINE_FLAG_10(name##1)
+#define DEFINE_FLAG_12(name) DEFINE_FLAG_11(name##0) DEFINE_FLAG_11(name##1)
+DEFINE_FLAG_12(bloat_flag_);
+
namespace {
#define BM_GetFlag(T) \
@@ -115,6 +134,20 @@
BENCHMARKED_TYPES(BM_GetFlag)
+void BM_ThreadedFindCommandLineFlag(benchmark::State& state) {
+ char dummy[] = "dummy";
+ char* argv[] = {dummy};
+ // We need to ensure that flags have been parsed. That is where the registry
+ // is finalized.
+ absl::ParseCommandLine(1, argv);
+
+ for (auto s : state) {
+ benchmark::DoNotOptimize(
+ absl::FindCommandLineFlag("bloat_flag_010101010101"));
+ }
+}
+BENCHMARK(BM_ThreadedFindCommandLineFlag)->ThreadRange(1, 16);
+
} // namespace
#define InvokeGetFlag(T) \
diff --git a/absl/flags/internal/registry.h b/absl/flags/internal/registry.h
index 1df2db7..a8d9eb9 100644
--- a/absl/flags/internal/registry.h
+++ b/absl/flags/internal/registry.h
@@ -30,9 +30,6 @@
ABSL_NAMESPACE_BEGIN
namespace flags_internal {
-// Executes specified visitor for each non-retired flag in the registry.
-// Requires the caller hold the registry lock.
-void ForEachFlagUnlocked(std::function<void(CommandLineFlag&)> visitor);
// Executes specified visitor for each non-retired flag in the registry. While
// callback are executed, the registry is locked and can't be changed.
void ForEachFlag(std::function<void(CommandLineFlag&)> visitor);
@@ -41,6 +38,8 @@
bool RegisterCommandLineFlag(CommandLineFlag&);
+void FinalizeRegistry();
+
//-----------------------------------------------------------------------------
// Retired registrations:
//
diff --git a/absl/flags/internal/usage.h b/absl/flags/internal/usage.h
index 0c62dc4..619ccce 100644
--- a/absl/flags/internal/usage.h
+++ b/absl/flags/internal/usage.h
@@ -36,7 +36,8 @@
kHumanReadable,
};
-// Outputs the help message describing specific flag.
+// Streams the help message describing `flag` to `out`.
+// The default value for `flag` is included in the output.
void FlagHelp(std::ostream& out, const CommandLineFlag& flag,
HelpFormat format = HelpFormat::kHumanReadable);
diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc
index 4f4bb3d..1835a83 100644
--- a/absl/flags/parse.cc
+++ b/absl/flags/parse.cc
@@ -611,6 +611,11 @@
OnUndefinedFlag on_undef_flag) {
ABSL_INTERNAL_CHECK(argc > 0, "Missing argv[0]");
+ // Once parsing has started we will not have more flag registrations.
+ // If we did, they would be missing during parsing, which is a problem on
+ // itself.
+ flags_internal::FinalizeRegistry();
+
// This routine does not return anything since we abort on failure.
CheckDefaultValuesParsingRoundtrip();
diff --git a/absl/flags/reflection.cc b/absl/flags/reflection.cc
index d706022..c6bf8aa 100644
--- a/absl/flags/reflection.cc
+++ b/absl/flags/reflection.cc
@@ -17,6 +17,7 @@
#include <assert.h>
+#include <atomic>
#include <map>
#include <string>
@@ -56,21 +57,23 @@
// Returns the flag object for the specified name, or nullptr if not found.
// Will emit a warning if a 'retired' flag is specified.
- CommandLineFlag* FindFlagLocked(absl::string_view name);
+ CommandLineFlag* FindFlag(absl::string_view name);
static FlagRegistry& GlobalRegistry(); // returns a singleton registry
private:
friend class flags_internal::FlagSaverImpl; // reads all the flags in order
// to copy them
- friend void ForEachFlagUnlocked(
- std::function<void(CommandLineFlag&)> visitor);
+ friend void ForEachFlag(std::function<void(CommandLineFlag&)> visitor);
+ friend void FinalizeRegistry();
- // The map from name to flag, for FindFlagLocked().
+ // The map from name to flag, for FindFlag().
using FlagMap = std::map<absl::string_view, CommandLineFlag*>;
using FlagIterator = FlagMap::iterator;
using FlagConstIterator = FlagMap::const_iterator;
FlagMap flags_;
+ std::vector<CommandLineFlag*> flat_flags_;
+ std::atomic<bool> finalized_flags_{false};
absl::Mutex lock_;
@@ -79,15 +82,6 @@
FlagRegistry& operator=(const FlagRegistry&);
};
-CommandLineFlag* FlagRegistry::FindFlagLocked(absl::string_view name) {
- FlagConstIterator i = flags_.find(name);
- if (i == flags_.end()) {
- return nullptr;
- }
-
- return i->second;
-}
-
namespace {
class FlagRegistryLock {
@@ -101,8 +95,24 @@
} // namespace
+CommandLineFlag* FlagRegistry::FindFlag(absl::string_view name) {
+ if (finalized_flags_.load(std::memory_order_acquire)) {
+ // We could save some gcus here if we make `Name()` be non-virtual.
+ // We could move the `const char*` name to the base class.
+ auto it = std::partition_point(
+ flat_flags_.begin(), flat_flags_.end(),
+ [=](CommandLineFlag* f) { return f->Name() < name; });
+ if (it != flat_flags_.end() && (*it)->Name() == name) return *it;
+ }
+
+ FlagRegistryLock frl(*this);
+ auto it = flags_.find(name);
+ return it != flags_.end() ? it->second : nullptr;
+}
+
void FlagRegistry::RegisterFlag(CommandLineFlag& flag) {
FlagRegistryLock registry_lock(*this);
+
std::pair<FlagIterator, bool> ins =
flags_.insert(FlagMap::value_type(flag.Name(), &flag));
if (ins.second == false) { // means the name was already in the map
@@ -152,18 +162,15 @@
// --------------------------------------------------------------------
-void ForEachFlagUnlocked(std::function<void(CommandLineFlag&)> visitor) {
- FlagRegistry& registry = FlagRegistry::GlobalRegistry();
- for (FlagRegistry::FlagConstIterator i = registry.flags_.begin();
- i != registry.flags_.end(); ++i) {
- visitor(*i->second);
- }
-}
-
void ForEachFlag(std::function<void(CommandLineFlag&)> visitor) {
FlagRegistry& registry = FlagRegistry::GlobalRegistry();
+
+ if (registry.finalized_flags_.load(std::memory_order_acquire)) {
+ for (const auto& i : registry.flat_flags_) visitor(*i);
+ }
+
FlagRegistryLock frl(registry);
- ForEachFlagUnlocked(visitor);
+ for (const auto& i : registry.flags_) visitor(*i.second);
}
// --------------------------------------------------------------------
@@ -173,6 +180,21 @@
return true;
}
+void FinalizeRegistry() {
+ auto& registry = FlagRegistry::GlobalRegistry();
+ FlagRegistryLock frl(registry);
+ if (registry.finalized_flags_.load(std::memory_order_relaxed)) {
+ // Was already finalized. Ignore the second time.
+ return;
+ }
+ registry.flat_flags_.reserve(registry.flags_.size());
+ for (const auto& f : registry.flags_) {
+ registry.flat_flags_.push_back(f.second);
+ }
+ registry.flags_.clear();
+ registry.finalized_flags_.store(true, std::memory_order_release);
+}
+
// --------------------------------------------------------------------
namespace {
@@ -298,9 +320,7 @@
if (name.empty()) return nullptr;
flags_internal::FlagRegistry& registry =
flags_internal::FlagRegistry::GlobalRegistry();
- flags_internal::FlagRegistryLock frl(registry);
-
- return registry.FindFlagLocked(name);
+ return registry.FindFlag(name);
}
// --------------------------------------------------------------------
diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc
index 39ba24a..1d2e6cf 100644
--- a/absl/hash/hash_test.cc
+++ b/absl/hash/hash_test.cc
@@ -82,8 +82,8 @@
}
REGISTER_TYPED_TEST_CASE_P(HashValueIntTest, BasicUsage, FastPath);
-using IntTypes = testing::Types<unsigned char, char, int, int32_t, int64_t, uint32_t,
- uint64_t, size_t>;
+using IntTypes = testing::Types<unsigned char, char, int, int32_t, int64_t,
+ uint32_t, uint64_t, size_t>;
INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueIntTest, IntTypes);
enum LegacyEnum { kValue1, kValue2, kValue3 };
@@ -819,8 +819,8 @@
}
REGISTER_TYPED_TEST_CASE_P(HashIntTest, BasicUsage);
-using IntTypes = testing::Types<unsigned char, char, int, int32_t, int64_t, uint32_t,
- uint64_t, size_t>;
+using IntTypes = testing::Types<unsigned char, char, int, int32_t, int64_t,
+ uint32_t, uint64_t, size_t>;
INSTANTIATE_TYPED_TEST_CASE_P(My, HashIntTest, IntTypes);
struct StructWithPadding {
diff --git a/absl/hash/internal/city.cc b/absl/hash/internal/city.cc
index e122c18..58d4bcb 100644
--- a/absl/hash/internal/city.cc
+++ b/absl/hash/internal/city.cc
@@ -253,9 +253,8 @@
// Return a 16-byte hash for 48 bytes. Quick and dirty.
// Callers do best to use "random-looking" values for a and b.
-static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(uint64_t w, uint64_t x,
- uint64_t y, uint64_t z,
- uint64_t a, uint64_t b) {
+static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(
+ uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) {
a += w;
b = Rotate(b + a + z, 21);
uint64_t c = a;
@@ -266,8 +265,9 @@
}
// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
-static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(const char *s, uint64_t a,
- uint64_t b) {
+static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(const char *s,
+ uint64_t a,
+ uint64_t b) {
return WeakHashLen32WithSeeds(Fetch64(s), Fetch64(s + 8), Fetch64(s + 16),
Fetch64(s + 24), a, b);
}
@@ -310,8 +310,10 @@
uint64_t x = Fetch64(s + len - 40);
uint64_t y = Fetch64(s + len - 16) + Fetch64(s + len - 56);
uint64_t z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24));
- std::pair<uint64_t, uint64_t> v = WeakHashLen32WithSeeds(s + len - 64, len, z);
- std::pair<uint64_t, uint64_t> w = WeakHashLen32WithSeeds(s + len - 32, y + k1, x);
+ std::pair<uint64_t, uint64_t> v =
+ WeakHashLen32WithSeeds(s + len - 64, len, z);
+ std::pair<uint64_t, uint64_t> w =
+ WeakHashLen32WithSeeds(s + len - 32, y + k1, x);
x = x * k1 + Fetch64(s);
// Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
@@ -337,7 +339,7 @@
}
uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0,
- uint64_t seed1) {
+ uint64_t seed1) {
return HashLen16(CityHash64(s, len) - seed0, seed1);
}
diff --git a/absl/hash/internal/city.h b/absl/hash/internal/city.h
index 161c774..9c1e7a5 100644
--- a/absl/hash/internal/city.h
+++ b/absl/hash/internal/city.h
@@ -71,7 +71,7 @@
// Hash function for a byte array. For convenience, two seeds are also
// hashed into the result.
uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0,
- uint64_t seed1);
+ uint64_t seed1);
// Hash function for a byte array. Most useful in 32-bit binaries.
uint32_t CityHash32(const char *s, size_t len);
diff --git a/absl/random/internal/generate_real_test.cc b/absl/random/internal/generate_real_test.cc
index aa02f0c..4bdc453 100644
--- a/absl/random/internal/generate_real_test.cc
+++ b/absl/random/internal/generate_real_test.cc
@@ -419,8 +419,8 @@
};
// Rely on RandU64ToFloat generating values from greatest to least when
- // supplied with uint64_t values from greatest (0xfff...) to least (0x0). Thus,
- // this algorithm stores the previous value, and if the new value is at
+ // supplied with uint64_t values from greatest (0xfff...) to least (0x0).
+ // Thus, this algorithm stores the previous value, and if the new value is at
// greater than or equal to the previous value, then there is a collision in
// the generation algorithm.
//
diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc
index 4443c82..dbed3e9 100644
--- a/absl/strings/cord_test.cc
+++ b/absl/strings/cord_test.cc
@@ -1,3 +1,17 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include "absl/strings/cord.h"
#include <algorithm>
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc
index 9feb224..e28a29b 100644
--- a/absl/strings/internal/str_format/arg.cc
+++ b/absl/strings/internal/str_format/arg.cc
@@ -1,3 +1,17 @@
+// Copyright 2020 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.
+
//
// POSIX spec:
// http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h
index 3dbc152..7040c86 100644
--- a/absl/strings/internal/str_format/arg.h
+++ b/absl/strings/internal/str_format/arg.h
@@ -1,3 +1,17 @@
+// Copyright 2020 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.
+
#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_
diff --git a/absl/strings/internal/str_format/bind.cc b/absl/strings/internal/str_format/bind.cc
index 6980ed1..194e21a 100644
--- a/absl/strings/internal/str_format/bind.cc
+++ b/absl/strings/internal/str_format/bind.cc
@@ -1,3 +1,17 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include "absl/strings/internal/str_format/bind.h"
#include <cerrno>
diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h
index 585246e..727b211 100644
--- a/absl/strings/internal/str_format/bind.h
+++ b/absl/strings/internal/str_format/bind.h
@@ -1,3 +1,17 @@
+// Copyright 2020 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.
+
#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_
diff --git a/absl/strings/internal/str_format/bind_test.cc b/absl/strings/internal/str_format/bind_test.cc
index 64790a8..1eef9c4 100644
--- a/absl/strings/internal/str_format/bind_test.cc
+++ b/absl/strings/internal/str_format/bind_test.cc
@@ -1,3 +1,17 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include "absl/strings/internal/str_format/bind.h"
#include <string.h>
diff --git a/absl/strings/internal/str_format/checker.h b/absl/strings/internal/str_format/checker.h
index 424c51f..2a2601e 100644
--- a/absl/strings/internal/str_format/checker.h
+++ b/absl/strings/internal/str_format/checker.h
@@ -1,3 +1,17 @@
+// Copyright 2020 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.
+
#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
diff --git a/absl/strings/internal/str_format/checker_test.cc b/absl/strings/internal/str_format/checker_test.cc
index a76d70b..7c70f47 100644
--- a/absl/strings/internal/str_format/checker_test.cc
+++ b/absl/strings/internal/str_format/checker_test.cc
@@ -1,3 +1,17 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include <string>
#include "gmock/gmock.h"
diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc
index 634ee78..375db0a 100644
--- a/absl/strings/internal/str_format/convert_test.cc
+++ b/absl/strings/internal/str_format/convert_test.cc
@@ -1,3 +1,17 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
diff --git a/absl/strings/internal/str_format/float_conversion.cc b/absl/strings/internal/str_format/float_conversion.cc
index 20aeada..d3c5f0a 100644
--- a/absl/strings/internal/str_format/float_conversion.cc
+++ b/absl/strings/internal/str_format/float_conversion.cc
@@ -1,3 +1,17 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include "absl/strings/internal/str_format/float_conversion.h"
#include <string.h>
diff --git a/absl/strings/internal/str_format/float_conversion.h b/absl/strings/internal/str_format/float_conversion.h
index e78bc19..71100e7 100644
--- a/absl/strings/internal/str_format/float_conversion.h
+++ b/absl/strings/internal/str_format/float_conversion.h
@@ -1,3 +1,17 @@
+// Copyright 2020 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.
+
#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_
diff --git a/absl/strings/internal/str_format/parser.cc b/absl/strings/internal/str_format/parser.cc
index cc55dfa..f308d02 100644
--- a/absl/strings/internal/str_format/parser.cc
+++ b/absl/strings/internal/str_format/parser.cc
@@ -1,3 +1,17 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include "absl/strings/internal/str_format/parser.h"
#include <assert.h>
diff --git a/absl/strings/internal/str_format/parser.h b/absl/strings/internal/str_format/parser.h
index fffed04..6504dd3 100644
--- a/absl/strings/internal/str_format/parser.h
+++ b/absl/strings/internal/str_format/parser.h
@@ -1,3 +1,17 @@
+// Copyright 2020 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.
+
#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_
diff --git a/absl/strings/internal/str_format/parser_test.cc b/absl/strings/internal/str_format/parser_test.cc
index 5aced98..a5fa1c7 100644
--- a/absl/strings/internal/str_format/parser_test.cc
+++ b/absl/strings/internal/str_format/parser_test.cc
@@ -1,3 +1,17 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include "absl/strings/internal/str_format/parser.h"
#include <string.h>
diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc
index d9fb25a..c60027a 100644
--- a/absl/strings/str_format_test.cc
+++ b/absl/strings/str_format_test.cc
@@ -1,3 +1,16 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
#include "absl/strings/str_format.h"
diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel
index b2df413..cd4009a 100644
--- a/absl/synchronization/BUILD.bazel
+++ b/absl/synchronization/BUILD.bazel
@@ -80,6 +80,7 @@
"barrier.h",
"blocking_counter.h",
"internal/create_thread_identity.h",
+ "internal/futex.h",
"internal/per_thread_sem.h",
"internal/waiter.h",
"mutex.h",
diff --git a/absl/synchronization/BUILD.gn b/absl/synchronization/BUILD.gn
index 4d26b4f..78f64cd 100644
--- a/absl/synchronization/BUILD.gn
+++ b/absl/synchronization/BUILD.gn
@@ -42,6 +42,7 @@
"barrier.h",
"blocking_counter.h",
"internal/create_thread_identity.h",
+ "internal/futex.h",
"internal/per_thread_sem.h",
"internal/waiter.h",
"mutex.h",
diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt
index c255b03..e633d0b 100644
--- a/absl/synchronization/CMakeLists.txt
+++ b/absl/synchronization/CMakeLists.txt
@@ -52,6 +52,7 @@
"barrier.h"
"blocking_counter.h"
"internal/create_thread_identity.h"
+ "internal/futex.h"
"internal/per_thread_sem.h"
"internal/waiter.h"
"mutex.h"
diff --git a/absl/synchronization/internal/futex.h b/absl/synchronization/internal/futex.h
new file mode 100644
index 0000000..06fbd6d
--- /dev/null
+++ b/absl/synchronization/internal/futex.h
@@ -0,0 +1,154 @@
+// Copyright 2020 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.
+#ifndef ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_
+#define ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_
+
+#include "absl/base/config.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#ifdef __linux__
+#include <linux/futex.h>
+#include <sys/syscall.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <time.h>
+
+#include <atomic>
+#include <cstdint>
+
+#include "absl/base/optimization.h"
+#include "absl/synchronization/internal/kernel_timeout.h"
+
+#ifdef ABSL_INTERNAL_HAVE_FUTEX
+#error ABSL_INTERNAL_HAVE_FUTEX may not be set on the command line
+#elif defined(__BIONIC__)
+// Bionic supports all the futex operations we need even when some of the futex
+// definitions are missing.
+#define ABSL_INTERNAL_HAVE_FUTEX
+#elif defined(__linux__) && defined(FUTEX_CLOCK_REALTIME)
+// FUTEX_CLOCK_REALTIME requires Linux >= 2.6.28.
+#define ABSL_INTERNAL_HAVE_FUTEX
+#endif
+
+#ifdef ABSL_INTERNAL_HAVE_FUTEX
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace synchronization_internal {
+
+// Some Android headers are missing these definitions even though they
+// support these futex operations.
+#ifdef __BIONIC__
+#ifndef SYS_futex
+#define SYS_futex __NR_futex
+#endif
+#ifndef FUTEX_WAIT_BITSET
+#define FUTEX_WAIT_BITSET 9
+#endif
+#ifndef FUTEX_PRIVATE_FLAG
+#define FUTEX_PRIVATE_FLAG 128
+#endif
+#ifndef FUTEX_CLOCK_REALTIME
+#define FUTEX_CLOCK_REALTIME 256
+#endif
+#ifndef FUTEX_BITSET_MATCH_ANY
+#define FUTEX_BITSET_MATCH_ANY 0xFFFFFFFF
+#endif
+#endif
+
+#if defined(__NR_futex_time64) && !defined(SYS_futex_time64)
+#define SYS_futex_time64 __NR_futex_time64
+#endif
+
+#if defined(SYS_futex_time64) && !defined(SYS_futex)
+#define SYS_futex SYS_futex_time64
+#endif
+
+class FutexImpl {
+ public:
+ static int WaitUntil(std::atomic<int32_t> *v, int32_t val,
+ KernelTimeout t) {
+ int err = 0;
+ 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 {
+ // 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);
+ }
+ if (ABSL_PREDICT_FALSE(err != 0)) {
+ err = -errno;
+ }
+ return err;
+ }
+
+ static int WaitBitsetAbsoluteTimeout(std::atomic<int32_t> *v, int32_t val,
+ int32_t bits,
+ const struct timespec *abstime) {
+ int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v),
+ FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG, val, abstime,
+ nullptr, bits);
+ if (ABSL_PREDICT_FALSE(err != 0)) {
+ err = -errno;
+ }
+ return err;
+ }
+
+ static int Wake(std::atomic<int32_t> *v, int32_t count) {
+ int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v),
+ FUTEX_WAKE | FUTEX_PRIVATE_FLAG, count);
+ if (ABSL_PREDICT_FALSE(err < 0)) {
+ err = -errno;
+ }
+ return err;
+ }
+
+ // FUTEX_WAKE_BITSET
+ static int WakeBitset(std::atomic<int32_t> *v, int32_t count, int32_t bits) {
+ int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v),
+ FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG, count, nullptr,
+ nullptr, bits);
+ if (ABSL_PREDICT_FALSE(err < 0)) {
+ err = -errno;
+ }
+ return err;
+ }
+};
+
+class Futex : public FutexImpl {};
+
+} // namespace synchronization_internal
+ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_INTERNAL_HAVE_FUTEX
+
+#endif // ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_
diff --git a/absl/synchronization/internal/kernel_timeout.h b/absl/synchronization/internal/kernel_timeout.h
index 1084e1e..bbd4d2d 100644
--- a/absl/synchronization/internal/kernel_timeout.h
+++ b/absl/synchronization/internal/kernel_timeout.h
@@ -26,6 +26,7 @@
#define ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_
#include <time.h>
+
#include <algorithm>
#include <limits>
@@ -142,7 +143,7 @@
struct timespec abstime;
int64_t seconds = (std::min)(n / kNanosPerSecond,
- int64_t{(std::numeric_limits<time_t>::max)()});
+ int64_t{(std::numeric_limits<time_t>::max)()});
abstime.tv_sec = static_cast<time_t>(seconds);
abstime.tv_nsec = static_cast<decltype(abstime.tv_nsec)>(n % kNanosPerSecond);
return abstime;
diff --git a/absl/synchronization/internal/waiter.cc b/absl/synchronization/internal/waiter.cc
index b6150b9..2123be6 100644
--- a/absl/synchronization/internal/waiter.cc
+++ b/absl/synchronization/internal/waiter.cc
@@ -48,6 +48,7 @@
#include "absl/base/optimization.h"
#include "absl/synchronization/internal/kernel_timeout.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace synchronization_internal {
@@ -66,71 +67,6 @@
#if ABSL_WAITER_MODE == ABSL_WAITER_MODE_FUTEX
-// Some Android headers are missing these definitions even though they
-// support these futex operations.
-#ifdef __BIONIC__
-#ifndef SYS_futex
-#define SYS_futex __NR_futex
-#endif
-#ifndef FUTEX_WAIT_BITSET
-#define FUTEX_WAIT_BITSET 9
-#endif
-#ifndef FUTEX_PRIVATE_FLAG
-#define FUTEX_PRIVATE_FLAG 128
-#endif
-#ifndef FUTEX_CLOCK_REALTIME
-#define FUTEX_CLOCK_REALTIME 256
-#endif
-#ifndef FUTEX_BITSET_MATCH_ANY
-#define FUTEX_BITSET_MATCH_ANY 0xFFFFFFFF
-#endif
-#endif
-
-#if defined(__NR_futex_time64) && !defined(SYS_futex_time64)
-#define SYS_futex_time64 __NR_futex_time64
-#endif
-
-#if defined(SYS_futex_time64) && !defined(SYS_futex)
-#define SYS_futex SYS_futex_time64
-#endif
-
-class Futex {
- public:
- static int WaitUntil(std::atomic<int32_t> *v, int32_t val,
- KernelTimeout t) {
- int err = 0;
- 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 {
- // 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);
- }
- if (err != 0) {
- err = -errno;
- }
- return err;
- }
-
- static int Wake(std::atomic<int32_t> *v, int32_t count) {
- int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v),
- FUTEX_WAKE | FUTEX_PRIVATE_FLAG, count);
- if (ABSL_PREDICT_FALSE(err < 0)) {
- err = -errno;
- }
- return err;
- }
-};
-
Waiter::Waiter() {
futex_.store(0, std::memory_order_relaxed);
}
diff --git a/absl/synchronization/internal/waiter.h b/absl/synchronization/internal/waiter.h
index 887f9b1..be3df18 100644
--- a/absl/synchronization/internal/waiter.h
+++ b/absl/synchronization/internal/waiter.h
@@ -36,6 +36,7 @@
#include <cstdint>
#include "absl/base/internal/thread_identity.h"
+#include "absl/synchronization/internal/futex.h"
#include "absl/synchronization/internal/kernel_timeout.h"
// May be chosen at compile time via -DABSL_FORCE_WAITER_MODE=<index>
@@ -48,12 +49,7 @@
#define ABSL_WAITER_MODE ABSL_FORCE_WAITER_MODE
#elif defined(_WIN32) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
#define ABSL_WAITER_MODE ABSL_WAITER_MODE_WIN32
-#elif defined(__BIONIC__)
-// Bionic supports all the futex operations we need even when some of the futex
-// definitions are missing.
-#define ABSL_WAITER_MODE ABSL_WAITER_MODE_FUTEX
-#elif defined(__linux__) && defined(FUTEX_CLOCK_REALTIME)
-// FUTEX_CLOCK_REALTIME requires Linux >= 2.6.28.
+#elif defined(ABSL_INTERNAL_HAVE_FUTEX)
#define ABSL_WAITER_MODE ABSL_WAITER_MODE_FUTEX
#elif defined(ABSL_HAVE_SEMAPHORE_H)
#define ABSL_WAITER_MODE ABSL_WAITER_MODE_SEM
diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc
index 9b7f088..9e01393 100644
--- a/absl/synchronization/mutex.cc
+++ b/absl/synchronization/mutex.cc
@@ -50,6 +50,7 @@
#include "absl/base/internal/spinlock.h"
#include "absl/base/internal/sysinfo.h"
#include "absl/base/internal/thread_identity.h"
+#include "absl/base/internal/tsan_mutex_interface.h"
#include "absl/base/port.h"
#include "absl/debugging/stacktrace.h"
#include "absl/debugging/symbolize.h"
@@ -88,8 +89,8 @@
ABSL_CONST_INIT std::atomic<bool> synch_check_invariants(false);
ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
- absl::base_internal::AtomicHook<void (*)(int64_t wait_cycles)>
- submit_profile_data;
+absl::base_internal::AtomicHook<void (*)(int64_t wait_cycles)>
+ submit_profile_data;
ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook<void (*)(
const char *msg, const void *obj, int64_t wait_cycles)>
mutex_tracer;
@@ -491,7 +492,7 @@
std::atomic<intptr_t> *cv_word;
int64_t contention_start_cycles; // Time (in cycles) when this thread started
- // to contend for the mutex.
+ // to contend for the mutex.
};
struct SynchLocksHeld {
@@ -705,7 +706,7 @@
static constexpr bool kDebugMode = true;
#endif
-#ifdef ABSL_HAVE_THREAD_SANITIZER
+#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
static unsigned TsanFlags(Mutex::MuHow how) {
return how == kShared ? __tsan_mutex_read_lock : 0;
}
@@ -1767,7 +1768,7 @@
// All memory accesses are ignored inside of mutex operations + for unlock
// operation tsan considers that we've already released the mutex.
bool res = false;
-#ifdef ABSL_HAVE_THREAD_SANITIZER
+#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
const int flags = read_lock ? __tsan_mutex_read_lock : 0;
const int tryflags = flags | (trylock ? __tsan_mutex_try_lock : 0);
#endif
@@ -2311,7 +2312,8 @@
if (!cond_waiter) {
// Sample lock contention events only if the (first) waiter was trying to
// acquire the lock, not waiting on a condition variable or Condition.
- int64_t wait_cycles = base_internal::CycleClock::Now() - enqueue_timestamp;
+ int64_t wait_cycles =
+ base_internal::CycleClock::Now() - enqueue_timestamp;
mutex_tracer("slow release", this, wait_cycles);
ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0);
submit_profile_data(enqueue_timestamp);
diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h
index 6340bd6..f686c4d 100644
--- a/absl/synchronization/mutex.h
+++ b/absl/synchronization/mutex.h
@@ -667,10 +667,10 @@
// };
// mu_.Await(Condition(&reached));
//
- // NOTE: never use "mu_.AssertHeld()" instead of "mu_.AssertReadHeld()" in the
- // lambda as it may be called when the mutex is being unlocked from a scope
- // holding only a reader lock, which will make the assertion not fulfilled and
- // crash the binary.
+ // NOTE: never use "mu_.AssertHeld()" instead of "mu_.AssertReaderHeld()" in
+ // the lambda as it may be called when the mutex is being unlocked from a
+ // scope holding only a reader lock, which will make the assertion not
+ // fulfilled and crash the binary.
// See class comment for performance advice. In particular, if there
// might be more than one waiter for the same condition, make sure
@@ -954,7 +954,7 @@
//
// This has the same memory ordering concerns as RegisterMutexProfiler() above.
void RegisterMutexTracer(void (*fn)(const char *msg, const void *obj,
- int64_t wait_cycles));
+ int64_t wait_cycles));
// TODO(gfalcon): Combine RegisterMutexProfiler() and RegisterMutexTracer()
// into a single interface, since they are only ever called in pairs.
diff --git a/absl/time/clock.cc b/absl/time/clock.cc
index e5c423c..6862e01 100644
--- a/absl/time/clock.cc
+++ b/absl/time/clock.cc
@@ -74,9 +74,7 @@
#if !ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS
namespace absl {
ABSL_NAMESPACE_BEGIN
-int64_t GetCurrentTimeNanos() {
- return GET_CURRENT_TIME_NANOS_FROM_SYSTEM();
-}
+int64_t GetCurrentTimeNanos() { return GET_CURRENT_TIME_NANOS_FROM_SYSTEM(); }
ABSL_NAMESPACE_END
} // namespace absl
#else // Use the cyclecounter-based implementation below.
diff --git a/absl/time/duration.cc b/absl/time/duration.cc
index eca1a6d..4443109 100644
--- a/absl/time/duration.cc
+++ b/absl/time/duration.cc
@@ -356,7 +356,7 @@
// the remainder. If it does not saturate, the remainder remain accurate,
// but the returned quotient will over/underflow int64_t and should not be used.
int64_t IDivDuration(bool satq, const Duration num, const Duration den,
- Duration* rem) {
+ Duration* rem) {
int64_t q = 0;
if (IDivFastPath(num, den, &q, rem)) {
return q;
diff --git a/absl/time/time.cc b/absl/time/time.cc
index 6bb36cb..1ec2026 100644
--- a/absl/time/time.cc
+++ b/absl/time/time.cc
@@ -60,9 +60,10 @@
inline int64_t FloorToUnit(absl::Duration d, absl::Duration unit) {
absl::Duration rem;
int64_t q = absl::IDivDuration(d, unit, &rem);
- return (q > 0 ||
- rem >= ZeroDuration() ||
- q == std::numeric_limits<int64_t>::min()) ? q : q - 1;
+ return (q > 0 || rem >= ZeroDuration() ||
+ q == std::numeric_limits<int64_t>::min())
+ ? q
+ : q - 1;
}
inline absl::Time::Breakdown InfiniteFutureBreakdown() {
diff --git a/absl/time/time.h b/absl/time/time.h
index 37f6131..7250803 100644
--- a/absl/time/time.h
+++ b/absl/time/time.h
@@ -639,7 +639,7 @@
// Deprecated. Use `absl::TimeZone::CivilInfo`.
struct
Breakdown {
- int64_t year; // year (e.g., 2013)
+ int64_t year; // year (e.g., 2013)
int month; // month of year [1:12]
int day; // day of month [1:31]
int hour; // hour of day [0:23]
@@ -1494,12 +1494,10 @@
constexpr bool operator<(Duration lhs, Duration rhs) {
return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs)
? time_internal::GetRepHi(lhs) < time_internal::GetRepHi(rhs)
- : time_internal::GetRepHi(lhs) ==
- (std::numeric_limits<int64_t>::min)()
- ? time_internal::GetRepLo(lhs) + 1 <
- time_internal::GetRepLo(rhs) + 1
- : time_internal::GetRepLo(lhs) <
- time_internal::GetRepLo(rhs);
+ : time_internal::GetRepHi(lhs) == (std::numeric_limits<int64_t>::min)()
+ ? time_internal::GetRepLo(lhs) + 1 <
+ time_internal::GetRepLo(rhs) + 1
+ : time_internal::GetRepLo(lhs) < time_internal::GetRepLo(rhs);
}
constexpr bool operator==(Duration lhs, Duration rhs) {
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc
index b28a99f..cde9423 100644
--- a/absl/time/time_test.cc
+++ b/absl/time/time_test.cc
@@ -1070,7 +1070,8 @@
EXPECT_EQ("292277026596-12-04T15:30:07+00:00",
absl::FormatTime(absl::RFC3339_full, t, utc));
EXPECT_EQ(
- absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()), t);
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()),
+ t);
// Checks that we can also get the maximal Time value for a far-east zone.
const absl::TimeZone plus14 = absl::FixedTimeZone(14 * 60 * 60);
@@ -1078,7 +1079,8 @@
EXPECT_EQ("292277026596-12-05T05:30:07+14:00",
absl::FormatTime(absl::RFC3339_full, t, plus14));
EXPECT_EQ(
- absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()), t);
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()),
+ t);
// One second later should push us to infinity.
t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 15, 30, 8), utc);
@@ -1092,7 +1094,8 @@
EXPECT_EQ("-292277022657-01-27T08:29:52+00:00",
absl::FormatTime(absl::RFC3339_full, t, utc));
EXPECT_EQ(
- absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()), t);
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()),
+ t);
// Checks that we can also get the minimal Time value for a far-west zone.
const absl::TimeZone minus12 = absl::FixedTimeZone(-12 * 60 * 60);
@@ -1101,7 +1104,8 @@
EXPECT_EQ("-292277022657-01-26T20:29:52-12:00",
absl::FormatTime(absl::RFC3339_full, t, minus12));
EXPECT_EQ(
- absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()), t);
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()),
+ t);
// One second before should push us to -infinity.
t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 27, 8, 29, 51), utc);
diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h
index d404e80..772008c 100644
--- a/absl/types/internal/variant.h
+++ b/absl/types/internal/variant.h
@@ -45,7 +45,7 @@
template <class... Types>
class variant;
-ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, -1);
+ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, static_cast<size_t>(-1));
template <class T>
struct variant_size;
diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc
index cf8f7f3..cf23733 100644
--- a/absl/types/variant_test.cc
+++ b/absl/types/variant_test.cc
@@ -2311,7 +2311,8 @@
ASSERT_TRUE(absl::holds_alternative<int32_t>(variant2));
EXPECT_EQ(42, absl::get<int32_t>(variant2));
- variant2 = ConvertVariantTo<variant<int32_t, uint32_t>>(variant<uint32_t>(42));
+ variant2 =
+ ConvertVariantTo<variant<int32_t, uint32_t>>(variant<uint32_t>(42));
ASSERT_TRUE(absl::holds_alternative<uint32_t>(variant2));
EXPECT_EQ(42, absl::get<uint32_t>(variant2));
#endif // !ABSL_USES_STD_VARIANT
@@ -2453,7 +2454,8 @@
ConvertVariantTo<variant<int32_t, uint32_t>>(variant<int32_t>(42)));
EXPECT_THAT(absl::get_if<int32_t>(&variant2), Pointee(42));
- variant2 = ConvertVariantTo<variant<int32_t, uint32_t>>(variant<uint32_t>(42));
+ variant2 =
+ ConvertVariantTo<variant<int32_t, uint32_t>>(variant<uint32_t>(42));
EXPECT_THAT(absl::get_if<uint32_t>(&variant2), Pointee(42));
#endif
diff --git a/ci/linux_docker_containers.sh b/ci/linux_docker_containers.sh
index e42fa58..752b572 100644
--- a/ci/linux_docker_containers.sh
+++ b/ci/linux_docker_containers.sh
@@ -16,6 +16,6 @@
# Test scripts should source this file to get the identifiers.
readonly LINUX_ALPINE_CONTAINER="gcr.io/google.com/absl-177019/alpine:20191016"
-readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20200909"
-readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20200909"
+readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20201008"
+readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20201008"
readonly LINUX_GCC_49_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-4.9:20191018"