Roll chromium_revision ffaf1e2ba6..ef538e3112 (565764:566490)
Change log:ffaf1e2ba6..ef538e3112Full diff:ffaf1e2ba6..ef538e3112Roll chromium third_party fb3dc2a0aa..cbc2a20101 Change log:fb3dc2a0aa..cbc2a20101Changed dependencies: * src/base:2743076235..02a6c4cdd0* src/build:459adce3eb..3c4d6b6d24* src/ios:71b35d6ee6..0c6d3816a0* src/testing:f624b1f4b7..e0597e0b5d* src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/eca23c365a..fdacd1639e * src/third_party/depot_tools:e05f18d477..e09b6845cf* src/third_party/freetype/src:0589f6e6ee..8f1ed54877* src/third_party/googletest/src:145d05750b..9077ec7efe* src/tools:76e5757c8f..c7862334ceDEPS diff:ffaf1e2ba6..ef538e3112/DEPS Clang version changed 332838:334100 Details:ffaf1e2ba6..ef538e3112/tools/clang/scripts/update.py TBR=buildbot@webrtc.org, BUG=None CQ_INCLUDE_TRYBOTS=master.internal.tryserver.corp.webrtc:linux_internal NO_AUTOIMPORT_DEPS_CHECK=true Change-Id: Iac45f00b35127f886b32aac8b79578fbe528fb00 Reviewed-on: https://webrtc-review.googlesource.com/83220 Reviewed-by: WebRTC Buildbot <buildbot@webrtc.org> Commit-Queue: WebRTC Buildbot <buildbot@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23585}
This commit is contained in:
22
DEPS
22
DEPS
@ -10,7 +10,7 @@ vars = {
|
||||
'checkout_configuration': 'default',
|
||||
'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"',
|
||||
'webrtc_git': 'https://webrtc.googlesource.com',
|
||||
'chromium_revision': 'ffaf1e2ba66b521c4afe3af865a3f044ae1bff00',
|
||||
'chromium_revision': 'ef538e3112d34f22bf36c50f71ec9c3108bda689',
|
||||
'boringssl_git': 'https://boringssl.googlesource.com',
|
||||
# Three lines of non-changing comments so that
|
||||
# the commit queue can handle CLs rolling swarming_client
|
||||
@ -27,7 +27,7 @@ vars = {
|
||||
# Three lines of non-changing comments so that
|
||||
# the commit queue can handle CLs rolling catapult
|
||||
# and whatever else without interference from each other.
|
||||
'catapult_revision': 'eca23c365a07863178be2918fb2c97b23fa97381',
|
||||
'catapult_revision': 'fdacd1639e2adc4631fc1d57f68e4d3715cef5ba',
|
||||
# Three lines of non-changing comments so that
|
||||
# the commit queue can handle CLs rolling libFuzzer
|
||||
# and whatever else without interference from each other.
|
||||
@ -35,7 +35,7 @@ vars = {
|
||||
# Three lines of non-changing comments so that
|
||||
# the commit queue can handle CLs rolling freetype
|
||||
# and whatever else without interference from each other.
|
||||
'freetype_revision': '0589f6e6ee6e9bfe0c7139374fc8812e849e7bf7',
|
||||
'freetype_revision': '8f1ed54877ffab4fc2cf2be329446c748a885842',
|
||||
# Three lines of non-changing comments so that
|
||||
# the commit queue can handle CLs rolling HarfBuzz
|
||||
# and whatever else without interference from each other.
|
||||
@ -43,15 +43,15 @@ vars = {
|
||||
# Three lines of non-changing comments so that
|
||||
# the commit queue can handle CLs rolling Chromium third_party
|
||||
# and whatever else without interference from each other.
|
||||
'chromium_third_party_revision': 'fb3dc2a0aa643c64ee5ee4c3ba13ed40443b68b7',
|
||||
'chromium_third_party_revision': 'cbc2a20101b62439635a362571b6ea68d542054c',
|
||||
}
|
||||
deps = {
|
||||
# TODO(kjellander): Move this to be Android-only once the libevent dependency
|
||||
# in base/third_party/libevent is solved.
|
||||
'src/base':
|
||||
Var('chromium_git') + '/chromium/src/base' + '@' + '27430762358b568f216d88d8af9dd83c1bddcd79',
|
||||
Var('chromium_git') + '/chromium/src/base' + '@' + '02a6c4cdd034f8d80847508e82e1391f01033017',
|
||||
'src/build':
|
||||
Var('chromium_git') + '/chromium/src/build' + '@' + '459adce3ebfbc114c2d637ebd44c886eac58d441',
|
||||
Var('chromium_git') + '/chromium/src/build' + '@' + '3c4d6b6d24da4fda0c55f2cff4dd9f542fbfdd43',
|
||||
'src/buildtools':
|
||||
Var('chromium_git') + '/chromium/buildtools.git' + '@' + '6f4dae280c6a542acacd8db281decc5c0b2a9823',
|
||||
# Gradle 4.3-rc4. Used for testing Android Studio project generation for WebRTC.
|
||||
@ -61,11 +61,11 @@ deps = {
|
||||
'condition': 'checkout_android',
|
||||
},
|
||||
'src/ios': {
|
||||
'url': Var('chromium_git') + '/chromium/src/ios' + '@' + '71b35d6ee6df3985bb870990daa8851f60ce4d2e',
|
||||
'url': Var('chromium_git') + '/chromium/src/ios' + '@' + '0c6d3816a06717b42104f4d59f5b525c95e8ac97',
|
||||
'condition': 'checkout_ios',
|
||||
},
|
||||
'src/testing':
|
||||
Var('chromium_git') + '/chromium/src/testing' + '@' + 'f624b1f4b7e728d3816e5fcf7f51f98e6f7e7f54',
|
||||
Var('chromium_git') + '/chromium/src/testing' + '@' + 'e0597e0b5d0d6d2b146bf1738347ca6bcb6613cd',
|
||||
# This entry is used for chromium third_party rolling into webrtc third_party only.
|
||||
'src/third_party_chromium': {
|
||||
'url': Var('chromium_git') + '/chromium/src/third_party' + '@' + Var('chromium_third_party_revision'),
|
||||
@ -94,7 +94,7 @@ deps = {
|
||||
'src/third_party/colorama/src':
|
||||
Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',
|
||||
'src/third_party/depot_tools':
|
||||
Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e05f18d47735f3bc3f5808d0ce38a452b82d95e8',
|
||||
Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e09b6845cf720ac429578b209267cb6dd1c901da',
|
||||
'src/third_party/errorprone/lib': {
|
||||
'url': Var('chromium_git') + '/chromium/third_party/errorprone.git' + '@' + '980d49e839aa4984015efed34b0134d4b2c9b6d7',
|
||||
'condition': 'checkout_android',
|
||||
@ -113,7 +113,7 @@ deps = {
|
||||
'src/third_party/gtest-parallel':
|
||||
Var('chromium_git') + '/external/github.com/google/gtest-parallel' + '@' + 'cb3514a0858be0f66281d892e2242d1073fd75fe',
|
||||
'src/third_party/googletest/src':
|
||||
Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '145d05750b15324899473340c8dd5af50d125d33',
|
||||
Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '9077ec7efe5b652468ab051e93c67589d5cb8f85',
|
||||
'src/third_party/icu': {
|
||||
'url': Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'f61e46dbee9d539a32551493e3bcc1dea92f83ec',
|
||||
},
|
||||
@ -185,7 +185,7 @@ deps = {
|
||||
'src/third_party/yasm/source/patched-yasm':
|
||||
Var('chromium_git') + '/chromium/deps/yasm/patched-yasm.git' + '@' + 'b98114e18d8b9b84586b10d24353ab8616d4c5fc',
|
||||
'src/tools':
|
||||
Var('chromium_git') + '/chromium/src/tools' + '@' + '76e5757c8fdee7192701a19b6a807a5d9b5c8fc4',
|
||||
Var('chromium_git') + '/chromium/src/tools' + '@' + 'c7862334ce4a9647355f622299799ef0554daf6f',
|
||||
'src/tools/gyp':
|
||||
Var('chromium_git') + '/external/gyp.git' + '@' + 'd61a9397e668fa9843c4aa7da9e79460fe590bfb',
|
||||
'src/tools/swarming_client':
|
||||
|
||||
2
third_party/abseil-cpp/README.chromium
vendored
2
third_party/abseil-cpp/README.chromium
vendored
@ -4,7 +4,7 @@ URL: https://github.com/abseil/abseil-cpp
|
||||
License: Apache 2.0
|
||||
License File: LICENSE
|
||||
Version: 0
|
||||
Revision: 014f02a3eca93ef88163c3b408c86998ecf6572c
|
||||
Revision: 92020a042c0cd46979db9f6f0cb32783dc07765e
|
||||
Security Critical: yes
|
||||
|
||||
Description:
|
||||
|
||||
12
third_party/abseil-cpp/WORKSPACE
vendored
12
third_party/abseil-cpp/WORKSPACE
vendored
@ -13,20 +13,20 @@ http_archive(
|
||||
# GoogleTest/GoogleMock framework. Used by most unit-tests.
|
||||
http_archive(
|
||||
name = "com_google_googletest",
|
||||
urls = ["https://github.com/google/googletest/archive/master.zip"],
|
||||
strip_prefix = "googletest-master",
|
||||
urls = ["https://github.com/google/googletest/archive/4e4df226fc197c0dda6e37f5c8c3845ca1e73a49.zip"],
|
||||
strip_prefix = "googletest-4e4df226fc197c0dda6e37f5c8c3845ca1e73a49",
|
||||
)
|
||||
|
||||
# Google benchmark.
|
||||
http_archive(
|
||||
name = "com_github_google_benchmark",
|
||||
urls = ["https://github.com/google/benchmark/archive/master.zip"],
|
||||
strip_prefix = "benchmark-master",
|
||||
urls = ["https://github.com/google/benchmark/archive/16703ff83c1ae6d53e5155df3bb3ab0bc96083be.zip"],
|
||||
strip_prefix = "benchmark-16703ff83c1ae6d53e5155df3bb3ab0bc96083be",
|
||||
)
|
||||
|
||||
# RE2 regular-expression framework. Used by some unit-tests.
|
||||
http_archive(
|
||||
name = "com_googlesource_code_re2",
|
||||
urls = ["https://github.com/google/re2/archive/master.zip"],
|
||||
strip_prefix = "re2-master",
|
||||
urls = ["https://github.com/google/re2/archive/6cf8ccd82dbaab2668e9b13596c68183c9ecd13f.zip"],
|
||||
strip_prefix = "re2-6cf8ccd82dbaab2668e9b13596c68183c9ecd13f",
|
||||
)
|
||||
|
||||
@ -49,7 +49,7 @@ cc_test(
|
||||
deps = [
|
||||
":algorithm",
|
||||
"//absl/base:core_headers",
|
||||
"@com_github_google_benchmark//:benchmark",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@ -124,5 +124,3 @@ BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, EightBits)
|
||||
->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
|
||||
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
7
third_party/abseil-cpp/absl/base/BUILD.bazel
vendored
7
third_party/abseil-cpp/absl/base/BUILD.bazel
vendored
@ -371,6 +371,11 @@ cc_test(
|
||||
size = "small",
|
||||
srcs = ["internal/sysinfo_test.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = [
|
||||
"no_test_android_arm",
|
||||
"no_test_android_arm64",
|
||||
"no_test_android_x86",
|
||||
],
|
||||
deps = [
|
||||
":base",
|
||||
"//absl/synchronization",
|
||||
@ -416,6 +421,6 @@ cc_test(
|
||||
deps = [
|
||||
":base",
|
||||
"//absl/synchronization",
|
||||
"@com_github_google_benchmark//:benchmark",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
@ -168,8 +168,58 @@ TEST(ThrowingValueTest, ThrowingCompoundAssignmentOps) {
|
||||
TEST(ThrowingValueTest, ThrowingStreamOps) {
|
||||
ThrowingValue<> bomb;
|
||||
|
||||
TestOp([&]() { std::cin >> bomb; });
|
||||
TestOp([&]() { std::cout << bomb; });
|
||||
TestOp([&]() {
|
||||
std::istringstream stream;
|
||||
stream >> bomb;
|
||||
});
|
||||
TestOp([&]() {
|
||||
std::stringstream stream;
|
||||
stream << bomb;
|
||||
});
|
||||
}
|
||||
|
||||
// Tests the operator<< of ThrowingValue by forcing ConstructorTracker to emit
|
||||
// a nonfatal failure that contains the std::string representation of the Thrower
|
||||
TEST(ThrowingValueTest, StreamOpsOutput) {
|
||||
using ::testing::TypeSpec;
|
||||
exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown);
|
||||
|
||||
// Test default spec list (kEverythingThrows)
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{
|
||||
using Thrower = ThrowingValue<TypeSpec{}>;
|
||||
auto thrower = Thrower(123);
|
||||
thrower.~Thrower();
|
||||
},
|
||||
"ThrowingValue<>(123)");
|
||||
|
||||
// Test with one item in spec list (kNoThrowCopy)
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{
|
||||
using Thrower = ThrowingValue<TypeSpec::kNoThrowCopy>;
|
||||
auto thrower = Thrower(234);
|
||||
thrower.~Thrower();
|
||||
},
|
||||
"ThrowingValue<kNoThrowCopy>(234)");
|
||||
|
||||
// Test with multiple items in spec list (kNoThrowMove, kNoThrowNew)
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{
|
||||
using Thrower =
|
||||
ThrowingValue<TypeSpec::kNoThrowMove | TypeSpec::kNoThrowNew>;
|
||||
auto thrower = Thrower(345);
|
||||
thrower.~Thrower();
|
||||
},
|
||||
"ThrowingValue<kNoThrowMove | kNoThrowNew>(345)");
|
||||
|
||||
// Test with all items in spec list (kNoThrowCopy, kNoThrowMove, kNoThrowNew)
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{
|
||||
using Thrower = ThrowingValue<static_cast<TypeSpec>(-1)>;
|
||||
auto thrower = Thrower(456);
|
||||
thrower.~Thrower();
|
||||
},
|
||||
"ThrowingValue<kNoThrowCopy | kNoThrowMove | kNoThrowNew>(456)");
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
@ -653,20 +703,20 @@ struct BasicGuaranteeWithExtraInvariants : public NonNegative {
|
||||
};
|
||||
constexpr int BasicGuaranteeWithExtraInvariants::kExceptionSentinel;
|
||||
|
||||
TEST(ExceptionCheckTest, BasicGuaranteeWithInvariants) {
|
||||
TEST(ExceptionCheckTest, BasicGuaranteeWithExtraInvariants) {
|
||||
auto tester_with_val =
|
||||
tester.WithInitialValue(BasicGuaranteeWithExtraInvariants{});
|
||||
EXPECT_TRUE(tester_with_val.Test());
|
||||
EXPECT_TRUE(
|
||||
tester_with_val
|
||||
.WithInvariants([](BasicGuaranteeWithExtraInvariants* w) {
|
||||
if (w->i == BasicGuaranteeWithExtraInvariants::kExceptionSentinel) {
|
||||
.WithInvariants([](BasicGuaranteeWithExtraInvariants* o) {
|
||||
if (o->i == BasicGuaranteeWithExtraInvariants::kExceptionSentinel) {
|
||||
return testing::AssertionSuccess();
|
||||
}
|
||||
return testing::AssertionFailure()
|
||||
<< "i should be "
|
||||
<< BasicGuaranteeWithExtraInvariants::kExceptionSentinel
|
||||
<< ", but is " << w->i;
|
||||
<< ", but is " << o->i;
|
||||
})
|
||||
.Test());
|
||||
}
|
||||
@ -846,29 +896,28 @@ TEST(ConstructorTrackerTest, NotDestroyedAfter) {
|
||||
new (&storage) Tracked;
|
||||
},
|
||||
"not destroyed");
|
||||
|
||||
// Manual destruction of the Tracked instance is not required because
|
||||
// ~ConstructorTracker() handles that automatically when a leak is found
|
||||
}
|
||||
|
||||
TEST(ConstructorTrackerTest, DestroyedTwice) {
|
||||
exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown);
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{
|
||||
Tracked t;
|
||||
t.~Tracked();
|
||||
},
|
||||
"destroyed improperly");
|
||||
"re-destroyed");
|
||||
}
|
||||
|
||||
TEST(ConstructorTrackerTest, ConstructedTwice) {
|
||||
exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown);
|
||||
absl::aligned_storage_t<sizeof(Tracked), alignof(Tracked)> storage;
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{
|
||||
new (&storage) Tracked;
|
||||
new (&storage) Tracked;
|
||||
reinterpret_cast<Tracked*>(&storage)->~Tracked();
|
||||
},
|
||||
"re-constructed");
|
||||
reinterpret_cast<Tracked*>(&storage)->~Tracked();
|
||||
}
|
||||
|
||||
TEST(ThrowingValueTraitsTest, RelationalOperators) {
|
||||
|
||||
@ -21,16 +21,14 @@ namespace testing {
|
||||
|
||||
exceptions_internal::NoThrowTag nothrow_ctor;
|
||||
|
||||
bool nothrow_guarantee(const void*) {
|
||||
return ::testing::AssertionFailure()
|
||||
<< "Exception thrown violating NoThrow Guarantee";
|
||||
}
|
||||
exceptions_internal::StrongGuaranteeTagType strong_guarantee;
|
||||
|
||||
namespace exceptions_internal {
|
||||
|
||||
int countdown = -1;
|
||||
|
||||
ConstructorTracker* ConstructorTracker::current_tracker_instance_ = nullptr;
|
||||
|
||||
void MaybeThrow(absl::string_view msg, bool throw_bad_alloc) {
|
||||
if (countdown-- == 0) {
|
||||
if (throw_bad_alloc) throw TestBadAllocException(msg);
|
||||
@ -43,6 +41,31 @@ testing::AssertionResult FailureMessage(const TestException& e,
|
||||
return testing::AssertionFailure() << "Exception thrown from " << e.what();
|
||||
}
|
||||
|
||||
std::string GetSpecString(TypeSpec spec) {
|
||||
std::string out;
|
||||
absl::string_view sep;
|
||||
const auto append = [&](absl::string_view s) {
|
||||
absl::StrAppend(&out, sep, s);
|
||||
sep = " | ";
|
||||
};
|
||||
if (static_cast<bool>(TypeSpec::kNoThrowCopy & spec)) {
|
||||
append("kNoThrowCopy");
|
||||
}
|
||||
if (static_cast<bool>(TypeSpec::kNoThrowMove & spec)) {
|
||||
append("kNoThrowMove");
|
||||
}
|
||||
if (static_cast<bool>(TypeSpec::kNoThrowNew & spec)) {
|
||||
append("kNoThrowNew");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string GetSpecString(AllocSpec spec) {
|
||||
return static_cast<bool>(AllocSpec::kNoThrowAllocate & spec)
|
||||
? "kNoThrowAllocate"
|
||||
: "";
|
||||
}
|
||||
|
||||
} // namespace exceptions_internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
@ -62,6 +62,9 @@ constexpr AllocSpec operator&(AllocSpec a, AllocSpec b) {
|
||||
|
||||
namespace exceptions_internal {
|
||||
|
||||
std::string GetSpecString(TypeSpec);
|
||||
std::string GetSpecString(AllocSpec);
|
||||
|
||||
struct NoThrowTag {};
|
||||
struct StrongGuaranteeTagType {};
|
||||
|
||||
@ -101,36 +104,9 @@ void MaybeThrow(absl::string_view msg, bool throw_bad_alloc = false);
|
||||
testing::AssertionResult FailureMessage(const TestException& e,
|
||||
int countdown) noexcept;
|
||||
|
||||
class ConstructorTracker;
|
||||
|
||||
class TrackedObject {
|
||||
public:
|
||||
TrackedObject(const TrackedObject&) = delete;
|
||||
TrackedObject(TrackedObject&&) = delete;
|
||||
|
||||
protected:
|
||||
explicit TrackedObject(const char* child_ctor) {
|
||||
if (!GetInstanceMap().emplace(this, child_ctor).second) {
|
||||
ADD_FAILURE() << "Object at address " << static_cast<void*>(this)
|
||||
<< " re-constructed in ctor " << child_ctor;
|
||||
}
|
||||
}
|
||||
|
||||
~TrackedObject() noexcept {
|
||||
if (GetInstanceMap().erase(this) == 0) {
|
||||
ADD_FAILURE() << "Object at address " << static_cast<void*>(this)
|
||||
<< " destroyed improperly";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
using InstanceMap = std::unordered_map<TrackedObject*, absl::string_view>;
|
||||
static InstanceMap& GetInstanceMap() {
|
||||
static auto* instance_map = new InstanceMap();
|
||||
return *instance_map;
|
||||
}
|
||||
|
||||
friend class ConstructorTracker;
|
||||
struct TrackedAddress {
|
||||
bool is_alive;
|
||||
std::string description;
|
||||
};
|
||||
|
||||
// Inspects the constructions and destructions of anything inheriting from
|
||||
@ -138,33 +114,86 @@ class TrackedObject {
|
||||
// ConstructorTracker will destroy everything left over in its destructor.
|
||||
class ConstructorTracker {
|
||||
public:
|
||||
explicit ConstructorTracker(int c)
|
||||
: init_count_(c), init_instances_(TrackedObject::GetInstanceMap()) {}
|
||||
explicit ConstructorTracker(int count) : countdown_(count) {
|
||||
assert(current_tracker_instance_ == nullptr);
|
||||
current_tracker_instance_ = this;
|
||||
}
|
||||
|
||||
~ConstructorTracker() {
|
||||
auto& cur_instances = TrackedObject::GetInstanceMap();
|
||||
for (auto it = cur_instances.begin(); it != cur_instances.end();) {
|
||||
if (init_instances_.count(it->first) == 0) {
|
||||
ADD_FAILURE() << "Object at address " << static_cast<void*>(it->first)
|
||||
<< " constructed from " << it->second
|
||||
<< " where the exception countdown was set to "
|
||||
<< init_count_ << " was not destroyed";
|
||||
// Erasing an item inside an unordered_map invalidates the existing
|
||||
// iterator. A new one is returned for iteration to continue.
|
||||
it = cur_instances.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
assert(current_tracker_instance_ == this);
|
||||
current_tracker_instance_ = nullptr;
|
||||
|
||||
for (auto& it : address_map_) {
|
||||
void* address = it.first;
|
||||
TrackedAddress& tracked_address = it.second;
|
||||
if (tracked_address.is_alive) {
|
||||
ADD_FAILURE() << "Object at address " << address
|
||||
<< " with countdown of " << countdown_
|
||||
<< " was not destroyed [" << tracked_address.description
|
||||
<< "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ObjectConstructed(void* address, std::string description) {
|
||||
if (!CurrentlyTracking()) return;
|
||||
|
||||
TrackedAddress& tracked_address =
|
||||
current_tracker_instance_->address_map_[address];
|
||||
if (tracked_address.is_alive) {
|
||||
ADD_FAILURE() << "Object at address " << address << " with countdown of "
|
||||
<< current_tracker_instance_->countdown_
|
||||
<< " was re-constructed. Previously: ["
|
||||
<< tracked_address.description << "] Now: [" << description
|
||||
<< "]";
|
||||
}
|
||||
tracked_address = {true, std::move(description)};
|
||||
}
|
||||
|
||||
static void ObjectDestructed(void* address) {
|
||||
if (!CurrentlyTracking()) return;
|
||||
|
||||
auto it = current_tracker_instance_->address_map_.find(address);
|
||||
// Not tracked. Ignore.
|
||||
if (it == current_tracker_instance_->address_map_.end()) return;
|
||||
|
||||
TrackedAddress& tracked_address = it->second;
|
||||
if (!tracked_address.is_alive) {
|
||||
ADD_FAILURE() << "Object at address " << address << " with countdown of "
|
||||
<< current_tracker_instance_->countdown_
|
||||
<< " was re-destroyed or created prior to construction "
|
||||
<< "tracking [" << tracked_address.description << "]";
|
||||
}
|
||||
tracked_address.is_alive = false;
|
||||
}
|
||||
|
||||
private:
|
||||
int init_count_;
|
||||
TrackedObject::InstanceMap init_instances_;
|
||||
static bool CurrentlyTracking() {
|
||||
return current_tracker_instance_ != nullptr;
|
||||
}
|
||||
|
||||
std::unordered_map<void*, TrackedAddress> address_map_;
|
||||
int countdown_;
|
||||
|
||||
static ConstructorTracker* current_tracker_instance_;
|
||||
};
|
||||
|
||||
class TrackedObject {
|
||||
public:
|
||||
TrackedObject(const TrackedObject&) = delete;
|
||||
TrackedObject(TrackedObject&&) = delete;
|
||||
|
||||
protected:
|
||||
explicit TrackedObject(std::string description) {
|
||||
ConstructorTracker::ObjectConstructed(this, std::move(description));
|
||||
}
|
||||
|
||||
~TrackedObject() noexcept { ConstructorTracker::ObjectDestructed(this); }
|
||||
};
|
||||
|
||||
template <typename Factory, typename Operation, typename Invariant>
|
||||
absl::optional<testing::AssertionResult> TestSingleInvariantAtCountdownImpl(
|
||||
const Factory& factory, Operation operation, int count,
|
||||
const Factory& factory, const Operation& operation, int count,
|
||||
const Invariant& invariant) {
|
||||
auto t_ptr = factory();
|
||||
absl::optional<testing::AssertionResult> current_res;
|
||||
@ -229,7 +258,6 @@ inline absl::optional<testing::AssertionResult> TestAllInvariantsAtCountdown(
|
||||
|
||||
extern exceptions_internal::NoThrowTag nothrow_ctor;
|
||||
|
||||
bool nothrow_guarantee(const void*);
|
||||
extern exceptions_internal::StrongGuaranteeTagType strong_guarantee;
|
||||
|
||||
// A test class which is convertible to bool. The conversion can be
|
||||
@ -283,17 +311,18 @@ class ThrowingValue : private exceptions_internal::TrackedObject {
|
||||
return static_cast<bool>(Spec & spec);
|
||||
}
|
||||
|
||||
static constexpr int kDefaultValue = 0;
|
||||
static constexpr int kBadValue = 938550620;
|
||||
|
||||
public:
|
||||
ThrowingValue() : TrackedObject(ABSL_PRETTY_FUNCTION) {
|
||||
ThrowingValue() : TrackedObject(GetInstanceString(kDefaultValue)) {
|
||||
exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
|
||||
dummy_ = 0;
|
||||
dummy_ = kDefaultValue;
|
||||
}
|
||||
|
||||
ThrowingValue(const ThrowingValue& other) noexcept(
|
||||
IsSpecified(TypeSpec::kNoThrowCopy))
|
||||
: TrackedObject(ABSL_PRETTY_FUNCTION) {
|
||||
: TrackedObject(GetInstanceString(other.dummy_)) {
|
||||
if (!IsSpecified(TypeSpec::kNoThrowCopy)) {
|
||||
exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
|
||||
}
|
||||
@ -302,20 +331,20 @@ class ThrowingValue : private exceptions_internal::TrackedObject {
|
||||
|
||||
ThrowingValue(ThrowingValue&& other) noexcept(
|
||||
IsSpecified(TypeSpec::kNoThrowMove))
|
||||
: TrackedObject(ABSL_PRETTY_FUNCTION) {
|
||||
: TrackedObject(GetInstanceString(other.dummy_)) {
|
||||
if (!IsSpecified(TypeSpec::kNoThrowMove)) {
|
||||
exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
|
||||
}
|
||||
dummy_ = other.dummy_;
|
||||
}
|
||||
|
||||
explicit ThrowingValue(int i) : TrackedObject(ABSL_PRETTY_FUNCTION) {
|
||||
explicit ThrowingValue(int i) : TrackedObject(GetInstanceString(i)) {
|
||||
exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
|
||||
dummy_ = i;
|
||||
}
|
||||
|
||||
ThrowingValue(int i, exceptions_internal::NoThrowTag) noexcept
|
||||
: TrackedObject(ABSL_PRETTY_FUNCTION), dummy_(i) {}
|
||||
: TrackedObject(GetInstanceString(i)), dummy_(i) {}
|
||||
|
||||
// absl expects nothrow destructors
|
||||
~ThrowingValue() noexcept = default;
|
||||
@ -548,9 +577,9 @@ class ThrowingValue : private exceptions_internal::TrackedObject {
|
||||
void operator&() const = delete; // NOLINT(runtime/operator)
|
||||
|
||||
// Stream operators
|
||||
friend std::ostream& operator<<(std::ostream& os, const ThrowingValue&) {
|
||||
friend std::ostream& operator<<(std::ostream& os, const ThrowingValue& tv) {
|
||||
exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
|
||||
return os;
|
||||
return os << GetInstanceString(tv.dummy_);
|
||||
}
|
||||
|
||||
friend std::istream& operator>>(std::istream& is, const ThrowingValue&) {
|
||||
@ -606,6 +635,12 @@ class ThrowingValue : private exceptions_internal::TrackedObject {
|
||||
const int& Get() const noexcept { return dummy_; }
|
||||
|
||||
private:
|
||||
static std::string GetInstanceString(int dummy) {
|
||||
return absl::StrCat("ThrowingValue<",
|
||||
exceptions_internal::GetSpecString(Spec), ">(", dummy,
|
||||
")");
|
||||
}
|
||||
|
||||
int dummy_;
|
||||
};
|
||||
// While not having to do with exceptions, explicitly delete comma operator, to
|
||||
@ -658,26 +693,30 @@ class ThrowingAllocator : private exceptions_internal::TrackedObject {
|
||||
using propagate_on_container_swap = std::true_type;
|
||||
using is_always_equal = std::false_type;
|
||||
|
||||
ThrowingAllocator() : TrackedObject(ABSL_PRETTY_FUNCTION) {
|
||||
ThrowingAllocator() : TrackedObject(GetInstanceString(next_id_)) {
|
||||
exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
|
||||
dummy_ = std::make_shared<const int>(next_id_++);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
ThrowingAllocator(const ThrowingAllocator<U, Spec>& other) noexcept // NOLINT
|
||||
: TrackedObject(ABSL_PRETTY_FUNCTION), dummy_(other.State()) {}
|
||||
: TrackedObject(GetInstanceString(*other.State())),
|
||||
dummy_(other.State()) {}
|
||||
|
||||
// According to C++11 standard [17.6.3.5], Table 28, the move/copy ctors of
|
||||
// allocator shall not exit via an exception, thus they are marked noexcept.
|
||||
ThrowingAllocator(const ThrowingAllocator& other) noexcept
|
||||
: TrackedObject(ABSL_PRETTY_FUNCTION), dummy_(other.State()) {}
|
||||
: TrackedObject(GetInstanceString(*other.State())),
|
||||
dummy_(other.State()) {}
|
||||
|
||||
template <typename U>
|
||||
ThrowingAllocator(ThrowingAllocator<U, Spec>&& other) noexcept // NOLINT
|
||||
: TrackedObject(ABSL_PRETTY_FUNCTION), dummy_(std::move(other.State())) {}
|
||||
: TrackedObject(GetInstanceString(*other.State())),
|
||||
dummy_(std::move(other.State())) {}
|
||||
|
||||
ThrowingAllocator(ThrowingAllocator&& other) noexcept
|
||||
: TrackedObject(ABSL_PRETTY_FUNCTION), dummy_(std::move(other.State())) {}
|
||||
: TrackedObject(GetInstanceString(*other.State())),
|
||||
dummy_(std::move(other.State())) {}
|
||||
|
||||
~ThrowingAllocator() noexcept = default;
|
||||
|
||||
@ -758,6 +797,12 @@ class ThrowingAllocator : private exceptions_internal::TrackedObject {
|
||||
friend class ThrowingAllocator;
|
||||
|
||||
private:
|
||||
static std::string GetInstanceString(int dummy) {
|
||||
return absl::StrCat("ThrowingAllocator<",
|
||||
exceptions_internal::GetSpecString(Spec), ">(", dummy,
|
||||
")");
|
||||
}
|
||||
|
||||
const std::shared_ptr<const int>& State() const { return dummy_; }
|
||||
std::shared_ptr<const int>& State() { return dummy_; }
|
||||
|
||||
@ -801,6 +846,29 @@ void TestThrowingCtor(Args&&... args) {
|
||||
}
|
||||
}
|
||||
|
||||
// Tests the nothrow guarantee of the provided nullary operation. If the an
|
||||
// exception is thrown, the result will be AssertionFailure(). Otherwise, it
|
||||
// will be AssertionSuccess().
|
||||
template <typename Operation>
|
||||
testing::AssertionResult TestNothrowOp(const Operation& operation) {
|
||||
struct Cleanup {
|
||||
Cleanup() { exceptions_internal::SetCountdown(); }
|
||||
~Cleanup() { exceptions_internal::UnsetCountdown(); }
|
||||
} c;
|
||||
try {
|
||||
operation();
|
||||
return testing::AssertionSuccess();
|
||||
} catch (exceptions_internal::TestException) {
|
||||
return testing::AssertionFailure()
|
||||
<< "TestException thrown during call to operation() when nothrow "
|
||||
"guarantee was expected.";
|
||||
} catch (...) {
|
||||
return testing::AssertionFailure()
|
||||
<< "Unknown exception thrown during call to operation() when "
|
||||
"nothrow guarantee was expected.";
|
||||
}
|
||||
}
|
||||
|
||||
namespace exceptions_internal {
|
||||
|
||||
// Dummy struct for ExceptionSafetyTester<> partial state.
|
||||
|
||||
@ -28,8 +28,12 @@
|
||||
#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \
|
||||
EXPECT_THROW(expr, exception_t)
|
||||
|
||||
#elif defined(__ANDROID__)
|
||||
// Android asserts do not log anywhere that gtest can currently inspect.
|
||||
// So we expect exit, but cannot match the message.
|
||||
#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \
|
||||
EXPECT_DEATH(expr, ".*")
|
||||
#else
|
||||
|
||||
#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \
|
||||
EXPECT_DEATH(expr, text)
|
||||
|
||||
|
||||
@ -23,9 +23,7 @@ namespace base_internal {
|
||||
// Arbitrary value with high bits set. Xor'ing with it is unlikely
|
||||
// to map one valid pointer to another valid pointer.
|
||||
constexpr uintptr_t HideMask() {
|
||||
static_assert(sizeof(uintptr_t) == 4 || sizeof(uintptr_t) == 8,
|
||||
"uintptr_t must be 32 or 64 bits");
|
||||
return sizeof(uintptr_t) == 8 ? 0xF03A5F7BF03A5F7BULL : 0xF03A5F7BUL;
|
||||
return (uintptr_t{0xF03A5F7BU} << (sizeof(uintptr_t) - 4) * 8) | 0xF03A5F7BU;
|
||||
}
|
||||
|
||||
// Hide a pointer from the leak checker. For internal use only.
|
||||
|
||||
@ -18,10 +18,12 @@
|
||||
#include <atomic>
|
||||
#include <limits>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/internal/atomic_hook.h"
|
||||
#include "absl/base/internal/cycleclock.h"
|
||||
#include "absl/base/internal/spinlock_wait.h"
|
||||
#include "absl/base/internal/sysinfo.h" /* For NumCPUs() */
|
||||
#include "absl/base/call_once.h"
|
||||
|
||||
// Description of lock-word:
|
||||
// 31..00: [............................3][2][1][0]
|
||||
@ -54,30 +56,10 @@
|
||||
namespace absl {
|
||||
namespace base_internal {
|
||||
|
||||
static int adaptive_spin_count = 0;
|
||||
|
||||
namespace {
|
||||
struct SpinLock_InitHelper {
|
||||
SpinLock_InitHelper() {
|
||||
// On multi-cpu machines, spin for longer before yielding
|
||||
// the processor or sleeping. Reduces idle time significantly.
|
||||
if (base_internal::NumCPUs() > 1) {
|
||||
adaptive_spin_count = 1000;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Hook into global constructor execution:
|
||||
// We do not do adaptive spinning before that,
|
||||
// but nothing lock-intensive should be going on at that time.
|
||||
static SpinLock_InitHelper init_helper;
|
||||
|
||||
ABSL_CONST_INIT static base_internal::AtomicHook<void (*)(const void *lock,
|
||||
int64_t wait_cycles)>
|
||||
submit_profile_data;
|
||||
|
||||
} // namespace
|
||||
|
||||
void RegisterSpinLockProfiler(void (*fn)(const void *contendedlock,
|
||||
int64_t wait_cycles)) {
|
||||
submit_profile_data.Store(fn);
|
||||
@ -120,6 +102,14 @@ void SpinLock::InitLinkerInitializedAndCooperative() {
|
||||
// from the lock is returned from the method.
|
||||
uint32_t SpinLock::SpinLoop(int64_t initial_wait_timestamp,
|
||||
uint32_t *wait_cycles) {
|
||||
// We are already in the slow path of SpinLock, initialize the
|
||||
// adaptive_spin_count here.
|
||||
ABSL_CONST_INIT static absl::once_flag init_adaptive_spin_count;
|
||||
ABSL_CONST_INIT static int adaptive_spin_count = 0;
|
||||
base_internal::LowLevelCallOnce(&init_adaptive_spin_count, []() {
|
||||
adaptive_spin_count = base_internal::NumCPUs() > 1 ? 1000 : 1;
|
||||
});
|
||||
|
||||
int c = adaptive_spin_count;
|
||||
uint32_t lock_value;
|
||||
do {
|
||||
|
||||
@ -36,5 +36,3 @@ void BM_UnsafeCurrentThreadIdentity(benchmark::State& state) {
|
||||
BENCHMARK(BM_UnsafeCurrentThreadIdentity);
|
||||
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
@ -158,8 +158,8 @@
|
||||
#define ABSL_PREDICT_FALSE(x) (__builtin_expect(x, 0))
|
||||
#define ABSL_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
|
||||
#else
|
||||
#define ABSL_PREDICT_FALSE(x) x
|
||||
#define ABSL_PREDICT_TRUE(x) x
|
||||
#define ABSL_PREDICT_FALSE(x) (x)
|
||||
#define ABSL_PREDICT_TRUE(x) (x)
|
||||
#endif
|
||||
|
||||
#endif // ABSL_BASE_OPTIMIZATION_H_
|
||||
|
||||
@ -69,7 +69,7 @@ cc_test(
|
||||
tags = ["benchmark"],
|
||||
deps = [
|
||||
":fixed_array",
|
||||
"@com_github_google_benchmark//:benchmark",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
@ -126,7 +126,7 @@ cc_test(
|
||||
":inlined_vector",
|
||||
"//absl/base",
|
||||
"//absl/strings",
|
||||
"@com_github_google_benchmark//:benchmark",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@ -64,5 +64,3 @@ BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 256)->Range(0, 1 << 16);
|
||||
BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 65536)->Range(0, 1 << 16);
|
||||
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
@ -372,5 +372,3 @@ void BM_StdVectorEmpty(benchmark::State& state) {
|
||||
BENCHMARK(BM_StdVectorEmpty);
|
||||
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
4
third_party/abseil-cpp/absl/memory/memory.h
vendored
4
third_party/abseil-cpp/absl/memory/memory.h
vendored
@ -179,9 +179,9 @@ typename memory_internal::MakeUniqueResult<T>::invalid make_unique(
|
||||
// useful within templates that need to handle a complement of raw pointers,
|
||||
// `std::nullptr_t`, and smart pointers.
|
||||
template <typename T>
|
||||
auto RawPtr(T&& ptr) -> decltype(&*ptr) {
|
||||
auto RawPtr(T&& ptr) -> decltype(std::addressof(*ptr)) {
|
||||
// ptr is a forwarding reference to support Ts with non-const operators.
|
||||
return (ptr != nullptr) ? &*ptr : nullptr;
|
||||
return (ptr != nullptr) ? std::addressof(*ptr) : nullptr;
|
||||
}
|
||||
inline std::nullptr_t RawPtr(std::nullptr_t) { return nullptr; }
|
||||
|
||||
|
||||
12
third_party/abseil-cpp/absl/numeric/BUILD.bazel
vendored
12
third_party/abseil-cpp/absl/numeric/BUILD.bazel
vendored
@ -53,3 +53,15 @@ cc_test(
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "int128_benchmark",
|
||||
srcs = ["int128_benchmark.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = ["benchmark"],
|
||||
deps = [
|
||||
":int128",
|
||||
"//absl/base:config",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
221
third_party/abseil-cpp/absl/numeric/int128_benchmark.cc
vendored
Normal file
221
third_party/abseil-cpp/absl/numeric/int128_benchmark.cc
vendored
Normal file
@ -0,0 +1,221 @@
|
||||
// Copyright 2017 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
|
||||
//
|
||||
// http://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/numeric/int128.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr size_t kSampleSize = 1000000;
|
||||
|
||||
std::mt19937 MakeRandomEngine() {
|
||||
std::random_device r;
|
||||
std::seed_seq seed({r(), r(), r(), r(), r(), r(), r(), r()});
|
||||
return std::mt19937(seed);
|
||||
}
|
||||
|
||||
std::vector<std::pair<absl::uint128, absl::uint128>>
|
||||
GetRandomClass128SampleUniformDivisor() {
|
||||
std::vector<std::pair<absl::uint128, absl::uint128>> values;
|
||||
std::mt19937 random = MakeRandomEngine();
|
||||
std::uniform_int_distribution<uint64_t> uniform_uint64;
|
||||
values.reserve(kSampleSize);
|
||||
for (size_t i = 0; i < kSampleSize; ++i) {
|
||||
absl::uint128 a =
|
||||
absl::MakeUint128(uniform_uint64(random), uniform_uint64(random));
|
||||
absl::uint128 b =
|
||||
absl::MakeUint128(uniform_uint64(random), uniform_uint64(random));
|
||||
values.emplace_back(std::max(a, b),
|
||||
std::max(absl::uint128(2), std::min(a, b)));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
void BM_DivideClass128UniformDivisor(benchmark::State& state) {
|
||||
auto values = GetRandomClass128SampleUniformDivisor();
|
||||
while (state.KeepRunningBatch(values.size())) {
|
||||
for (const auto& pair : values) {
|
||||
benchmark::DoNotOptimize(pair.first / pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_DivideClass128UniformDivisor);
|
||||
|
||||
std::vector<std::pair<absl::uint128, uint64_t>>
|
||||
GetRandomClass128SampleSmallDivisor() {
|
||||
std::vector<std::pair<absl::uint128, uint64_t>> values;
|
||||
std::mt19937 random = MakeRandomEngine();
|
||||
std::uniform_int_distribution<uint64_t> uniform_uint64;
|
||||
values.reserve(kSampleSize);
|
||||
for (size_t i = 0; i < kSampleSize; ++i) {
|
||||
absl::uint128 a =
|
||||
absl::MakeUint128(uniform_uint64(random), uniform_uint64(random));
|
||||
uint64_t b = std::max(uint64_t{2}, uniform_uint64(random));
|
||||
values.emplace_back(std::max(a, absl::uint128(b)), b);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
void BM_DivideClass128SmallDivisor(benchmark::State& state) {
|
||||
auto values = GetRandomClass128SampleSmallDivisor();
|
||||
while (state.KeepRunningBatch(values.size())) {
|
||||
for (const auto& pair : values) {
|
||||
benchmark::DoNotOptimize(pair.first / pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_DivideClass128SmallDivisor);
|
||||
|
||||
std::vector<std::pair<absl::uint128, absl::uint128>> GetRandomClass128Sample() {
|
||||
std::vector<std::pair<absl::uint128, absl::uint128>> values;
|
||||
std::mt19937 random = MakeRandomEngine();
|
||||
std::uniform_int_distribution<uint64_t> uniform_uint64;
|
||||
values.reserve(kSampleSize);
|
||||
for (size_t i = 0; i < kSampleSize; ++i) {
|
||||
values.emplace_back(
|
||||
absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)),
|
||||
absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
void BM_MultiplyClass128(benchmark::State& state) {
|
||||
auto values = GetRandomClass128Sample();
|
||||
while (state.KeepRunningBatch(values.size())) {
|
||||
for (const auto& pair : values) {
|
||||
benchmark::DoNotOptimize(pair.first * pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_MultiplyClass128);
|
||||
|
||||
void BM_AddClass128(benchmark::State& state) {
|
||||
auto values = GetRandomClass128Sample();
|
||||
while (state.KeepRunningBatch(values.size())) {
|
||||
for (const auto& pair : values) {
|
||||
benchmark::DoNotOptimize(pair.first + pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_AddClass128);
|
||||
|
||||
#ifdef ABSL_HAVE_INTRINSIC_INT128
|
||||
|
||||
// Some implementations of <random> do not support __int128 when it is
|
||||
// available, so we make our own uniform_int_distribution-like type.
|
||||
class UniformIntDistribution128 {
|
||||
public:
|
||||
// NOLINTNEXTLINE: mimicking std::uniform_int_distribution API
|
||||
unsigned __int128 operator()(std::mt19937& generator) {
|
||||
return (static_cast<unsigned __int128>(dist64_(generator)) << 64) |
|
||||
dist64_(generator);
|
||||
}
|
||||
|
||||
private:
|
||||
std::uniform_int_distribution<uint64_t> dist64_;
|
||||
};
|
||||
|
||||
std::vector<std::pair<unsigned __int128, unsigned __int128>>
|
||||
GetRandomIntrinsic128SampleUniformDivisor() {
|
||||
std::vector<std::pair<unsigned __int128, unsigned __int128>> values;
|
||||
std::mt19937 random = MakeRandomEngine();
|
||||
UniformIntDistribution128 uniform_uint128;
|
||||
values.reserve(kSampleSize);
|
||||
for (size_t i = 0; i < kSampleSize; ++i) {
|
||||
unsigned __int128 a = uniform_uint128(random);
|
||||
unsigned __int128 b = uniform_uint128(random);
|
||||
values.emplace_back(
|
||||
std::max(a, b),
|
||||
std::max(static_cast<unsigned __int128>(2), std::min(a, b)));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
void BM_DivideIntrinsic128UniformDivisor(benchmark::State& state) {
|
||||
auto values = GetRandomIntrinsic128SampleUniformDivisor();
|
||||
while (state.KeepRunningBatch(values.size())) {
|
||||
for (const auto& pair : values) {
|
||||
benchmark::DoNotOptimize(pair.first / pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_DivideIntrinsic128UniformDivisor);
|
||||
|
||||
std::vector<std::pair<unsigned __int128, uint64_t>>
|
||||
GetRandomIntrinsic128SampleSmallDivisor() {
|
||||
std::vector<std::pair<unsigned __int128, uint64_t>> values;
|
||||
std::mt19937 random = MakeRandomEngine();
|
||||
UniformIntDistribution128 uniform_uint128;
|
||||
std::uniform_int_distribution<uint64_t> uniform_uint64;
|
||||
values.reserve(kSampleSize);
|
||||
for (size_t i = 0; i < kSampleSize; ++i) {
|
||||
unsigned __int128 a = uniform_uint128(random);
|
||||
uint64_t b = std::max(uint64_t{2}, uniform_uint64(random));
|
||||
values.emplace_back(std::max(a, static_cast<unsigned __int128>(b)), b);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
void BM_DivideIntrinsic128SmallDivisor(benchmark::State& state) {
|
||||
auto values = GetRandomIntrinsic128SampleSmallDivisor();
|
||||
while (state.KeepRunningBatch(values.size())) {
|
||||
for (const auto& pair : values) {
|
||||
benchmark::DoNotOptimize(pair.first / pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_DivideIntrinsic128SmallDivisor);
|
||||
|
||||
std::vector<std::pair<unsigned __int128, unsigned __int128>>
|
||||
GetRandomIntrinsic128Sample() {
|
||||
std::vector<std::pair<unsigned __int128, unsigned __int128>> values;
|
||||
std::mt19937 random = MakeRandomEngine();
|
||||
UniformIntDistribution128 uniform_uint128;
|
||||
values.reserve(kSampleSize);
|
||||
for (size_t i = 0; i < kSampleSize; ++i) {
|
||||
values.emplace_back(uniform_uint128(random), uniform_uint128(random));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
void BM_MultiplyIntrinsic128(benchmark::State& state) {
|
||||
auto values = GetRandomIntrinsic128Sample();
|
||||
while (state.KeepRunningBatch(values.size())) {
|
||||
for (const auto& pair : values) {
|
||||
benchmark::DoNotOptimize(pair.first * pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_MultiplyIntrinsic128);
|
||||
|
||||
void BM_AddIntrinsic128(benchmark::State& state) {
|
||||
auto values = GetRandomIntrinsic128Sample();
|
||||
while (state.KeepRunningBatch(values.size())) {
|
||||
for (const auto& pair : values) {
|
||||
benchmark::DoNotOptimize(pair.first + pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_AddIntrinsic128);
|
||||
|
||||
#endif // ABSL_HAVE_INTRINSIC_INT128
|
||||
|
||||
} // namespace
|
||||
82
third_party/abseil-cpp/absl/strings/BUILD.bazel
vendored
82
third_party/abseil-cpp/absl/strings/BUILD.bazel
vendored
@ -111,7 +111,7 @@ cc_test(
|
||||
size = "small",
|
||||
srcs = [
|
||||
"escaping_test.cc",
|
||||
"internal/escaping_test_common.inc",
|
||||
"internal/escaping_test_common.h",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
visibility = ["//visibility:private"],
|
||||
@ -123,11 +123,32 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "escaping_benchmark",
|
||||
srcs = [
|
||||
"escaping_benchmark.cc",
|
||||
"internal/escaping_test_common.h",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = ["benchmark"],
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
":strings",
|
||||
"//absl/base",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "ascii_test",
|
||||
size = "small",
|
||||
srcs = ["ascii_test.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = [
|
||||
"no_test_android_arm",
|
||||
"no_test_android_arm64",
|
||||
"no_test_android_x86",
|
||||
],
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
":strings",
|
||||
@ -136,6 +157,22 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "memutil_benchmark",
|
||||
srcs = [
|
||||
"internal/memutil.h",
|
||||
"internal/memutil_benchmark.cc",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = ["benchmark"],
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
":strings",
|
||||
"//absl/base:core_headers",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "memutil_test",
|
||||
size = "small",
|
||||
@ -178,7 +215,7 @@ cc_test(
|
||||
":strings",
|
||||
"//absl/base",
|
||||
"//absl/base:core_headers",
|
||||
"@com_github_google_benchmark//:benchmark",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
@ -219,7 +256,7 @@ cc_test(
|
||||
deps = [
|
||||
":strings",
|
||||
"//absl/base",
|
||||
"@com_github_google_benchmark//:benchmark",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
@ -257,7 +294,7 @@ cc_test(
|
||||
deps = [
|
||||
":strings",
|
||||
"//absl/base",
|
||||
"@com_github_google_benchmark//:benchmark",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
@ -273,6 +310,18 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "ostringstream_benchmark",
|
||||
srcs = ["internal/ostringstream_benchmark.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = ["benchmark"],
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
":internal",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "resize_uninitialized_test",
|
||||
size = "small",
|
||||
@ -312,7 +361,7 @@ cc_test(
|
||||
deps = [
|
||||
":strings",
|
||||
"//absl/memory",
|
||||
"@com_github_google_benchmark//:benchmark",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
@ -337,7 +386,7 @@ cc_test(
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
":strings",
|
||||
"@com_github_google_benchmark//:benchmark",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
@ -345,11 +394,14 @@ cc_test(
|
||||
name = "numbers_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"internal/numbers_test_common.inc",
|
||||
"internal/numbers_test_common.h",
|
||||
"numbers_test.cc",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = [
|
||||
"no_test_android_arm",
|
||||
"no_test_android_arm64",
|
||||
"no_test_android_x86",
|
||||
"no_test_loonix",
|
||||
],
|
||||
visibility = ["//visibility:private"],
|
||||
@ -377,8 +429,24 @@ cc_test(
|
||||
name = "char_map_test",
|
||||
srcs = ["internal/char_map_test.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = [
|
||||
"no_test_android_arm",
|
||||
"no_test_android_arm64",
|
||||
"no_test_android_x86",
|
||||
],
|
||||
deps = [
|
||||
":internal",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "char_map_benchmark",
|
||||
srcs = ["internal/char_map_benchmark.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = ["benchmark"],
|
||||
deps = [
|
||||
":internal",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
@ -130,9 +130,11 @@ TEST(AsciiIsFoo, All) {
|
||||
// Checks that absl::ascii_isfoo returns the same value as isfoo in the C
|
||||
// locale.
|
||||
TEST(AsciiIsFoo, SameAsIsFoo) {
|
||||
#ifndef __ANDROID__
|
||||
// temporarily change locale to C. It should already be C, but just for safety
|
||||
std::string old_locale = setlocale(LC_CTYPE, nullptr);
|
||||
ASSERT_TRUE(setlocale(LC_CTYPE, "C"));
|
||||
const char* old_locale = setlocale(LC_CTYPE, "C");
|
||||
ASSERT_TRUE(old_locale != nullptr);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
EXPECT_EQ(isalpha(i) != 0, absl::ascii_isalpha(i)) << i;
|
||||
@ -150,14 +152,18 @@ TEST(AsciiIsFoo, SameAsIsFoo) {
|
||||
EXPECT_EQ(isascii(i) != 0, absl::ascii_isascii(i)) << i;
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
// restore the old locale.
|
||||
ASSERT_TRUE(setlocale(LC_CTYPE, old_locale.c_str()));
|
||||
ASSERT_TRUE(setlocale(LC_CTYPE, old_locale));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(AsciiToFoo, All) {
|
||||
#ifndef __ANDROID__
|
||||
// temporarily change locale to C. It should already be C, but just for safety
|
||||
std::string old_locale = setlocale(LC_CTYPE, nullptr);
|
||||
ASSERT_TRUE(setlocale(LC_CTYPE, "C"));
|
||||
const char* old_locale = setlocale(LC_CTYPE, "C");
|
||||
ASSERT_TRUE(old_locale != nullptr);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (absl::ascii_islower(i))
|
||||
@ -180,9 +186,10 @@ TEST(AsciiToFoo, All) {
|
||||
EXPECT_EQ(absl::ascii_tolower(i), absl::ascii_tolower(sc)) << i;
|
||||
EXPECT_EQ(absl::ascii_toupper(i), absl::ascii_toupper(sc)) << i;
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
// restore the old locale.
|
||||
ASSERT_TRUE(setlocale(LC_CTYPE, old_locale.c_str()));
|
||||
ASSERT_TRUE(setlocale(LC_CTYPE, old_locale));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(AsciiStrTo, Lower) {
|
||||
|
||||
94
third_party/abseil-cpp/absl/strings/escaping_benchmark.cc
vendored
Normal file
94
third_party/abseil-cpp/absl/strings/escaping_benchmark.cc
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright 2018 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://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/escaping.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <random>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/strings/internal/escaping_test_common.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void BM_CUnescapeHexString(benchmark::State& state) {
|
||||
std::string src;
|
||||
for (int i = 0; i < 50; i++) {
|
||||
src += "\\x55";
|
||||
}
|
||||
std::string dest;
|
||||
for (auto _ : state) {
|
||||
absl::CUnescape(src, &dest);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_CUnescapeHexString);
|
||||
|
||||
void BM_WebSafeBase64Escape_string(benchmark::State& state) {
|
||||
std::string raw;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
for (const auto& test_set : absl::strings_internal::base64_strings()) {
|
||||
raw += std::string(test_set.plaintext);
|
||||
}
|
||||
}
|
||||
|
||||
// The actual benchmark loop is tiny...
|
||||
std::string escaped;
|
||||
for (auto _ : state) {
|
||||
absl::WebSafeBase64Escape(raw, &escaped);
|
||||
}
|
||||
|
||||
// We want to be sure the compiler doesn't throw away the loop above,
|
||||
// and the easiest way to ensure that is to round-trip the results and verify
|
||||
// them.
|
||||
std::string round_trip;
|
||||
absl::WebSafeBase64Unescape(escaped, &round_trip);
|
||||
ABSL_RAW_CHECK(round_trip == raw, "");
|
||||
}
|
||||
BENCHMARK(BM_WebSafeBase64Escape_string);
|
||||
|
||||
// Used for the CEscape benchmarks
|
||||
const char kStringValueNoEscape[] = "1234567890";
|
||||
const char kStringValueSomeEscaped[] = "123\n56789\xA1";
|
||||
const char kStringValueMostEscaped[] = "\xA1\xA2\ny\xA4\xA5\xA6z\b\r";
|
||||
|
||||
void CEscapeBenchmarkHelper(benchmark::State& state, const char* string_value,
|
||||
int max_len) {
|
||||
std::string src;
|
||||
while (src.size() < max_len) {
|
||||
absl::StrAppend(&src, string_value);
|
||||
}
|
||||
|
||||
for (auto _ : state) {
|
||||
absl::CEscape(src);
|
||||
}
|
||||
}
|
||||
|
||||
void BM_CEscape_NoEscape(benchmark::State& state) {
|
||||
CEscapeBenchmarkHelper(state, kStringValueNoEscape, state.range(0));
|
||||
}
|
||||
BENCHMARK(BM_CEscape_NoEscape)->Range(1, 1 << 14);
|
||||
|
||||
void BM_CEscape_SomeEscaped(benchmark::State& state) {
|
||||
CEscapeBenchmarkHelper(state, kStringValueSomeEscaped, state.range(0));
|
||||
}
|
||||
BENCHMARK(BM_CEscape_SomeEscaped)->Range(1, 1 << 14);
|
||||
|
||||
void BM_CEscape_MostEscaped(benchmark::State& state) {
|
||||
CEscapeBenchmarkHelper(state, kStringValueMostEscaped, state.range(0));
|
||||
}
|
||||
BENCHMARK(BM_CEscape_MostEscaped)->Range(1, 1 << 14);
|
||||
|
||||
} // namespace
|
||||
@ -25,7 +25,7 @@
|
||||
#include "absl/container/fixed_array.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
|
||||
#include "absl/strings/internal/escaping_test_common.inc"
|
||||
#include "absl/strings/internal/escaping_test_common.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -575,7 +575,7 @@ TEST(Base64, EscapeAndUnescape) {
|
||||
}
|
||||
|
||||
// Now try the long strings, this tests the streaming
|
||||
for (const auto& tc : base64_strings) {
|
||||
for (const auto& tc : absl::strings_internal::base64_strings()) {
|
||||
std::string buffer;
|
||||
absl::WebSafeBase64Escape(tc.plaintext, &buffer);
|
||||
EXPECT_EQ(tc.cyphertext, buffer);
|
||||
|
||||
61
third_party/abseil-cpp/absl/strings/internal/char_map_benchmark.cc
vendored
Normal file
61
third_party/abseil-cpp/absl/strings/internal/char_map_benchmark.cc
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright 2017 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
|
||||
//
|
||||
// http://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/char_map.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
namespace {
|
||||
|
||||
absl::strings_internal::Charmap MakeBenchmarkMap() {
|
||||
absl::strings_internal::Charmap m;
|
||||
uint32_t x[] = {0x0, 0x1, 0x2, 0x3, 0xf, 0xe, 0xd, 0xc};
|
||||
for (uint32_t& t : x) t *= static_cast<uint32_t>(0x11111111UL);
|
||||
for (uint32_t i = 0; i < 256; ++i) {
|
||||
if ((x[i / 32] >> (i % 32)) & 1)
|
||||
m = m | absl::strings_internal::Charmap::Char(i);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
// Micro-benchmark for Charmap::contains.
|
||||
void BM_Contains(benchmark::State& state) {
|
||||
// Loop-body replicated 10 times to increase time per iteration.
|
||||
// Argument continuously changed to avoid generating common subexpressions.
|
||||
const absl::strings_internal::Charmap benchmark_map = MakeBenchmarkMap();
|
||||
unsigned char c = 0;
|
||||
int ops = 0;
|
||||
for (auto _ : state) {
|
||||
ops += benchmark_map.contains(c++);
|
||||
ops += benchmark_map.contains(c++);
|
||||
ops += benchmark_map.contains(c++);
|
||||
ops += benchmark_map.contains(c++);
|
||||
ops += benchmark_map.contains(c++);
|
||||
ops += benchmark_map.contains(c++);
|
||||
ops += benchmark_map.contains(c++);
|
||||
ops += benchmark_map.contains(c++);
|
||||
ops += benchmark_map.contains(c++);
|
||||
ops += benchmark_map.contains(c++);
|
||||
}
|
||||
benchmark::DoNotOptimize(ops);
|
||||
}
|
||||
BENCHMARK(BM_Contains);
|
||||
|
||||
// We don't bother benchmarking Charmap::IsZero or Charmap::IntersectsWith;
|
||||
// their running time is data-dependent and it is not worth characterizing
|
||||
// "typical" data.
|
||||
|
||||
} // namespace
|
||||
131
third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h
vendored
Normal file
131
third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
// Copyright 2017 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
|
||||
//
|
||||
// http://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.
|
||||
//
|
||||
// This test contains common things needed by both escaping_test.cc and
|
||||
// escaping_benchmark.cc.
|
||||
|
||||
#ifndef ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_
|
||||
#define ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_
|
||||
|
||||
#include <array>
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
namespace strings_internal {
|
||||
|
||||
struct base64_testcase {
|
||||
absl::string_view plaintext;
|
||||
absl::string_view cyphertext;
|
||||
};
|
||||
|
||||
inline const std::array<base64_testcase, 5>& base64_strings() {
|
||||
static const std::array<base64_testcase, 5> testcase{{
|
||||
// Some google quotes
|
||||
// Cyphertext created with "uuencode (GNU sharutils) 4.6.3"
|
||||
// (Note that we're testing the websafe encoding, though, so if
|
||||
// you add messages, be sure to run "tr -- '+/' '-_'" on the output)
|
||||
{ "I was always good at math and science, and I never realized "
|
||||
"that was unusual or somehow undesirable. So one of the things "
|
||||
"I care a lot about is helping to remove that stigma, "
|
||||
"to show girls that you can be feminine, you can like the things "
|
||||
"that girls like, but you can also be really good at technology. "
|
||||
"You can be really good at building things."
|
||||
" - Marissa Meyer, Newsweek, 2010-12-22" "\n",
|
||||
|
||||
"SSB3YXMgYWx3YXlzIGdvb2QgYXQgbWF0aCBhbmQgc2NpZW5jZSwgYW5kIEkg"
|
||||
"bmV2ZXIgcmVhbGl6ZWQgdGhhdCB3YXMgdW51c3VhbCBvciBzb21laG93IHVu"
|
||||
"ZGVzaXJhYmxlLiBTbyBvbmUgb2YgdGhlIHRoaW5ncyBJIGNhcmUgYSBsb3Qg"
|
||||
"YWJvdXQgaXMgaGVscGluZyB0byByZW1vdmUgdGhhdCBzdGlnbWEsIHRvIHNo"
|
||||
"b3cgZ2lybHMgdGhhdCB5b3UgY2FuIGJlIGZlbWluaW5lLCB5b3UgY2FuIGxp"
|
||||
"a2UgdGhlIHRoaW5ncyB0aGF0IGdpcmxzIGxpa2UsIGJ1dCB5b3UgY2FuIGFs"
|
||||
"c28gYmUgcmVhbGx5IGdvb2QgYXQgdGVjaG5vbG9neS4gWW91IGNhbiBiZSBy"
|
||||
"ZWFsbHkgZ29vZCBhdCBidWlsZGluZyB0aGluZ3MuIC0gTWFyaXNzYSBNZXll"
|
||||
"ciwgTmV3c3dlZWssIDIwMTAtMTItMjIK" },
|
||||
|
||||
{ "Typical first year for a new cluster: "
|
||||
"~0.5 overheating "
|
||||
"~1 PDU failure "
|
||||
"~1 rack-move "
|
||||
"~1 network rewiring "
|
||||
"~20 rack failures "
|
||||
"~5 racks go wonky "
|
||||
"~8 network maintenances "
|
||||
"~12 router reloads "
|
||||
"~3 router failures "
|
||||
"~dozens of minor 30-second blips for dns "
|
||||
"~1000 individual machine failures "
|
||||
"~thousands of hard drive failures "
|
||||
"slow disks, bad memory, misconfigured machines, flaky machines, etc."
|
||||
" - Jeff Dean, The Joys of Real Hardware" "\n",
|
||||
|
||||
"VHlwaWNhbCBmaXJzdCB5ZWFyIGZvciBhIG5ldyBjbHVzdGVyOiB-MC41IG92"
|
||||
"ZXJoZWF0aW5nIH4xIFBEVSBmYWlsdXJlIH4xIHJhY2stbW92ZSB-MSBuZXR3"
|
||||
"b3JrIHJld2lyaW5nIH4yMCByYWNrIGZhaWx1cmVzIH41IHJhY2tzIGdvIHdv"
|
||||
"bmt5IH44IG5ldHdvcmsgbWFpbnRlbmFuY2VzIH4xMiByb3V0ZXIgcmVsb2Fk"
|
||||
"cyB-MyByb3V0ZXIgZmFpbHVyZXMgfmRvemVucyBvZiBtaW5vciAzMC1zZWNv"
|
||||
"bmQgYmxpcHMgZm9yIGRucyB-MTAwMCBpbmRpdmlkdWFsIG1hY2hpbmUgZmFp"
|
||||
"bHVyZXMgfnRob3VzYW5kcyBvZiBoYXJkIGRyaXZlIGZhaWx1cmVzIHNsb3cg"
|
||||
"ZGlza3MsIGJhZCBtZW1vcnksIG1pc2NvbmZpZ3VyZWQgbWFjaGluZXMsIGZs"
|
||||
"YWt5IG1hY2hpbmVzLCBldGMuIC0gSmVmZiBEZWFuLCBUaGUgSm95cyBvZiBS"
|
||||
"ZWFsIEhhcmR3YXJlCg" },
|
||||
|
||||
{ "I'm the head of the webspam team at Google. "
|
||||
"That means that if you type your name into Google and get porn back, "
|
||||
"it's my fault. Unless you're a porn star, in which case porn is a "
|
||||
"completely reasonable response."
|
||||
" - Matt Cutts, Google Plus" "\n",
|
||||
|
||||
"SSdtIHRoZSBoZWFkIG9mIHRoZSB3ZWJzcGFtIHRlYW0gYXQgR29vZ2xlLiAg"
|
||||
"VGhhdCBtZWFucyB0aGF0IGlmIHlvdSB0eXBlIHlvdXIgbmFtZSBpbnRvIEdv"
|
||||
"b2dsZSBhbmQgZ2V0IHBvcm4gYmFjaywgaXQncyBteSBmYXVsdC4gVW5sZXNz"
|
||||
"IHlvdSdyZSBhIHBvcm4gc3RhciwgaW4gd2hpY2ggY2FzZSBwb3JuIGlzIGEg"
|
||||
"Y29tcGxldGVseSByZWFzb25hYmxlIHJlc3BvbnNlLiAtIE1hdHQgQ3V0dHMs"
|
||||
"IEdvb2dsZSBQbHVzCg" },
|
||||
|
||||
{ "It will still be a long time before machines approach human "
|
||||
"intelligence. "
|
||||
"But luckily, machines don't actually have to be intelligent; "
|
||||
"they just have to fake it. Access to a wealth of information, "
|
||||
"combined with a rudimentary decision-making capacity, "
|
||||
"can often be almost as useful. Of course, the results are better yet "
|
||||
"when coupled with intelligence. A reference librarian with access to "
|
||||
"a good search engine is a formidable tool."
|
||||
" - Craig Silverstein, Siemens Pictures of the Future, Spring 2004"
|
||||
"\n",
|
||||
|
||||
"SXQgd2lsbCBzdGlsbCBiZSBhIGxvbmcgdGltZSBiZWZvcmUgbWFjaGluZXMg"
|
||||
"YXBwcm9hY2ggaHVtYW4gaW50ZWxsaWdlbmNlLiBCdXQgbHVja2lseSwgbWFj"
|
||||
"aGluZXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSB0byBiZSBpbnRlbGxpZ2VudDsg"
|
||||
"dGhleSBqdXN0IGhhdmUgdG8gZmFrZSBpdC4gQWNjZXNzIHRvIGEgd2VhbHRo"
|
||||
"IG9mIGluZm9ybWF0aW9uLCBjb21iaW5lZCB3aXRoIGEgcnVkaW1lbnRhcnkg"
|
||||
"ZGVjaXNpb24tbWFraW5nIGNhcGFjaXR5LCBjYW4gb2Z0ZW4gYmUgYWxtb3N0"
|
||||
"IGFzIHVzZWZ1bC4gT2YgY291cnNlLCB0aGUgcmVzdWx0cyBhcmUgYmV0dGVy"
|
||||
"IHlldCB3aGVuIGNvdXBsZWQgd2l0aCBpbnRlbGxpZ2VuY2UuIEEgcmVmZXJl"
|
||||
"bmNlIGxpYnJhcmlhbiB3aXRoIGFjY2VzcyB0byBhIGdvb2Qgc2VhcmNoIGVu"
|
||||
"Z2luZSBpcyBhIGZvcm1pZGFibGUgdG9vbC4gLSBDcmFpZyBTaWx2ZXJzdGVp"
|
||||
"biwgU2llbWVucyBQaWN0dXJlcyBvZiB0aGUgRnV0dXJlLCBTcHJpbmcgMjAw"
|
||||
"NAo" },
|
||||
|
||||
// Degenerate edge case
|
||||
{ "",
|
||||
"" },
|
||||
}};
|
||||
|
||||
return testcase;
|
||||
}
|
||||
|
||||
} // namespace strings_internal
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_
|
||||
323
third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc
vendored
Normal file
323
third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc
vendored
Normal file
@ -0,0 +1,323 @@
|
||||
// Copyright 2018 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://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/memutil.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "absl/strings/ascii.h"
|
||||
|
||||
// We fill the haystack with aaaaaaaaaaaaaaaaaa...aaaab.
|
||||
// That gives us:
|
||||
// - an easy search: 'b'
|
||||
// - a medium search: 'ab'. That means every letter is a possible match.
|
||||
// - a pathological search: 'aaaaaa.......aaaaab' (half as many a's as haytack)
|
||||
// We benchmark case-sensitive and case-insensitive versions of
|
||||
// three memmem implementations:
|
||||
// - memmem() from memutil.h
|
||||
// - search() from STL
|
||||
// - memmatch(), a custom implementation using memchr and memcmp.
|
||||
// Here are sample results:
|
||||
//
|
||||
// Run on (12 X 3800 MHz CPU s)
|
||||
// CPU Caches:
|
||||
// L1 Data 32K (x6)
|
||||
// L1 Instruction 32K (x6)
|
||||
// L2 Unified 256K (x6)
|
||||
// L3 Unified 15360K (x1)
|
||||
// ----------------------------------------------------------------
|
||||
// Benchmark Time CPU Iterations
|
||||
// ----------------------------------------------------------------
|
||||
// BM_Memmem 3583 ns 3582 ns 196469 2.59966GB/s
|
||||
// BM_MemmemMedium 13743 ns 13742 ns 50901 693.986MB/s
|
||||
// BM_MemmemPathological 13695030 ns 13693977 ns 51 713.133kB/s
|
||||
// BM_Memcasemem 3299 ns 3299 ns 212942 2.82309GB/s
|
||||
// BM_MemcasememMedium 16407 ns 16406 ns 42170 581.309MB/s
|
||||
// BM_MemcasememPathological 17267745 ns 17266030 ns 41 565.598kB/s
|
||||
// BM_Search 1610 ns 1609 ns 431321 5.78672GB/s
|
||||
// BM_SearchMedium 11111 ns 11110 ns 63001 858.414MB/s
|
||||
// BM_SearchPathological 12117390 ns 12116397 ns 58 805.984kB/s
|
||||
// BM_Searchcase 3081 ns 3081 ns 229949 3.02313GB/s
|
||||
// BM_SearchcaseMedium 16003 ns 16001 ns 44170 595.998MB/s
|
||||
// BM_SearchcasePathological 15823413 ns 15821909 ns 44 617.222kB/s
|
||||
// BM_Memmatch 197 ns 197 ns 3584225 47.2951GB/s
|
||||
// BM_MemmatchMedium 52333 ns 52329 ns 13280 182.244MB/s
|
||||
// BM_MemmatchPathological 659799 ns 659727 ns 1058 14.4556MB/s
|
||||
// BM_Memcasematch 5460 ns 5460 ns 127606 1.70586GB/s
|
||||
// BM_MemcasematchMedium 32861 ns 32857 ns 21258 290.248MB/s
|
||||
// BM_MemcasematchPathological 15154243 ns 15153089 ns 46 644.464kB/s
|
||||
// BM_MemmemStartup 5 ns 5 ns 150821500
|
||||
// BM_SearchStartup 5 ns 5 ns 150644203
|
||||
// BM_MemmatchStartup 7 ns 7 ns 97068802
|
||||
//
|
||||
// Conclusions:
|
||||
//
|
||||
// The following recommendations are based on the sample results above. However,
|
||||
// we have found that the performance of STL search can vary significantly
|
||||
// depending on compiler and standard library implementation. We recommend you
|
||||
// run the benchmarks for yourself on relevant platforms.
|
||||
//
|
||||
// If you need case-insensitive, STL search is slightly better than memmem for
|
||||
// all cases.
|
||||
//
|
||||
// Case-sensitive is more subtle:
|
||||
// Custom memmatch is _very_ fast at scanning, so if you have very few possible
|
||||
// matches in your haystack, that's the way to go. Performance drops
|
||||
// significantly with more matches.
|
||||
//
|
||||
// STL search is slightly faster than memmem in the medium and pathological
|
||||
// benchmarks. However, the performance of memmem is currently more dependable
|
||||
// across platforms and build configurations.
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int kHaystackSize = 10000;
|
||||
constexpr int64_t kHaystackSize64 = kHaystackSize;
|
||||
const char* MakeHaystack() {
|
||||
char* haystack = new char[kHaystackSize];
|
||||
for (int i = 0; i < kHaystackSize - 1; ++i) haystack[i] = 'a';
|
||||
haystack[kHaystackSize - 1] = 'b';
|
||||
return haystack;
|
||||
}
|
||||
const char* const kHaystack = MakeHaystack();
|
||||
|
||||
void BM_Memmem(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(
|
||||
absl::strings_internal::memmem(kHaystack, kHaystackSize, "b", 1));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_Memmem);
|
||||
|
||||
void BM_MemmemMedium(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(
|
||||
absl::strings_internal::memmem(kHaystack, kHaystackSize, "ab", 2));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_MemmemMedium);
|
||||
|
||||
void BM_MemmemPathological(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(absl::strings_internal::memmem(
|
||||
kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2,
|
||||
kHaystackSize - kHaystackSize / 2));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_MemmemPathological);
|
||||
|
||||
void BM_Memcasemem(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(
|
||||
absl::strings_internal::memcasemem(kHaystack, kHaystackSize, "b", 1));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_Memcasemem);
|
||||
|
||||
void BM_MemcasememMedium(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(
|
||||
absl::strings_internal::memcasemem(kHaystack, kHaystackSize, "ab", 2));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_MemcasememMedium);
|
||||
|
||||
void BM_MemcasememPathological(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(absl::strings_internal::memcasemem(
|
||||
kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2,
|
||||
kHaystackSize - kHaystackSize / 2));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_MemcasememPathological);
|
||||
|
||||
bool case_eq(const char a, const char b) {
|
||||
return absl::ascii_tolower(a) == absl::ascii_tolower(b);
|
||||
}
|
||||
|
||||
void BM_Search(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
|
||||
kHaystack + kHaystackSize - 1,
|
||||
kHaystack + kHaystackSize));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_Search);
|
||||
|
||||
void BM_SearchMedium(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
|
||||
kHaystack + kHaystackSize - 2,
|
||||
kHaystack + kHaystackSize));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_SearchMedium);
|
||||
|
||||
void BM_SearchPathological(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
|
||||
kHaystack + kHaystackSize / 2,
|
||||
kHaystack + kHaystackSize));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_SearchPathological);
|
||||
|
||||
void BM_Searchcase(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
|
||||
kHaystack + kHaystackSize - 1,
|
||||
kHaystack + kHaystackSize, case_eq));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_Searchcase);
|
||||
|
||||
void BM_SearchcaseMedium(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
|
||||
kHaystack + kHaystackSize - 2,
|
||||
kHaystack + kHaystackSize, case_eq));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_SearchcaseMedium);
|
||||
|
||||
void BM_SearchcasePathological(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
|
||||
kHaystack + kHaystackSize / 2,
|
||||
kHaystack + kHaystackSize, case_eq));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_SearchcasePathological);
|
||||
|
||||
char* memcasechr(const char* s, int c, size_t slen) {
|
||||
c = absl::ascii_tolower(c);
|
||||
for (; slen; ++s, --slen) {
|
||||
if (absl::ascii_tolower(*s) == c) return const_cast<char*>(s);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* memcasematch(const char* phaystack, size_t haylen,
|
||||
const char* pneedle, size_t neelen) {
|
||||
if (0 == neelen) {
|
||||
return phaystack; // even if haylen is 0
|
||||
}
|
||||
if (haylen < neelen) return nullptr;
|
||||
|
||||
const char* match;
|
||||
const char* hayend = phaystack + haylen - neelen + 1;
|
||||
while ((match = static_cast<char*>(
|
||||
memcasechr(phaystack, pneedle[0], hayend - phaystack)))) {
|
||||
if (absl::strings_internal::memcasecmp(match, pneedle, neelen) == 0)
|
||||
return match;
|
||||
else
|
||||
phaystack = match + 1;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BM_Memmatch(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(
|
||||
absl::strings_internal::memmatch(kHaystack, kHaystackSize, "b", 1));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_Memmatch);
|
||||
|
||||
void BM_MemmatchMedium(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(
|
||||
absl::strings_internal::memmatch(kHaystack, kHaystackSize, "ab", 2));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_MemmatchMedium);
|
||||
|
||||
void BM_MemmatchPathological(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(absl::strings_internal::memmatch(
|
||||
kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2,
|
||||
kHaystackSize - kHaystackSize / 2));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_MemmatchPathological);
|
||||
|
||||
void BM_Memcasematch(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize, "b", 1));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_Memcasematch);
|
||||
|
||||
void BM_MemcasematchMedium(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize, "ab", 2));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_MemcasematchMedium);
|
||||
|
||||
void BM_MemcasematchPathological(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize,
|
||||
kHaystack + kHaystackSize / 2,
|
||||
kHaystackSize - kHaystackSize / 2));
|
||||
}
|
||||
state.SetBytesProcessed(kHaystackSize64 * state.iterations());
|
||||
}
|
||||
BENCHMARK(BM_MemcasematchPathological);
|
||||
|
||||
void BM_MemmemStartup(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(absl::strings_internal::memmem(
|
||||
kHaystack + kHaystackSize - 10, 10, kHaystack + kHaystackSize - 1, 1));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_MemmemStartup);
|
||||
|
||||
void BM_SearchStartup(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(
|
||||
std::search(kHaystack + kHaystackSize - 10, kHaystack + kHaystackSize,
|
||||
kHaystack + kHaystackSize - 1, kHaystack + kHaystackSize));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_SearchStartup);
|
||||
|
||||
void BM_MemmatchStartup(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(absl::strings_internal::memmatch(
|
||||
kHaystack + kHaystackSize - 10, 10, kHaystack + kHaystackSize - 1, 1));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_MemmatchStartup);
|
||||
|
||||
} // namespace
|
||||
178
third_party/abseil-cpp/absl/strings/internal/numbers_test_common.h
vendored
Normal file
178
third_party/abseil-cpp/absl/strings/internal/numbers_test_common.h
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
// Copyright 2017 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
|
||||
//
|
||||
// http://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.
|
||||
//
|
||||
// This file contains common things needed by numbers_test.cc,
|
||||
// numbers_legacy_test.cc and numbers_benchmark.cc.
|
||||
|
||||
#ifndef ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_
|
||||
#define ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
namespace absl {
|
||||
namespace strings_internal {
|
||||
|
||||
template <typename IntType>
|
||||
inline bool Itoa(IntType value, int base, std::string* destination) {
|
||||
destination->clear();
|
||||
if (base <= 1 || base > 36) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value == 0) {
|
||||
destination->push_back('0');
|
||||
return true;
|
||||
}
|
||||
|
||||
bool negative = value < 0;
|
||||
while (value != 0) {
|
||||
const IntType next_value = value / base;
|
||||
// Can't use std::abs here because of problems when IntType is unsigned.
|
||||
int remainder = value > next_value * base ? value - next_value * base
|
||||
: next_value * base - value;
|
||||
char c = remainder < 10 ? '0' + remainder : 'A' + remainder - 10;
|
||||
destination->insert(0, 1, c);
|
||||
value = next_value;
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
destination->insert(0, 1, '-');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct uint32_test_case {
|
||||
const char* str;
|
||||
bool expect_ok;
|
||||
int base; // base to pass to the conversion function
|
||||
uint32_t expected;
|
||||
};
|
||||
|
||||
inline const std::array<uint32_test_case, 27>& strtouint32_test_cases() {
|
||||
static const std::array<uint32_test_case, 27> test_cases{{
|
||||
{"0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()},
|
||||
{"0x34234324", true, 16, 0x34234324},
|
||||
{"34234324", true, 16, 0x34234324},
|
||||
{"0", true, 16, 0},
|
||||
{" \t\n 0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()},
|
||||
{" \f\v 46", true, 10, 46}, // must accept weird whitespace
|
||||
{" \t\n 72717222", true, 8, 072717222},
|
||||
{" \t\n 072717222", true, 8, 072717222},
|
||||
{" \t\n 072717228", false, 8, 07271722},
|
||||
{"0", true, 0, 0},
|
||||
|
||||
// Base-10 version.
|
||||
{"34234324", true, 0, 34234324},
|
||||
{"4294967295", true, 0, std::numeric_limits<uint32_t>::max()},
|
||||
{"34234324 \n\t", true, 10, 34234324},
|
||||
|
||||
// Unusual base
|
||||
{"0", true, 3, 0},
|
||||
{"2", true, 3, 2},
|
||||
{"11", true, 3, 4},
|
||||
|
||||
// Invalid uints.
|
||||
{"", false, 0, 0},
|
||||
{" ", false, 0, 0},
|
||||
{"abc", false, 0, 0}, // would be valid hex, but prefix is missing
|
||||
{"34234324a", false, 0, 34234324},
|
||||
{"34234.3", false, 0, 34234},
|
||||
{"-1", false, 0, 0},
|
||||
{" -123", false, 0, 0},
|
||||
{" \t\n -123", false, 0, 0},
|
||||
|
||||
// Out of bounds.
|
||||
{"4294967296", false, 0, std::numeric_limits<uint32_t>::max()},
|
||||
{"0x100000000", false, 0, std::numeric_limits<uint32_t>::max()},
|
||||
{nullptr, false, 0, 0},
|
||||
}};
|
||||
return test_cases;
|
||||
}
|
||||
|
||||
struct uint64_test_case {
|
||||
const char* str;
|
||||
bool expect_ok;
|
||||
int base;
|
||||
uint64_t expected;
|
||||
};
|
||||
|
||||
inline const std::array<uint64_test_case, 34>& strtouint64_test_cases() {
|
||||
static const std::array<uint64_test_case, 34> test_cases{{
|
||||
{"0x3423432448783446", true, 16, int64_t{0x3423432448783446}},
|
||||
{"3423432448783446", true, 16, int64_t{0x3423432448783446}},
|
||||
|
||||
{"0", true, 16, 0},
|
||||
{"000", true, 0, 0},
|
||||
{"0", true, 0, 0},
|
||||
{" \t\n 0xffffffffffffffff", true, 16,
|
||||
std::numeric_limits<uint64_t>::max()},
|
||||
|
||||
{"012345670123456701234", true, 8, int64_t{012345670123456701234}},
|
||||
{"12345670123456701234", true, 8, int64_t{012345670123456701234}},
|
||||
|
||||
{"12845670123456701234", false, 8, 0},
|
||||
|
||||
// Base-10 version.
|
||||
{"34234324487834466", true, 0, int64_t{34234324487834466}},
|
||||
|
||||
{" \t\n 18446744073709551615", true, 0,
|
||||
std::numeric_limits<uint64_t>::max()},
|
||||
|
||||
{"34234324487834466 \n\t ", true, 0, int64_t{34234324487834466}},
|
||||
|
||||
{" \f\v 46", true, 10, 46}, // must accept weird whitespace
|
||||
|
||||
// Unusual base
|
||||
{"0", true, 3, 0},
|
||||
{"2", true, 3, 2},
|
||||
{"11", true, 3, 4},
|
||||
|
||||
{"0", true, 0, 0},
|
||||
|
||||
// Invalid uints.
|
||||
{"", false, 0, 0},
|
||||
{" ", false, 0, 0},
|
||||
{"abc", false, 0, 0},
|
||||
{"34234324487834466a", false, 0, 0},
|
||||
{"34234487834466.3", false, 0, 0},
|
||||
{"-1", false, 0, 0},
|
||||
{" -123", false, 0, 0},
|
||||
{" \t\n -123", false, 0, 0},
|
||||
|
||||
// Out of bounds.
|
||||
{"18446744073709551616", false, 10, 0},
|
||||
{"18446744073709551616", false, 0, 0},
|
||||
{"0x10000000000000000", false, 16, std::numeric_limits<uint64_t>::max()},
|
||||
{"0X10000000000000000", false, 16,
|
||||
std::numeric_limits<uint64_t>::max()}, // 0X versus 0x.
|
||||
{"0x10000000000000000", false, 0, std::numeric_limits<uint64_t>::max()},
|
||||
{"0X10000000000000000", false, 0,
|
||||
std::numeric_limits<uint64_t>::max()}, // 0X versus 0x.
|
||||
|
||||
{"0x1234", true, 16, 0x1234},
|
||||
|
||||
// Base-10 std::string version.
|
||||
{"1234", true, 0, 1234},
|
||||
{nullptr, false, 0, 0},
|
||||
}};
|
||||
return test_cases;
|
||||
}
|
||||
|
||||
} // namespace strings_internal
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_
|
||||
106
third_party/abseil-cpp/absl/strings/internal/ostringstream_benchmark.cc
vendored
Normal file
106
third_party/abseil-cpp/absl/strings/internal/ostringstream_benchmark.cc
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
// Copyright 2018 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://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/ostringstream.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
namespace {
|
||||
|
||||
enum StringType {
|
||||
kNone,
|
||||
kStdString,
|
||||
};
|
||||
|
||||
// Benchmarks for std::ostringstream.
|
||||
template <StringType kOutput>
|
||||
void BM_StdStream(benchmark::State& state) {
|
||||
const int num_writes = state.range(0);
|
||||
const int bytes_per_write = state.range(1);
|
||||
const std::string payload(bytes_per_write, 'x');
|
||||
for (auto _ : state) {
|
||||
std::ostringstream strm;
|
||||
benchmark::DoNotOptimize(strm);
|
||||
for (int i = 0; i != num_writes; ++i) {
|
||||
strm << payload;
|
||||
}
|
||||
switch (kOutput) {
|
||||
case kNone: {
|
||||
break;
|
||||
}
|
||||
case kStdString: {
|
||||
std::string s = strm.str();
|
||||
benchmark::DoNotOptimize(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the stream, optionally write to it, then destroy it.
|
||||
BENCHMARK_TEMPLATE(BM_StdStream, kNone)
|
||||
->ArgPair(0, 0)
|
||||
->ArgPair(1, 16) // 16 bytes is small enough for SSO
|
||||
->ArgPair(1, 256) // 256 bytes requires heap allocation
|
||||
->ArgPair(1024, 256);
|
||||
// Create the stream, write to it, get std::string out, then destroy.
|
||||
BENCHMARK_TEMPLATE(BM_StdStream, kStdString)
|
||||
->ArgPair(1, 16) // 16 bytes is small enough for SSO
|
||||
->ArgPair(1, 256) // 256 bytes requires heap allocation
|
||||
->ArgPair(1024, 256);
|
||||
|
||||
// Benchmarks for OStringStream.
|
||||
template <StringType kOutput>
|
||||
void BM_CustomStream(benchmark::State& state) {
|
||||
const int num_writes = state.range(0);
|
||||
const int bytes_per_write = state.range(1);
|
||||
const std::string payload(bytes_per_write, 'x');
|
||||
for (auto _ : state) {
|
||||
std::string out;
|
||||
absl::strings_internal::OStringStream strm(&out);
|
||||
benchmark::DoNotOptimize(strm);
|
||||
for (int i = 0; i != num_writes; ++i) {
|
||||
strm << payload;
|
||||
}
|
||||
switch (kOutput) {
|
||||
case kNone: {
|
||||
break;
|
||||
}
|
||||
case kStdString: {
|
||||
std::string s = out;
|
||||
benchmark::DoNotOptimize(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the stream, optionally write to it, then destroy it.
|
||||
BENCHMARK_TEMPLATE(BM_CustomStream, kNone)
|
||||
->ArgPair(0, 0)
|
||||
->ArgPair(1, 16) // 16 bytes is small enough for SSO
|
||||
->ArgPair(1, 256) // 256 bytes requires heap allocation
|
||||
->ArgPair(1024, 256);
|
||||
// Create the stream, write to it, get std::string out, then destroy.
|
||||
// It's not useful in practice to extract std::string from OStringStream; we
|
||||
// measure it for completeness.
|
||||
BENCHMARK_TEMPLATE(BM_CustomStream, kStdString)
|
||||
->ArgPair(1, 16) // 16 bytes is small enough for SSO
|
||||
->ArgPair(1, 256) // 256 bytes requires heap allocation
|
||||
->ArgPair(1024, 256);
|
||||
|
||||
} // namespace
|
||||
@ -52,12 +52,16 @@ ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out);
|
||||
//
|
||||
// Converts the given std::string (optionally followed or preceded by ASCII
|
||||
// whitespace) into a float, which may be rounded on overflow or underflow.
|
||||
// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the
|
||||
// allowed formats for `str`.
|
||||
ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* value);
|
||||
|
||||
// SimpleAtod()
|
||||
//
|
||||
// Converts the given std::string (optionally followed or preceded by ASCII
|
||||
// whitespace) into a double, which may be rounded on overflow or underflow.
|
||||
// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the
|
||||
// allowed formats for `str`.
|
||||
ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* value);
|
||||
|
||||
// SimpleAtob()
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
|
||||
#include "absl/strings/internal/numbers_test_common.inc"
|
||||
#include "absl/strings/internal/numbers_test_common.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -48,6 +48,9 @@ using absl::numbers_internal::safe_strto64_base;
|
||||
using absl::numbers_internal::safe_strtou32_base;
|
||||
using absl::numbers_internal::safe_strtou64_base;
|
||||
using absl::numbers_internal::SixDigitsToBuffer;
|
||||
using absl::strings_internal::Itoa;
|
||||
using absl::strings_internal::strtouint32_test_cases;
|
||||
using absl::strings_internal::strtouint64_test_cases;
|
||||
using absl::SimpleAtoi;
|
||||
using testing::Eq;
|
||||
using testing::MatchesRegex;
|
||||
@ -119,7 +122,7 @@ TEST(ToString, PerfectDtoa) {
|
||||
{1e-300, 1e-200, 1e-100, 0.1, 1.0, 10.0, 1e100, 1e300}) {
|
||||
double d = multiplier * i;
|
||||
std::string s = PerfectDtoa(d);
|
||||
EXPECT_EQ(d, strtod(s.c_str(), nullptr));
|
||||
EXPECT_DOUBLE_EQ(d, strtod(s.c_str(), nullptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -654,8 +657,8 @@ TEST(stringtest, safe_strtou64_random) {
|
||||
}
|
||||
|
||||
TEST(stringtest, safe_strtou32_base) {
|
||||
for (int i = 0; strtouint32_test_cases[i].str != nullptr; ++i) {
|
||||
const auto& e = strtouint32_test_cases[i];
|
||||
for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
|
||||
const auto& e = strtouint32_test_cases()[i];
|
||||
uint32_t value;
|
||||
EXPECT_EQ(e.expect_ok, safe_strtou32_base(e.str, &value, e.base))
|
||||
<< "str=\"" << e.str << "\" base=" << e.base;
|
||||
@ -667,8 +670,8 @@ TEST(stringtest, safe_strtou32_base) {
|
||||
}
|
||||
|
||||
TEST(stringtest, safe_strtou32_base_length_delimited) {
|
||||
for (int i = 0; strtouint32_test_cases[i].str != nullptr; ++i) {
|
||||
const auto& e = strtouint32_test_cases[i];
|
||||
for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
|
||||
const auto& e = strtouint32_test_cases()[i];
|
||||
std::string tmp(e.str);
|
||||
tmp.append("12"); // Adds garbage at the end.
|
||||
|
||||
@ -685,8 +688,8 @@ TEST(stringtest, safe_strtou32_base_length_delimited) {
|
||||
}
|
||||
|
||||
TEST(stringtest, safe_strtou64_base) {
|
||||
for (int i = 0; strtouint64_test_cases[i].str != nullptr; ++i) {
|
||||
const auto& e = strtouint64_test_cases[i];
|
||||
for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
|
||||
const auto& e = strtouint64_test_cases()[i];
|
||||
uint64_t value;
|
||||
EXPECT_EQ(e.expect_ok, safe_strtou64_base(e.str, &value, e.base))
|
||||
<< "str=\"" << e.str << "\" base=" << e.base;
|
||||
@ -697,8 +700,8 @@ TEST(stringtest, safe_strtou64_base) {
|
||||
}
|
||||
|
||||
TEST(stringtest, safe_strtou64_base_length_delimited) {
|
||||
for (int i = 0; strtouint64_test_cases[i].str != nullptr; ++i) {
|
||||
const auto& e = strtouint64_test_cases[i];
|
||||
for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
|
||||
const auto& e = strtouint64_test_cases()[i];
|
||||
std::string tmp(e.str);
|
||||
tmp.append("12"); // Adds garbage at the end.
|
||||
|
||||
|
||||
@ -138,5 +138,3 @@ void BM_DoubleToString_By_SixDigits(benchmark::State& state) {
|
||||
BENCHMARK(BM_DoubleToString_By_SixDigits);
|
||||
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
@ -22,6 +22,15 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/substitute.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
// Android assert messages only go to system log, so death tests cannot inspect
|
||||
// the message for matching.
|
||||
#define ABSL_EXPECT_DEBUG_DEATH(statement, regex) \
|
||||
EXPECT_DEBUG_DEATH(statement, ".*")
|
||||
#else
|
||||
#define ABSL_EXPECT_DEBUG_DEATH EXPECT_DEBUG_DEATH
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// Test absl::StrCat of ints and longs of various sizes and signdedness.
|
||||
@ -396,8 +405,9 @@ TEST(StrAppend, Death) {
|
||||
std::string s = "self";
|
||||
// on linux it's "assertion", on mac it's "Assertion",
|
||||
// on chromiumos it's "Assertion ... failed".
|
||||
EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s.c_str() + 1), "ssertion.*failed");
|
||||
EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s), "ssertion.*failed");
|
||||
ABSL_EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s.c_str() + 1),
|
||||
"ssertion.*failed");
|
||||
ABSL_EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s), "ssertion.*failed");
|
||||
}
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
|
||||
@ -94,5 +94,3 @@ BENCHMARK(BM_JoinStreamable)
|
||||
->ArgPair(256, 256);
|
||||
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
@ -120,5 +120,3 @@ void BM_StrReplaceAll(benchmark::State& state) {
|
||||
BENCHMARK(BM_StrReplaceAll);
|
||||
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
@ -154,5 +154,3 @@ BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharLiteral);
|
||||
BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharStringLiteral);
|
||||
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
@ -327,5 +327,3 @@ void BM_AppendToStringNative(benchmark::State& state) {
|
||||
BENCHMARK(BM_AppendToStringNative)->Range(1 << 3, 1 << 12);
|
||||
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
@ -29,6 +29,15 @@
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/dynamic_annotations.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
// Android assert messages only go to system log, so death tests cannot inspect
|
||||
// the message for matching.
|
||||
#define ABSL_EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
EXPECT_DEATH_IF_SUPPORTED(statement, ".*")
|
||||
#else
|
||||
#define ABSL_EXPECT_DEATH_IF_SUPPORTED EXPECT_DEATH_IF_SUPPORTED
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// A minimal allocator that uses malloc().
|
||||
@ -1068,7 +1077,8 @@ TEST(HugeStringView, TwoPointTwoGB) {
|
||||
|
||||
#if !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW)
|
||||
TEST(NonNegativeLenTest, NonNegativeLen) {
|
||||
EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1), "len <= kMaxSize");
|
||||
ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1),
|
||||
"len <= kMaxSize");
|
||||
}
|
||||
|
||||
TEST(LenExceedsMaxSizeTest, LenExceedsMaxSize) {
|
||||
@ -1078,8 +1088,8 @@ TEST(LenExceedsMaxSizeTest, LenExceedsMaxSize) {
|
||||
absl::string_view ok_view("", max_size);
|
||||
|
||||
// Adding one to the max should trigger an assertion.
|
||||
EXPECT_DEATH_IF_SUPPORTED(absl::string_view("", max_size + 1),
|
||||
"len <= kMaxSize");
|
||||
ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("", max_size + 1),
|
||||
"len <= kMaxSize");
|
||||
}
|
||||
#endif // !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW)
|
||||
|
||||
|
||||
@ -99,7 +99,10 @@ class Arg {
|
||||
// Explicitly overload `const char*` so the compiler doesn't cast to `bool`.
|
||||
Arg(const char* value) // NOLINT(runtime/explicit)
|
||||
: piece_(absl::NullSafeStringView(value)) {}
|
||||
Arg(const std::string& value) // NOLINT(runtime/explicit)
|
||||
template <typename Allocator>
|
||||
Arg( // NOLINT
|
||||
const std::basic_string<char, std::char_traits<char>, Allocator>&
|
||||
value) noexcept
|
||||
: piece_(value) {}
|
||||
Arg(absl::string_view value) // NOLINT(runtime/explicit)
|
||||
: piece_(value) {}
|
||||
|
||||
@ -130,7 +130,7 @@ cc_test(
|
||||
deps = [
|
||||
":graphcycles_internal",
|
||||
"//absl/base",
|
||||
"@com_github_google_benchmark//:benchmark",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
@ -150,6 +150,9 @@ cc_test(
|
||||
srcs = ["mutex_test.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = [
|
||||
"no_test_android_arm",
|
||||
"no_test_android_arm64",
|
||||
"no_test_android_x86",
|
||||
"no_test_loonix", # Too slow.
|
||||
],
|
||||
deps = [
|
||||
@ -173,7 +176,7 @@ cc_test(
|
||||
":synchronization",
|
||||
":thread_pool",
|
||||
"//absl/base",
|
||||
"@com_github_google_benchmark//:benchmark",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@ -133,4 +133,5 @@ class GraphCycles {
|
||||
|
||||
} // namespace synchronization_internal
|
||||
} // namespace absl
|
||||
|
||||
#endif
|
||||
|
||||
@ -42,5 +42,3 @@ void BM_StressTest(benchmark::State& state) {
|
||||
BENCHMARK(BM_StressTest)->Range(2048, 1048576);
|
||||
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
@ -92,5 +92,3 @@ BENCHMARK(BM_ContendedMutex)->Threads(1);
|
||||
BENCHMARK(BM_ContendedMutex)->ThreadPerCpu();
|
||||
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
24
third_party/abseil-cpp/absl/time/BUILD.bazel
vendored
24
third_party/abseil-cpp/absl/time/BUILD.bazel
vendored
@ -81,10 +81,6 @@ cc_test(
|
||||
],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = [
|
||||
"no_test_android_arm",
|
||||
"no_test_android_arm64",
|
||||
"no_test_android_x86",
|
||||
"no_test_ios_x86_64",
|
||||
"no_test_loonix",
|
||||
],
|
||||
deps = [
|
||||
@ -97,3 +93,23 @@ cc_test(
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "time_benchmark",
|
||||
srcs = [
|
||||
"clock_benchmark.cc",
|
||||
"duration_benchmark.cc",
|
||||
"format_benchmark.cc",
|
||||
"time_benchmark.cc",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = [
|
||||
"benchmark",
|
||||
],
|
||||
deps = [
|
||||
":test_util",
|
||||
":time",
|
||||
"//absl/base",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
72
third_party/abseil-cpp/absl/time/clock_benchmark.cc
vendored
Normal file
72
third_party/abseil-cpp/absl/time/clock_benchmark.cc
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
// Copyright 2018 The Abseil Authors.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://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/time/clock.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <sys/time.h>
|
||||
#endif // _WIN32
|
||||
#include <cstdio>
|
||||
|
||||
#include "absl/base/internal/cycleclock.h"
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void BM_Clock_Now_AbslTime(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::Now());
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Clock_Now_AbslTime);
|
||||
|
||||
void BM_Clock_Now_GetCurrentTimeNanos(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::GetCurrentTimeNanos());
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Clock_Now_GetCurrentTimeNanos);
|
||||
|
||||
void BM_Clock_Now_AbslTime_ToUnixNanos(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ToUnixNanos(absl::Now()));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Clock_Now_AbslTime_ToUnixNanos);
|
||||
|
||||
void BM_Clock_Now_CycleClock(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::base_internal::CycleClock::Now());
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Clock_Now_CycleClock);
|
||||
|
||||
#if !defined(_WIN32)
|
||||
static void BM_Clock_Now_gettimeofday(benchmark::State& state) {
|
||||
struct timeval tv;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(gettimeofday(&tv, nullptr));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Clock_Now_gettimeofday);
|
||||
|
||||
static void BM_Clock_Now_clock_gettime(benchmark::State& state) {
|
||||
struct timespec ts;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(clock_gettime(CLOCK_REALTIME, &ts));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Clock_Now_clock_gettime);
|
||||
#endif // _WIN32
|
||||
|
||||
} // namespace
|
||||
361
third_party/abseil-cpp/absl/time/duration_benchmark.cc
vendored
Normal file
361
third_party/abseil-cpp/absl/time/duration_benchmark.cc
vendored
Normal file
@ -0,0 +1,361 @@
|
||||
// Copyright 2018 The Abseil Authors.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://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 <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
|
||||
#include "absl/time/time.h"
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
namespace {
|
||||
|
||||
//
|
||||
// Factory functions
|
||||
//
|
||||
|
||||
void BM_Duration_Factory_Nanoseconds(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::Nanoseconds(1));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Factory_Nanoseconds);
|
||||
|
||||
void BM_Duration_Factory_Microseconds(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::Microseconds(1));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Factory_Microseconds);
|
||||
|
||||
void BM_Duration_Factory_Milliseconds(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::Milliseconds(1));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Factory_Milliseconds);
|
||||
|
||||
void BM_Duration_Factory_Seconds(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::Seconds(1));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Factory_Seconds);
|
||||
|
||||
void BM_Duration_Factory_Minutes(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::Minutes(1));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Factory_Minutes);
|
||||
|
||||
void BM_Duration_Factory_Hours(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::Hours(1));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Factory_Hours);
|
||||
|
||||
//
|
||||
// Arithmetic
|
||||
//
|
||||
|
||||
void BM_Duration_Addition(benchmark::State& state) {
|
||||
absl::Duration d = absl::Nanoseconds(1);
|
||||
absl::Duration step = absl::Milliseconds(1);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(d += step);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Addition);
|
||||
|
||||
void BM_Duration_Subtraction(benchmark::State& state) {
|
||||
absl::Duration d = absl::Seconds(std::numeric_limits<int64_t>::max());
|
||||
absl::Duration step = absl::Milliseconds(1);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(d -= step);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Subtraction);
|
||||
|
||||
void BM_Duration_Multiplication_Fixed(benchmark::State& state) {
|
||||
absl::Duration d = absl::Milliseconds(1);
|
||||
absl::Duration s;
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(s += d * (i + 1));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Multiplication_Fixed);
|
||||
|
||||
void BM_Duration_Multiplication_Double(benchmark::State& state) {
|
||||
absl::Duration d = absl::Milliseconds(1);
|
||||
absl::Duration s;
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(s += d * (i + 1.0));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Multiplication_Double);
|
||||
|
||||
void BM_Duration_Division_Fixed(benchmark::State& state) {
|
||||
absl::Duration d = absl::Seconds(1);
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(d /= i + 1);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Division_Fixed);
|
||||
|
||||
void BM_Duration_Division_Double(benchmark::State& state) {
|
||||
absl::Duration d = absl::Seconds(1);
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(d /= i + 1.0);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_Division_Double);
|
||||
|
||||
void BM_Duration_FDivDuration_Nanoseconds(benchmark::State& state) {
|
||||
double d = 1;
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(
|
||||
d += absl::FDivDuration(absl::Milliseconds(i), absl::Nanoseconds(1)));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_FDivDuration_Nanoseconds);
|
||||
|
||||
void BM_Duration_IDivDuration_Nanoseconds(benchmark::State& state) {
|
||||
int64_t a = 1;
|
||||
absl::Duration ignore;
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(a +=
|
||||
absl::IDivDuration(absl::Nanoseconds(i),
|
||||
absl::Nanoseconds(1), &ignore));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_IDivDuration_Nanoseconds);
|
||||
|
||||
void BM_Duration_IDivDuration_Microseconds(benchmark::State& state) {
|
||||
int64_t a = 1;
|
||||
absl::Duration ignore;
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(a += absl::IDivDuration(absl::Microseconds(i),
|
||||
absl::Microseconds(1),
|
||||
&ignore));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_IDivDuration_Microseconds);
|
||||
|
||||
void BM_Duration_IDivDuration_Milliseconds(benchmark::State& state) {
|
||||
int64_t a = 1;
|
||||
absl::Duration ignore;
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(a += absl::IDivDuration(absl::Milliseconds(i),
|
||||
absl::Milliseconds(1),
|
||||
&ignore));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_IDivDuration_Milliseconds);
|
||||
|
||||
void BM_Duration_IDivDuration_Seconds(benchmark::State& state) {
|
||||
int64_t a = 1;
|
||||
absl::Duration ignore;
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(
|
||||
a += absl::IDivDuration(absl::Seconds(i), absl::Seconds(1), &ignore));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_IDivDuration_Seconds);
|
||||
|
||||
void BM_Duration_IDivDuration_Minutes(benchmark::State& state) {
|
||||
int64_t a = 1;
|
||||
absl::Duration ignore;
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(
|
||||
a += absl::IDivDuration(absl::Minutes(i), absl::Minutes(1), &ignore));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_IDivDuration_Minutes);
|
||||
|
||||
void BM_Duration_IDivDuration_Hours(benchmark::State& state) {
|
||||
int64_t a = 1;
|
||||
absl::Duration ignore;
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(
|
||||
a += absl::IDivDuration(absl::Hours(i), absl::Hours(1), &ignore));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_IDivDuration_Hours);
|
||||
|
||||
void BM_Duration_ToInt64Nanoseconds(benchmark::State& state) {
|
||||
absl::Duration d = absl::Seconds(100000);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ToInt64Nanoseconds(d));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_ToInt64Nanoseconds);
|
||||
|
||||
void BM_Duration_ToInt64Microseconds(benchmark::State& state) {
|
||||
absl::Duration d = absl::Seconds(100000);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ToInt64Microseconds(d));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_ToInt64Microseconds);
|
||||
|
||||
void BM_Duration_ToInt64Milliseconds(benchmark::State& state) {
|
||||
absl::Duration d = absl::Seconds(100000);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ToInt64Milliseconds(d));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_ToInt64Milliseconds);
|
||||
|
||||
void BM_Duration_ToInt64Seconds(benchmark::State& state) {
|
||||
absl::Duration d = absl::Seconds(100000);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ToInt64Seconds(d));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_ToInt64Seconds);
|
||||
|
||||
void BM_Duration_ToInt64Minutes(benchmark::State& state) {
|
||||
absl::Duration d = absl::Seconds(100000);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ToInt64Minutes(d));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_ToInt64Minutes);
|
||||
|
||||
void BM_Duration_ToInt64Hours(benchmark::State& state) {
|
||||
absl::Duration d = absl::Seconds(100000);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ToInt64Hours(d));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_ToInt64Hours);
|
||||
|
||||
//
|
||||
// To/FromTimespec
|
||||
//
|
||||
|
||||
void BM_Duration_ToTimespec_AbslTime(benchmark::State& state) {
|
||||
absl::Duration d = absl::Seconds(1);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ToTimespec(d));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_ToTimespec_AbslTime);
|
||||
|
||||
ABSL_ATTRIBUTE_NOINLINE timespec DoubleToTimespec(double seconds) {
|
||||
timespec ts;
|
||||
ts.tv_sec = seconds;
|
||||
ts.tv_nsec = (seconds - ts.tv_sec) * (1000 * 1000 * 1000);
|
||||
return ts;
|
||||
}
|
||||
|
||||
void BM_Duration_ToTimespec_Double(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(DoubleToTimespec(1.0));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_ToTimespec_Double);
|
||||
|
||||
void BM_Duration_FromTimespec_AbslTime(benchmark::State& state) {
|
||||
timespec ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
while (state.KeepRunning()) {
|
||||
if (++ts.tv_nsec == 1000 * 1000 * 1000) {
|
||||
++ts.tv_sec;
|
||||
ts.tv_nsec = 0;
|
||||
}
|
||||
benchmark::DoNotOptimize(absl::DurationFromTimespec(ts));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_FromTimespec_AbslTime);
|
||||
|
||||
ABSL_ATTRIBUTE_NOINLINE double TimespecToDouble(timespec ts) {
|
||||
return ts.tv_sec + (ts.tv_nsec / (1000 * 1000 * 1000));
|
||||
}
|
||||
|
||||
void BM_Duration_FromTimespec_Double(benchmark::State& state) {
|
||||
timespec ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
while (state.KeepRunning()) {
|
||||
if (++ts.tv_nsec == 1000 * 1000 * 1000) {
|
||||
++ts.tv_sec;
|
||||
ts.tv_nsec = 0;
|
||||
}
|
||||
benchmark::DoNotOptimize(TimespecToDouble(ts));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_FromTimespec_Double);
|
||||
|
||||
//
|
||||
// String conversions
|
||||
//
|
||||
|
||||
const char* const kDurations[] = {
|
||||
"0", // 0
|
||||
"123ns", // 1
|
||||
"1h2m3s", // 2
|
||||
"-2h3m4.005006007s", // 3
|
||||
"2562047788015215h30m7.99999999975s", // 4
|
||||
};
|
||||
const int kNumDurations = sizeof(kDurations) / sizeof(kDurations[0]);
|
||||
|
||||
void BM_Duration_FormatDuration(benchmark::State& state) {
|
||||
const std::string s = kDurations[state.range(0)];
|
||||
state.SetLabel(s);
|
||||
absl::Duration d;
|
||||
absl::ParseDuration(kDurations[state.range(0)], &d);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::FormatDuration(d));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_FormatDuration)->DenseRange(0, kNumDurations - 1);
|
||||
|
||||
void BM_Duration_ParseDuration(benchmark::State& state) {
|
||||
const std::string s = kDurations[state.range(0)];
|
||||
state.SetLabel(s);
|
||||
absl::Duration d;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ParseDuration(s, &d));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Duration_ParseDuration)->DenseRange(0, kNumDurations - 1);
|
||||
|
||||
} // namespace
|
||||
@ -330,18 +330,10 @@ TEST(Duration, ToChrono) {
|
||||
EXPECT_EQ(hours::max(), absl::ToChronoHours(inf));
|
||||
}
|
||||
|
||||
// Used for testing the factory overloads.
|
||||
template <typename T>
|
||||
struct ImplicitlyConvertible {
|
||||
T n_;
|
||||
explicit ImplicitlyConvertible(T n) : n_(n) {}
|
||||
// Marking this conversion operator with 'explicit' will cause the test to
|
||||
// fail (as desired).
|
||||
operator T() { return n_; }
|
||||
};
|
||||
|
||||
TEST(Duration, FactoryOverloads) {
|
||||
enum E { kOne = 1 };
|
||||
#define TEST_FACTORY_OVERLOADS(NAME) \
|
||||
EXPECT_EQ(1, NAME(kOne) / NAME(kOne)); \
|
||||
EXPECT_EQ(1, NAME(static_cast<int8_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(static_cast<int16_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(static_cast<int32_t>(1)) / NAME(1)); \
|
||||
@ -350,14 +342,6 @@ TEST(Duration, FactoryOverloads) {
|
||||
EXPECT_EQ(1, NAME(static_cast<uint16_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(static_cast<uint32_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(static_cast<uint64_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(ImplicitlyConvertible<int8_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(ImplicitlyConvertible<int16_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(ImplicitlyConvertible<int32_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(ImplicitlyConvertible<int64_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint8_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint16_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint32_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint64_t>(1)) / NAME(1)); \
|
||||
EXPECT_EQ(NAME(1) / 2, NAME(static_cast<float>(0.5))); \
|
||||
EXPECT_EQ(NAME(1) / 2, NAME(static_cast<double>(0.5))); \
|
||||
EXPECT_EQ(1.5, absl::FDivDuration(NAME(static_cast<float>(1.5)), NAME(1))); \
|
||||
|
||||
63
third_party/abseil-cpp/absl/time/format_benchmark.cc
vendored
Normal file
63
third_party/abseil-cpp/absl/time/format_benchmark.cc
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright 2018 The Abseil Authors.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://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 <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include "absl/time/internal/test_util.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
namespace {
|
||||
|
||||
namespace {
|
||||
const char* const kFormats[] = {
|
||||
absl::RFC1123_full, // 0
|
||||
absl::RFC1123_no_wday, // 1
|
||||
absl::RFC3339_full, // 2
|
||||
absl::RFC3339_sec, // 3
|
||||
"%Y-%m-%dT%H:%M:%S", // 4
|
||||
"%Y-%m-%d", // 5
|
||||
};
|
||||
const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
|
||||
} // namespace
|
||||
|
||||
void BM_Format_FormatTime(benchmark::State& state) {
|
||||
const std::string fmt = kFormats[state.range(0)];
|
||||
state.SetLabel(fmt);
|
||||
const absl::TimeZone lax =
|
||||
absl::time_internal::LoadTimeZone("America/Los_Angeles");
|
||||
const absl::Time t =
|
||||
absl::FromDateTime(1977, 6, 28, 9, 8, 7, lax) + absl::Nanoseconds(1);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::FormatTime(fmt, t, lax).length());
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Format_FormatTime)->DenseRange(0, kNumFormats - 1);
|
||||
|
||||
void BM_Format_ParseTime(benchmark::State& state) {
|
||||
const std::string fmt = kFormats[state.range(0)];
|
||||
state.SetLabel(fmt);
|
||||
const absl::TimeZone lax =
|
||||
absl::time_internal::LoadTimeZone("America/Los_Angeles");
|
||||
absl::Time t =
|
||||
absl::FromDateTime(1977, 6, 28, 9, 8, 7, lax) + absl::Nanoseconds(1);
|
||||
const std::string when = absl::FormatTime(fmt, t, lax);
|
||||
std::string err;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ParseTime(fmt, when, lax, &t, &err));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Format_ParseTime)->DenseRange(0, kNumFormats - 1);
|
||||
|
||||
} // namespace
|
||||
@ -81,6 +81,11 @@ cc_test(
|
||||
size = "small",
|
||||
srcs = ["src/time_zone_format_test.cc"],
|
||||
data = [":zoneinfo"],
|
||||
tags = [
|
||||
"no_test_android_arm",
|
||||
"no_test_android_arm64",
|
||||
"no_test_android_x86",
|
||||
],
|
||||
deps = [
|
||||
":civil_time",
|
||||
":time_zone",
|
||||
@ -93,6 +98,11 @@ cc_test(
|
||||
size = "small",
|
||||
srcs = ["src/time_zone_lookup_test.cc"],
|
||||
data = [":zoneinfo"],
|
||||
tags = [
|
||||
"no_test_android_arm",
|
||||
"no_test_android_arm64",
|
||||
"no_test_android_x86",
|
||||
],
|
||||
deps = [
|
||||
":civil_time",
|
||||
":time_zone",
|
||||
@ -102,6 +112,24 @@ cc_test(
|
||||
|
||||
### benchmarks
|
||||
|
||||
cc_test(
|
||||
name = "cctz_benchmark",
|
||||
srcs = [
|
||||
"src/cctz_benchmark.cc",
|
||||
"src/time_zone_if.h",
|
||||
"src/time_zone_impl.h",
|
||||
"src/time_zone_info.h",
|
||||
"src/tzfile.h",
|
||||
],
|
||||
linkstatic = 1,
|
||||
tags = ["benchmark"],
|
||||
deps = [
|
||||
":civil_time",
|
||||
":time_zone",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
### examples
|
||||
|
||||
### binaries
|
||||
|
||||
982
third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc
vendored
Normal file
982
third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc
vendored
Normal file
@ -0,0 +1,982 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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 <algorithm>
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
|
||||
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
|
||||
#include "time_zone_impl.h"
|
||||
|
||||
namespace {
|
||||
|
||||
namespace cctz = absl::time_internal::cctz;
|
||||
|
||||
void BM_Difference_Days(benchmark::State& state) {
|
||||
const cctz::civil_day c(2014, 8, 22);
|
||||
const cctz::civil_day epoch(1970, 1, 1);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(c - epoch);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Difference_Days);
|
||||
|
||||
void BM_Step_Days(benchmark::State& state) {
|
||||
const cctz::civil_day kStart(2014, 8, 22);
|
||||
cctz::civil_day c = kStart;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(++c);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Step_Days);
|
||||
|
||||
const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
|
||||
const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
|
||||
|
||||
const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z";
|
||||
const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z";
|
||||
|
||||
// A list of known time-zone names.
|
||||
// TODO: Refactor with src/time_zone_lookup_test.cc.
|
||||
const char* const kTimeZoneNames[] = {
|
||||
"Africa/Abidjan",
|
||||
"Africa/Accra",
|
||||
"Africa/Addis_Ababa",
|
||||
"Africa/Algiers",
|
||||
"Africa/Asmara",
|
||||
"Africa/Asmera",
|
||||
"Africa/Bamako",
|
||||
"Africa/Bangui",
|
||||
"Africa/Banjul",
|
||||
"Africa/Bissau",
|
||||
"Africa/Blantyre",
|
||||
"Africa/Brazzaville",
|
||||
"Africa/Bujumbura",
|
||||
"Africa/Cairo",
|
||||
"Africa/Casablanca",
|
||||
"Africa/Ceuta",
|
||||
"Africa/Conakry",
|
||||
"Africa/Dakar",
|
||||
"Africa/Dar_es_Salaam",
|
||||
"Africa/Djibouti",
|
||||
"Africa/Douala",
|
||||
"Africa/El_Aaiun",
|
||||
"Africa/Freetown",
|
||||
"Africa/Gaborone",
|
||||
"Africa/Harare",
|
||||
"Africa/Johannesburg",
|
||||
"Africa/Juba",
|
||||
"Africa/Kampala",
|
||||
"Africa/Khartoum",
|
||||
"Africa/Kigali",
|
||||
"Africa/Kinshasa",
|
||||
"Africa/Lagos",
|
||||
"Africa/Libreville",
|
||||
"Africa/Lome",
|
||||
"Africa/Luanda",
|
||||
"Africa/Lubumbashi",
|
||||
"Africa/Lusaka",
|
||||
"Africa/Malabo",
|
||||
"Africa/Maputo",
|
||||
"Africa/Maseru",
|
||||
"Africa/Mbabane",
|
||||
"Africa/Mogadishu",
|
||||
"Africa/Monrovia",
|
||||
"Africa/Nairobi",
|
||||
"Africa/Ndjamena",
|
||||
"Africa/Niamey",
|
||||
"Africa/Nouakchott",
|
||||
"Africa/Ouagadougou",
|
||||
"Africa/Porto-Novo",
|
||||
"Africa/Sao_Tome",
|
||||
"Africa/Timbuktu",
|
||||
"Africa/Tripoli",
|
||||
"Africa/Tunis",
|
||||
"Africa/Windhoek",
|
||||
"America/Adak",
|
||||
"America/Anchorage",
|
||||
"America/Anguilla",
|
||||
"America/Antigua",
|
||||
"America/Araguaina",
|
||||
"America/Argentina/Buenos_Aires",
|
||||
"America/Argentina/Catamarca",
|
||||
"America/Argentina/ComodRivadavia",
|
||||
"America/Argentina/Cordoba",
|
||||
"America/Argentina/Jujuy",
|
||||
"America/Argentina/La_Rioja",
|
||||
"America/Argentina/Mendoza",
|
||||
"America/Argentina/Rio_Gallegos",
|
||||
"America/Argentina/Salta",
|
||||
"America/Argentina/San_Juan",
|
||||
"America/Argentina/San_Luis",
|
||||
"America/Argentina/Tucuman",
|
||||
"America/Argentina/Ushuaia",
|
||||
"America/Aruba",
|
||||
"America/Asuncion",
|
||||
"America/Atikokan",
|
||||
"America/Atka",
|
||||
"America/Bahia",
|
||||
"America/Bahia_Banderas",
|
||||
"America/Barbados",
|
||||
"America/Belem",
|
||||
"America/Belize",
|
||||
"America/Blanc-Sablon",
|
||||
"America/Boa_Vista",
|
||||
"America/Bogota",
|
||||
"America/Boise",
|
||||
"America/Buenos_Aires",
|
||||
"America/Cambridge_Bay",
|
||||
"America/Campo_Grande",
|
||||
"America/Cancun",
|
||||
"America/Caracas",
|
||||
"America/Catamarca",
|
||||
"America/Cayenne",
|
||||
"America/Cayman",
|
||||
"America/Chicago",
|
||||
"America/Chihuahua",
|
||||
"America/Coral_Harbour",
|
||||
"America/Cordoba",
|
||||
"America/Costa_Rica",
|
||||
"America/Creston",
|
||||
"America/Cuiaba",
|
||||
"America/Curacao",
|
||||
"America/Danmarkshavn",
|
||||
"America/Dawson",
|
||||
"America/Dawson_Creek",
|
||||
"America/Denver",
|
||||
"America/Detroit",
|
||||
"America/Dominica",
|
||||
"America/Edmonton",
|
||||
"America/Eirunepe",
|
||||
"America/El_Salvador",
|
||||
"America/Ensenada",
|
||||
"America/Fort_Nelson",
|
||||
"America/Fort_Wayne",
|
||||
"America/Fortaleza",
|
||||
"America/Glace_Bay",
|
||||
"America/Godthab",
|
||||
"America/Goose_Bay",
|
||||
"America/Grand_Turk",
|
||||
"America/Grenada",
|
||||
"America/Guadeloupe",
|
||||
"America/Guatemala",
|
||||
"America/Guayaquil",
|
||||
"America/Guyana",
|
||||
"America/Halifax",
|
||||
"America/Havana",
|
||||
"America/Hermosillo",
|
||||
"America/Indiana/Indianapolis",
|
||||
"America/Indiana/Knox",
|
||||
"America/Indiana/Marengo",
|
||||
"America/Indiana/Petersburg",
|
||||
"America/Indiana/Tell_City",
|
||||
"America/Indiana/Vevay",
|
||||
"America/Indiana/Vincennes",
|
||||
"America/Indiana/Winamac",
|
||||
"America/Indianapolis",
|
||||
"America/Inuvik",
|
||||
"America/Iqaluit",
|
||||
"America/Jamaica",
|
||||
"America/Jujuy",
|
||||
"America/Juneau",
|
||||
"America/Kentucky/Louisville",
|
||||
"America/Kentucky/Monticello",
|
||||
"America/Knox_IN",
|
||||
"America/Kralendijk",
|
||||
"America/La_Paz",
|
||||
"America/Lima",
|
||||
"America/Los_Angeles",
|
||||
"America/Louisville",
|
||||
"America/Lower_Princes",
|
||||
"America/Maceio",
|
||||
"America/Managua",
|
||||
"America/Manaus",
|
||||
"America/Marigot",
|
||||
"America/Martinique",
|
||||
"America/Matamoros",
|
||||
"America/Mazatlan",
|
||||
"America/Mendoza",
|
||||
"America/Menominee",
|
||||
"America/Merida",
|
||||
"America/Metlakatla",
|
||||
"America/Mexico_City",
|
||||
"America/Miquelon",
|
||||
"America/Moncton",
|
||||
"America/Monterrey",
|
||||
"America/Montevideo",
|
||||
"America/Montreal",
|
||||
"America/Montserrat",
|
||||
"America/Nassau",
|
||||
"America/New_York",
|
||||
"America/Nipigon",
|
||||
"America/Nome",
|
||||
"America/Noronha",
|
||||
"America/North_Dakota/Beulah",
|
||||
"America/North_Dakota/Center",
|
||||
"America/North_Dakota/New_Salem",
|
||||
"America/Ojinaga",
|
||||
"America/Panama",
|
||||
"America/Pangnirtung",
|
||||
"America/Paramaribo",
|
||||
"America/Phoenix",
|
||||
"America/Port-au-Prince",
|
||||
"America/Port_of_Spain",
|
||||
"America/Porto_Acre",
|
||||
"America/Porto_Velho",
|
||||
"America/Puerto_Rico",
|
||||
"America/Punta_Arenas",
|
||||
"America/Rainy_River",
|
||||
"America/Rankin_Inlet",
|
||||
"America/Recife",
|
||||
"America/Regina",
|
||||
"America/Resolute",
|
||||
"America/Rio_Branco",
|
||||
"America/Rosario",
|
||||
"America/Santa_Isabel",
|
||||
"America/Santarem",
|
||||
"America/Santiago",
|
||||
"America/Santo_Domingo",
|
||||
"America/Sao_Paulo",
|
||||
"America/Scoresbysund",
|
||||
"America/Shiprock",
|
||||
"America/Sitka",
|
||||
"America/St_Barthelemy",
|
||||
"America/St_Johns",
|
||||
"America/St_Kitts",
|
||||
"America/St_Lucia",
|
||||
"America/St_Thomas",
|
||||
"America/St_Vincent",
|
||||
"America/Swift_Current",
|
||||
"America/Tegucigalpa",
|
||||
"America/Thule",
|
||||
"America/Thunder_Bay",
|
||||
"America/Tijuana",
|
||||
"America/Toronto",
|
||||
"America/Tortola",
|
||||
"America/Vancouver",
|
||||
"America/Virgin",
|
||||
"America/Whitehorse",
|
||||
"America/Winnipeg",
|
||||
"America/Yakutat",
|
||||
"America/Yellowknife",
|
||||
"Antarctica/Casey",
|
||||
"Antarctica/Davis",
|
||||
"Antarctica/DumontDUrville",
|
||||
"Antarctica/Macquarie",
|
||||
"Antarctica/Mawson",
|
||||
"Antarctica/McMurdo",
|
||||
"Antarctica/Palmer",
|
||||
"Antarctica/Rothera",
|
||||
"Antarctica/South_Pole",
|
||||
"Antarctica/Syowa",
|
||||
"Antarctica/Troll",
|
||||
"Antarctica/Vostok",
|
||||
"Arctic/Longyearbyen",
|
||||
"Asia/Aden",
|
||||
"Asia/Almaty",
|
||||
"Asia/Amman",
|
||||
"Asia/Anadyr",
|
||||
"Asia/Aqtau",
|
||||
"Asia/Aqtobe",
|
||||
"Asia/Ashgabat",
|
||||
"Asia/Ashkhabad",
|
||||
"Asia/Atyrau",
|
||||
"Asia/Baghdad",
|
||||
"Asia/Bahrain",
|
||||
"Asia/Baku",
|
||||
"Asia/Bangkok",
|
||||
"Asia/Barnaul",
|
||||
"Asia/Beirut",
|
||||
"Asia/Bishkek",
|
||||
"Asia/Brunei",
|
||||
"Asia/Calcutta",
|
||||
"Asia/Chita",
|
||||
"Asia/Choibalsan",
|
||||
"Asia/Chongqing",
|
||||
"Asia/Chungking",
|
||||
"Asia/Colombo",
|
||||
"Asia/Dacca",
|
||||
"Asia/Damascus",
|
||||
"Asia/Dhaka",
|
||||
"Asia/Dili",
|
||||
"Asia/Dubai",
|
||||
"Asia/Dushanbe",
|
||||
"Asia/Famagusta",
|
||||
"Asia/Gaza",
|
||||
"Asia/Harbin",
|
||||
"Asia/Hebron",
|
||||
"Asia/Ho_Chi_Minh",
|
||||
"Asia/Hong_Kong",
|
||||
"Asia/Hovd",
|
||||
"Asia/Irkutsk",
|
||||
"Asia/Istanbul",
|
||||
"Asia/Jakarta",
|
||||
"Asia/Jayapura",
|
||||
"Asia/Jerusalem",
|
||||
"Asia/Kabul",
|
||||
"Asia/Kamchatka",
|
||||
"Asia/Karachi",
|
||||
"Asia/Kashgar",
|
||||
"Asia/Kathmandu",
|
||||
"Asia/Katmandu",
|
||||
"Asia/Khandyga",
|
||||
"Asia/Kolkata",
|
||||
"Asia/Krasnoyarsk",
|
||||
"Asia/Kuala_Lumpur",
|
||||
"Asia/Kuching",
|
||||
"Asia/Kuwait",
|
||||
"Asia/Macao",
|
||||
"Asia/Macau",
|
||||
"Asia/Magadan",
|
||||
"Asia/Makassar",
|
||||
"Asia/Manila",
|
||||
"Asia/Muscat",
|
||||
"Asia/Nicosia",
|
||||
"Asia/Novokuznetsk",
|
||||
"Asia/Novosibirsk",
|
||||
"Asia/Omsk",
|
||||
"Asia/Oral",
|
||||
"Asia/Phnom_Penh",
|
||||
"Asia/Pontianak",
|
||||
"Asia/Pyongyang",
|
||||
"Asia/Qatar",
|
||||
"Asia/Qyzylorda",
|
||||
"Asia/Rangoon",
|
||||
"Asia/Riyadh",
|
||||
"Asia/Saigon",
|
||||
"Asia/Sakhalin",
|
||||
"Asia/Samarkand",
|
||||
"Asia/Seoul",
|
||||
"Asia/Shanghai",
|
||||
"Asia/Singapore",
|
||||
"Asia/Srednekolymsk",
|
||||
"Asia/Taipei",
|
||||
"Asia/Tashkent",
|
||||
"Asia/Tbilisi",
|
||||
"Asia/Tehran",
|
||||
"Asia/Tel_Aviv",
|
||||
"Asia/Thimbu",
|
||||
"Asia/Thimphu",
|
||||
"Asia/Tokyo",
|
||||
"Asia/Tomsk",
|
||||
"Asia/Ujung_Pandang",
|
||||
"Asia/Ulaanbaatar",
|
||||
"Asia/Ulan_Bator",
|
||||
"Asia/Urumqi",
|
||||
"Asia/Ust-Nera",
|
||||
"Asia/Vientiane",
|
||||
"Asia/Vladivostok",
|
||||
"Asia/Yakutsk",
|
||||
"Asia/Yangon",
|
||||
"Asia/Yekaterinburg",
|
||||
"Asia/Yerevan",
|
||||
"Atlantic/Azores",
|
||||
"Atlantic/Bermuda",
|
||||
"Atlantic/Canary",
|
||||
"Atlantic/Cape_Verde",
|
||||
"Atlantic/Faeroe",
|
||||
"Atlantic/Faroe",
|
||||
"Atlantic/Jan_Mayen",
|
||||
"Atlantic/Madeira",
|
||||
"Atlantic/Reykjavik",
|
||||
"Atlantic/South_Georgia",
|
||||
"Atlantic/St_Helena",
|
||||
"Atlantic/Stanley",
|
||||
"Australia/ACT",
|
||||
"Australia/Adelaide",
|
||||
"Australia/Brisbane",
|
||||
"Australia/Broken_Hill",
|
||||
"Australia/Canberra",
|
||||
"Australia/Currie",
|
||||
"Australia/Darwin",
|
||||
"Australia/Eucla",
|
||||
"Australia/Hobart",
|
||||
"Australia/LHI",
|
||||
"Australia/Lindeman",
|
||||
"Australia/Lord_Howe",
|
||||
"Australia/Melbourne",
|
||||
"Australia/NSW",
|
||||
"Australia/North",
|
||||
"Australia/Perth",
|
||||
"Australia/Queensland",
|
||||
"Australia/South",
|
||||
"Australia/Sydney",
|
||||
"Australia/Tasmania",
|
||||
"Australia/Victoria",
|
||||
"Australia/West",
|
||||
"Australia/Yancowinna",
|
||||
"Brazil/Acre",
|
||||
"Brazil/DeNoronha",
|
||||
"Brazil/East",
|
||||
"Brazil/West",
|
||||
"CET",
|
||||
"CST6CDT",
|
||||
"Canada/Atlantic",
|
||||
"Canada/Central",
|
||||
"Canada/Eastern",
|
||||
"Canada/Mountain",
|
||||
"Canada/Newfoundland",
|
||||
"Canada/Pacific",
|
||||
"Canada/Saskatchewan",
|
||||
"Canada/Yukon",
|
||||
"Chile/Continental",
|
||||
"Chile/EasterIsland",
|
||||
"Cuba",
|
||||
"EET",
|
||||
"EST",
|
||||
"EST5EDT",
|
||||
"Egypt",
|
||||
"Eire",
|
||||
"Etc/GMT",
|
||||
"Etc/GMT+0",
|
||||
"Etc/GMT+1",
|
||||
"Etc/GMT+10",
|
||||
"Etc/GMT+11",
|
||||
"Etc/GMT+12",
|
||||
"Etc/GMT+2",
|
||||
"Etc/GMT+3",
|
||||
"Etc/GMT+4",
|
||||
"Etc/GMT+5",
|
||||
"Etc/GMT+6",
|
||||
"Etc/GMT+7",
|
||||
"Etc/GMT+8",
|
||||
"Etc/GMT+9",
|
||||
"Etc/GMT-0",
|
||||
"Etc/GMT-1",
|
||||
"Etc/GMT-10",
|
||||
"Etc/GMT-11",
|
||||
"Etc/GMT-12",
|
||||
"Etc/GMT-13",
|
||||
"Etc/GMT-14",
|
||||
"Etc/GMT-2",
|
||||
"Etc/GMT-3",
|
||||
"Etc/GMT-4",
|
||||
"Etc/GMT-5",
|
||||
"Etc/GMT-6",
|
||||
"Etc/GMT-7",
|
||||
"Etc/GMT-8",
|
||||
"Etc/GMT-9",
|
||||
"Etc/GMT0",
|
||||
"Etc/Greenwich",
|
||||
"Etc/UCT",
|
||||
"Etc/UTC",
|
||||
"Etc/Universal",
|
||||
"Etc/Zulu",
|
||||
"Europe/Amsterdam",
|
||||
"Europe/Andorra",
|
||||
"Europe/Astrakhan",
|
||||
"Europe/Athens",
|
||||
"Europe/Belfast",
|
||||
"Europe/Belgrade",
|
||||
"Europe/Berlin",
|
||||
"Europe/Bratislava",
|
||||
"Europe/Brussels",
|
||||
"Europe/Bucharest",
|
||||
"Europe/Budapest",
|
||||
"Europe/Busingen",
|
||||
"Europe/Chisinau",
|
||||
"Europe/Copenhagen",
|
||||
"Europe/Dublin",
|
||||
"Europe/Gibraltar",
|
||||
"Europe/Guernsey",
|
||||
"Europe/Helsinki",
|
||||
"Europe/Isle_of_Man",
|
||||
"Europe/Istanbul",
|
||||
"Europe/Jersey",
|
||||
"Europe/Kaliningrad",
|
||||
"Europe/Kiev",
|
||||
"Europe/Kirov",
|
||||
"Europe/Lisbon",
|
||||
"Europe/Ljubljana",
|
||||
"Europe/London",
|
||||
"Europe/Luxembourg",
|
||||
"Europe/Madrid",
|
||||
"Europe/Malta",
|
||||
"Europe/Mariehamn",
|
||||
"Europe/Minsk",
|
||||
"Europe/Monaco",
|
||||
"Europe/Moscow",
|
||||
"Europe/Nicosia",
|
||||
"Europe/Oslo",
|
||||
"Europe/Paris",
|
||||
"Europe/Podgorica",
|
||||
"Europe/Prague",
|
||||
"Europe/Riga",
|
||||
"Europe/Rome",
|
||||
"Europe/Samara",
|
||||
"Europe/San_Marino",
|
||||
"Europe/Sarajevo",
|
||||
"Europe/Saratov",
|
||||
"Europe/Simferopol",
|
||||
"Europe/Skopje",
|
||||
"Europe/Sofia",
|
||||
"Europe/Stockholm",
|
||||
"Europe/Tallinn",
|
||||
"Europe/Tirane",
|
||||
"Europe/Tiraspol",
|
||||
"Europe/Ulyanovsk",
|
||||
"Europe/Uzhgorod",
|
||||
"Europe/Vaduz",
|
||||
"Europe/Vatican",
|
||||
"Europe/Vienna",
|
||||
"Europe/Vilnius",
|
||||
"Europe/Volgograd",
|
||||
"Europe/Warsaw",
|
||||
"Europe/Zagreb",
|
||||
"Europe/Zaporozhye",
|
||||
"Europe/Zurich",
|
||||
"GB",
|
||||
"GB-Eire",
|
||||
"GMT",
|
||||
"GMT+0",
|
||||
"GMT-0",
|
||||
"GMT0",
|
||||
"Greenwich",
|
||||
"HST",
|
||||
"Hongkong",
|
||||
"Iceland",
|
||||
"Indian/Antananarivo",
|
||||
"Indian/Chagos",
|
||||
"Indian/Christmas",
|
||||
"Indian/Cocos",
|
||||
"Indian/Comoro",
|
||||
"Indian/Kerguelen",
|
||||
"Indian/Mahe",
|
||||
"Indian/Maldives",
|
||||
"Indian/Mauritius",
|
||||
"Indian/Mayotte",
|
||||
"Indian/Reunion",
|
||||
"Iran",
|
||||
"Israel",
|
||||
"Jamaica",
|
||||
"Japan",
|
||||
"Kwajalein",
|
||||
"Libya",
|
||||
"MET",
|
||||
"MST",
|
||||
"MST7MDT",
|
||||
"Mexico/BajaNorte",
|
||||
"Mexico/BajaSur",
|
||||
"Mexico/General",
|
||||
"NZ",
|
||||
"NZ-CHAT",
|
||||
"Navajo",
|
||||
"PRC",
|
||||
"PST8PDT",
|
||||
"Pacific/Apia",
|
||||
"Pacific/Auckland",
|
||||
"Pacific/Bougainville",
|
||||
"Pacific/Chatham",
|
||||
"Pacific/Chuuk",
|
||||
"Pacific/Easter",
|
||||
"Pacific/Efate",
|
||||
"Pacific/Enderbury",
|
||||
"Pacific/Fakaofo",
|
||||
"Pacific/Fiji",
|
||||
"Pacific/Funafuti",
|
||||
"Pacific/Galapagos",
|
||||
"Pacific/Gambier",
|
||||
"Pacific/Guadalcanal",
|
||||
"Pacific/Guam",
|
||||
"Pacific/Honolulu",
|
||||
"Pacific/Johnston",
|
||||
"Pacific/Kiritimati",
|
||||
"Pacific/Kosrae",
|
||||
"Pacific/Kwajalein",
|
||||
"Pacific/Majuro",
|
||||
"Pacific/Marquesas",
|
||||
"Pacific/Midway",
|
||||
"Pacific/Nauru",
|
||||
"Pacific/Niue",
|
||||
"Pacific/Norfolk",
|
||||
"Pacific/Noumea",
|
||||
"Pacific/Pago_Pago",
|
||||
"Pacific/Palau",
|
||||
"Pacific/Pitcairn",
|
||||
"Pacific/Pohnpei",
|
||||
"Pacific/Ponape",
|
||||
"Pacific/Port_Moresby",
|
||||
"Pacific/Rarotonga",
|
||||
"Pacific/Saipan",
|
||||
"Pacific/Samoa",
|
||||
"Pacific/Tahiti",
|
||||
"Pacific/Tarawa",
|
||||
"Pacific/Tongatapu",
|
||||
"Pacific/Truk",
|
||||
"Pacific/Wake",
|
||||
"Pacific/Wallis",
|
||||
"Pacific/Yap",
|
||||
"Poland",
|
||||
"Portugal",
|
||||
"ROC",
|
||||
"ROK",
|
||||
"Singapore",
|
||||
"Turkey",
|
||||
"UCT",
|
||||
"US/Alaska",
|
||||
"US/Aleutian",
|
||||
"US/Arizona",
|
||||
"US/Central",
|
||||
"US/East-Indiana",
|
||||
"US/Eastern",
|
||||
"US/Hawaii",
|
||||
"US/Indiana-Starke",
|
||||
"US/Michigan",
|
||||
"US/Mountain",
|
||||
"US/Pacific",
|
||||
"US/Samoa",
|
||||
"UTC",
|
||||
"Universal",
|
||||
"W-SU",
|
||||
"WET",
|
||||
"Zulu",
|
||||
nullptr
|
||||
};
|
||||
|
||||
std::vector<std::string> AllTimeZoneNames() {
|
||||
std::vector<std::string> names;
|
||||
for (const char* const* namep = kTimeZoneNames; *namep != nullptr; ++namep) {
|
||||
names.push_back(std::string("file:") + *namep);
|
||||
}
|
||||
assert(!names.empty());
|
||||
|
||||
std::mt19937 urbg(42); // a UniformRandomBitGenerator with fixed seed
|
||||
std::shuffle(names.begin(), names.end(), urbg);
|
||||
return names;
|
||||
}
|
||||
|
||||
cctz::time_zone TestTimeZone() {
|
||||
cctz::time_zone tz;
|
||||
cctz::load_time_zone("America/Los_Angeles", &tz);
|
||||
return tz;
|
||||
}
|
||||
|
||||
void BM_Zone_LoadUTCTimeZoneFirst(benchmark::State& state) {
|
||||
cctz::time_zone tz;
|
||||
cctz::load_time_zone("UTC", &tz); // in case we're first
|
||||
cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Zone_LoadUTCTimeZoneFirst);
|
||||
|
||||
void BM_Zone_LoadUTCTimeZoneLast(benchmark::State& state) {
|
||||
cctz::time_zone tz;
|
||||
for (const auto& name : AllTimeZoneNames()) {
|
||||
cctz::load_time_zone(name, &tz); // prime cache
|
||||
}
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Zone_LoadUTCTimeZoneLast);
|
||||
|
||||
void BM_Zone_LoadTimeZoneFirst(benchmark::State& state) {
|
||||
cctz::time_zone tz = cctz::utc_time_zone(); // in case we're first
|
||||
const std::string name = "file:America/Los_Angeles";
|
||||
while (state.KeepRunning()) {
|
||||
state.PauseTiming();
|
||||
cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
|
||||
state.ResumeTiming();
|
||||
benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Zone_LoadTimeZoneFirst);
|
||||
|
||||
void BM_Zone_LoadTimeZoneCached(benchmark::State& state) {
|
||||
cctz::time_zone tz = cctz::utc_time_zone(); // in case we're first
|
||||
cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
|
||||
const std::string name = "file:America/Los_Angeles";
|
||||
cctz::load_time_zone(name, &tz); // prime cache
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Zone_LoadTimeZoneCached);
|
||||
|
||||
void BM_Zone_LoadLocalTimeZoneCached(benchmark::State& state) {
|
||||
cctz::utc_time_zone(); // in case we're first
|
||||
cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
|
||||
cctz::local_time_zone(); // prime cache
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(cctz::local_time_zone());
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Zone_LoadLocalTimeZoneCached);
|
||||
|
||||
void BM_Zone_LoadAllTimeZonesFirst(benchmark::State& state) {
|
||||
cctz::time_zone tz;
|
||||
const std::vector<std::string> names = AllTimeZoneNames();
|
||||
for (auto index = names.size(); state.KeepRunning(); ++index) {
|
||||
if (index == names.size()) {
|
||||
index = 0;
|
||||
}
|
||||
if (index == 0) {
|
||||
state.PauseTiming();
|
||||
cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
|
||||
state.ResumeTiming();
|
||||
}
|
||||
benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Zone_LoadAllTimeZonesFirst);
|
||||
|
||||
void BM_Zone_LoadAllTimeZonesCached(benchmark::State& state) {
|
||||
cctz::time_zone tz;
|
||||
const std::vector<std::string> names = AllTimeZoneNames();
|
||||
for (const auto& name : names) {
|
||||
cctz::load_time_zone(name, &tz); // prime cache
|
||||
}
|
||||
for (auto index = names.size(); state.KeepRunning(); ++index) {
|
||||
if (index == names.size()) {
|
||||
index = 0;
|
||||
}
|
||||
benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Zone_LoadAllTimeZonesCached);
|
||||
|
||||
void BM_Zone_TimeZoneImplGetImplicit(benchmark::State& state) {
|
||||
cctz::time_zone tz; // implicit UTC
|
||||
cctz::time_zone::Impl::get(tz);
|
||||
while (state.KeepRunning()) {
|
||||
cctz::time_zone::Impl::get(tz);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Zone_TimeZoneImplGetImplicit);
|
||||
|
||||
void BM_Zone_TimeZoneImplGetExplicit(benchmark::State& state) {
|
||||
cctz::time_zone tz = cctz::utc_time_zone(); // explicit UTC
|
||||
cctz::time_zone::Impl::get(tz);
|
||||
while (state.KeepRunning()) {
|
||||
cctz::time_zone::Impl::get(tz);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Zone_TimeZoneImplGetExplicit);
|
||||
|
||||
void BM_Zone_UTCTimeZone(benchmark::State& state) {
|
||||
cctz::time_zone tz;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(cctz::utc_time_zone());
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Zone_UTCTimeZone);
|
||||
|
||||
// In each "ToDateTime" benchmark we switch between two instants
|
||||
// separated by at least one transition in order to defeat any
|
||||
// internal caching of previous results (e.g., see local_time_hint_).
|
||||
//
|
||||
// The "UTC" variants use UTC instead of the Google/local time zone.
|
||||
|
||||
void BM_Time_ToDateTime_CCTZ(benchmark::State& state) {
|
||||
const cctz::time_zone tz = TestTimeZone();
|
||||
std::chrono::system_clock::time_point tp =
|
||||
std::chrono::system_clock::from_time_t(1384569027);
|
||||
std::chrono::system_clock::time_point tp2 =
|
||||
std::chrono::system_clock::from_time_t(1418962578);
|
||||
while (state.KeepRunning()) {
|
||||
std::swap(tp, tp2);
|
||||
tp += std::chrono::seconds(1);
|
||||
benchmark::DoNotOptimize(cctz::convert(tp, tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToDateTime_CCTZ);
|
||||
|
||||
void BM_Time_ToDateTime_Libc(benchmark::State& state) {
|
||||
// No timezone support, so just use localtime.
|
||||
time_t t = 1384569027;
|
||||
time_t t2 = 1418962578;
|
||||
struct tm tm;
|
||||
while (state.KeepRunning()) {
|
||||
std::swap(t, t2);
|
||||
t += 1;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
benchmark::DoNotOptimize(localtime_s(&tm, &t));
|
||||
#else
|
||||
benchmark::DoNotOptimize(localtime_r(&t, &tm));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToDateTime_Libc);
|
||||
|
||||
void BM_Time_ToDateTimeUTC_CCTZ(benchmark::State& state) {
|
||||
const cctz::time_zone tz = cctz::utc_time_zone();
|
||||
std::chrono::system_clock::time_point tp =
|
||||
std::chrono::system_clock::from_time_t(1384569027);
|
||||
while (state.KeepRunning()) {
|
||||
tp += std::chrono::seconds(1);
|
||||
benchmark::DoNotOptimize(cctz::convert(tp, tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToDateTimeUTC_CCTZ);
|
||||
|
||||
void BM_Time_ToDateTimeUTC_Libc(benchmark::State& state) {
|
||||
time_t t = 1384569027;
|
||||
struct tm tm;
|
||||
while (state.KeepRunning()) {
|
||||
t += 1;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
benchmark::DoNotOptimize(gmtime_s(&tm, &t));
|
||||
#else
|
||||
benchmark::DoNotOptimize(gmtime_r(&t, &tm));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToDateTimeUTC_Libc);
|
||||
|
||||
// In each "FromDateTime" benchmark we switch between two YMDhms
|
||||
// values separated by at least one transition in order to defeat any
|
||||
// internal caching of previous results (e.g., see time_local_hint_).
|
||||
//
|
||||
// The "UTC" variants use UTC instead of the Google/local time zone.
|
||||
// The "Day0" variants require normalization of the day of month.
|
||||
|
||||
void BM_Time_FromDateTime_CCTZ(benchmark::State& state) {
|
||||
const cctz::time_zone tz = TestTimeZone();
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
if ((i++ & 1) == 0) {
|
||||
benchmark::DoNotOptimize(
|
||||
cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz));
|
||||
} else {
|
||||
benchmark::DoNotOptimize(
|
||||
cctz::convert(cctz::civil_second(2013, 11, 15, 18, 30, 27), tz));
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromDateTime_CCTZ);
|
||||
|
||||
void BM_Time_FromDateTime_Libc(benchmark::State& state) {
|
||||
// No timezone support, so just use localtime.
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
struct tm tm;
|
||||
if ((i++ & 1) == 0) {
|
||||
tm.tm_year = 2014 - 1900;
|
||||
tm.tm_mon = 12 - 1;
|
||||
tm.tm_mday = 18;
|
||||
tm.tm_hour = 20;
|
||||
tm.tm_min = 16;
|
||||
tm.tm_sec = 18;
|
||||
} else {
|
||||
tm.tm_year = 2013 - 1900;
|
||||
tm.tm_mon = 11 - 1;
|
||||
tm.tm_mday = 15;
|
||||
tm.tm_hour = 18;
|
||||
tm.tm_min = 30;
|
||||
tm.tm_sec = 27;
|
||||
}
|
||||
tm.tm_isdst = -1;
|
||||
benchmark::DoNotOptimize(mktime(&tm));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromDateTime_Libc);
|
||||
|
||||
void BM_Time_FromDateTimeUTC_CCTZ(benchmark::State& state) {
|
||||
const cctz::time_zone tz = cctz::utc_time_zone();
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(
|
||||
cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromDateTimeUTC_CCTZ);
|
||||
|
||||
// There is no BM_Time_FromDateTimeUTC_Libc.
|
||||
|
||||
void BM_Time_FromDateTimeDay0_CCTZ(benchmark::State& state) {
|
||||
const cctz::time_zone tz = TestTimeZone();
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
if ((i++ & 1) == 0) {
|
||||
benchmark::DoNotOptimize(
|
||||
cctz::convert(cctz::civil_second(2014, 12, 0, 20, 16, 18), tz));
|
||||
} else {
|
||||
benchmark::DoNotOptimize(
|
||||
cctz::convert(cctz::civil_second(2013, 11, 0, 18, 30, 27), tz));
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromDateTimeDay0_CCTZ);
|
||||
|
||||
void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) {
|
||||
// No timezone support, so just use localtime.
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
struct tm tm;
|
||||
if ((i++ & 1) == 0) {
|
||||
tm.tm_year = 2014 - 1900;
|
||||
tm.tm_mon = 12 - 1;
|
||||
tm.tm_mday = 0;
|
||||
tm.tm_hour = 20;
|
||||
tm.tm_min = 16;
|
||||
tm.tm_sec = 18;
|
||||
} else {
|
||||
tm.tm_year = 2013 - 1900;
|
||||
tm.tm_mon = 11 - 1;
|
||||
tm.tm_mday = 0;
|
||||
tm.tm_hour = 18;
|
||||
tm.tm_min = 30;
|
||||
tm.tm_sec = 27;
|
||||
}
|
||||
tm.tm_isdst = -1;
|
||||
benchmark::DoNotOptimize(mktime(&tm));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromDateTimeDay0_Libc);
|
||||
|
||||
const char* const kFormats[] = {
|
||||
RFC1123_full, // 0
|
||||
RFC1123_no_wday, // 1
|
||||
RFC3339_full, // 2
|
||||
RFC3339_sec, // 3
|
||||
"%Y-%m-%dT%H:%M:%S", // 4
|
||||
"%Y-%m-%d", // 5
|
||||
};
|
||||
const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
|
||||
|
||||
void BM_Format_FormatTime(benchmark::State& state) {
|
||||
const std::string fmt = kFormats[state.range(0)];
|
||||
state.SetLabel(fmt);
|
||||
const cctz::time_zone tz = TestTimeZone();
|
||||
const std::chrono::system_clock::time_point tp =
|
||||
cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) +
|
||||
std::chrono::microseconds(1);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(cctz::format(fmt, tp, tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Format_FormatTime)->DenseRange(0, kNumFormats - 1);
|
||||
|
||||
void BM_Format_ParseTime(benchmark::State& state) {
|
||||
const std::string fmt = kFormats[state.range(0)];
|
||||
state.SetLabel(fmt);
|
||||
const cctz::time_zone tz = TestTimeZone();
|
||||
std::chrono::system_clock::time_point tp =
|
||||
cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) +
|
||||
std::chrono::microseconds(1);
|
||||
const std::string when = cctz::format(fmt, tp, tz);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(cctz::parse(fmt, when, tz, &tp));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Format_ParseTime)->DenseRange(0, kNumFormats - 1);
|
||||
|
||||
} // namespace
|
||||
@ -463,8 +463,12 @@ TEST(Format, ExtendedSecondOffset) {
|
||||
|
||||
EXPECT_TRUE(load_time_zone("Europe/Moscow", &tz));
|
||||
tp = convert(civil_second(1919, 6, 30, 23, 59, 59), utc);
|
||||
#if defined(__ANDROID__) && __ANDROID_API__ < 25
|
||||
// Only Android 'N'.1 and beyond have this tz2016g transition.
|
||||
#else
|
||||
TestFormatSpecifier(tp, tz, "%E*z", "+04:31:19");
|
||||
TestFormatSpecifier(tp, tz, "%Ez", "+04:31");
|
||||
#endif
|
||||
tp += seconds(1);
|
||||
TestFormatSpecifier(tp, tz, "%E*z", "+04:00:00");
|
||||
}
|
||||
|
||||
@ -693,7 +693,14 @@ TEST(TimeZones, LoadZonesConcurrently) {
|
||||
|
||||
// Allow a small number of failures to account for skew between
|
||||
// the contents of kTimeZoneNames and the zoneinfo data source.
|
||||
#if defined(__ANDROID__)
|
||||
// Cater to the possibility of using an even older zoneinfo data
|
||||
// source when running on Android, where it is difficult to override
|
||||
// the bionic tzdata provided by the test environment.
|
||||
const std::size_t max_failures = 20;
|
||||
#else
|
||||
const std::size_t max_failures = 3;
|
||||
#endif
|
||||
std::set<std::string> failures;
|
||||
for (const auto& thread_failure : thread_failures) {
|
||||
failures.insert(thread_failure.begin(), thread_failure.end());
|
||||
@ -839,7 +846,7 @@ TEST(TimeZoneImpl, LocalTimeInFixed) {
|
||||
const time_zone tz = fixed_time_zone(offset);
|
||||
const auto tp = system_clock::from_time_t(0);
|
||||
ExpectTime(tp, tz, 1969, 12, 31, 15, 26, 13, offset.count(), false,
|
||||
"UTC-083347");
|
||||
"-083347");
|
||||
EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz))));
|
||||
}
|
||||
|
||||
@ -1098,6 +1105,9 @@ TEST(TimeZoneEdgeCase, PacificApia) {
|
||||
TEST(TimeZoneEdgeCase, AfricaCairo) {
|
||||
const time_zone tz = LoadZone("Africa/Cairo");
|
||||
|
||||
#if defined(__ANDROID__) && __ANDROID_API__ < 21
|
||||
// Only Android 'L' and beyond have this tz2014c transition.
|
||||
#else
|
||||
// An interesting case of midnight not existing.
|
||||
//
|
||||
// 1400191199 == Thu, 15 May 2014 23:59:59 +0200 (EET)
|
||||
@ -1106,11 +1116,15 @@ TEST(TimeZoneEdgeCase, AfricaCairo) {
|
||||
ExpectTime(tp, tz, 2014, 5, 15, 23, 59, 59, 2 * 3600, false, "EET");
|
||||
tp += seconds(1);
|
||||
ExpectTime(tp, tz, 2014, 5, 16, 1, 0, 0, 3 * 3600, true, "EEST");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(TimeZoneEdgeCase, AfricaMonrovia) {
|
||||
const time_zone tz = LoadZone("Africa/Monrovia");
|
||||
|
||||
#if defined(__ANDROID__) && __ANDROID_API__ < 26
|
||||
// Only Android 'O' and beyond have this tz2017b transition.
|
||||
#else
|
||||
// Strange offset change -00:44:30 -> +00:00:00 (non-DST)
|
||||
//
|
||||
// 63593069 == Thu, 6 Jan 1972 23:59:59 -0044 (MMT)
|
||||
@ -1119,6 +1133,7 @@ TEST(TimeZoneEdgeCase, AfricaMonrovia) {
|
||||
ExpectTime(tp, tz, 1972, 1, 6, 23, 59, 59, -44.5 * 60, false, "MMT");
|
||||
tp += seconds(1);
|
||||
ExpectTime(tp, tz, 1972, 1, 7, 0, 44, 30, 0 * 60, false, "GMT");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(TimeZoneEdgeCase, AmericaJamaica) {
|
||||
|
||||
88
third_party/abseil-cpp/absl/time/time.h
vendored
88
third_party/abseil-cpp/absl/time/time.h
vendored
@ -82,8 +82,15 @@ constexpr Duration MakeDuration(int64_t hi, uint32_t lo);
|
||||
constexpr Duration MakeDuration(int64_t hi, int64_t lo);
|
||||
constexpr int64_t kTicksPerNanosecond = 4;
|
||||
constexpr int64_t kTicksPerSecond = 1000 * 1000 * 1000 * kTicksPerNanosecond;
|
||||
template <std::intmax_t N>
|
||||
constexpr Duration FromInt64(int64_t v, std::ratio<1, N>);
|
||||
constexpr Duration FromInt64(int64_t v, std::ratio<60>);
|
||||
constexpr Duration FromInt64(int64_t v, std::ratio<3600>);
|
||||
template <typename T>
|
||||
using IsFloatingPoint =
|
||||
using EnableIfIntegral = typename std::enable_if<
|
||||
std::is_integral<T>::value || std::is_enum<T>::value, int>::type;
|
||||
template <typename T>
|
||||
using EnableIfFloat =
|
||||
typename std::enable_if<std::is_floating_point<T>::value, int>::type;
|
||||
} // namespace time_internal
|
||||
|
||||
@ -178,15 +185,15 @@ inline Duration operator-(Duration lhs, Duration rhs) { return lhs -= rhs; }
|
||||
|
||||
// Multiplicative Operators
|
||||
template <typename T>
|
||||
inline Duration operator*(Duration lhs, T rhs) {
|
||||
Duration operator*(Duration lhs, T rhs) {
|
||||
return lhs *= rhs;
|
||||
}
|
||||
template <typename T>
|
||||
inline Duration operator*(T lhs, Duration rhs) {
|
||||
Duration operator*(T lhs, Duration rhs) {
|
||||
return rhs *= lhs;
|
||||
}
|
||||
template <typename T>
|
||||
inline Duration operator/(Duration lhs, T rhs) {
|
||||
Duration operator/(Duration lhs, T rhs) {
|
||||
return lhs /= rhs;
|
||||
}
|
||||
inline int64_t operator/(Duration lhs, Duration rhs) {
|
||||
@ -322,27 +329,27 @@ constexpr Duration Hours(int64_t n);
|
||||
// Example:
|
||||
// auto a = absl::Seconds(1.5); // OK
|
||||
// auto b = absl::Milliseconds(1500); // BETTER
|
||||
template <typename T, time_internal::IsFloatingPoint<T> = 0>
|
||||
template <typename T, time_internal::EnableIfFloat<T> = 0>
|
||||
Duration Nanoseconds(T n) {
|
||||
return n * Nanoseconds(1);
|
||||
}
|
||||
template <typename T, time_internal::IsFloatingPoint<T> = 0>
|
||||
template <typename T, time_internal::EnableIfFloat<T> = 0>
|
||||
Duration Microseconds(T n) {
|
||||
return n * Microseconds(1);
|
||||
}
|
||||
template <typename T, time_internal::IsFloatingPoint<T> = 0>
|
||||
template <typename T, time_internal::EnableIfFloat<T> = 0>
|
||||
Duration Milliseconds(T n) {
|
||||
return n * Milliseconds(1);
|
||||
}
|
||||
template <typename T, time_internal::IsFloatingPoint<T> = 0>
|
||||
template <typename T, time_internal::EnableIfFloat<T> = 0>
|
||||
Duration Seconds(T n) {
|
||||
return n * Seconds(1);
|
||||
}
|
||||
template <typename T, time_internal::IsFloatingPoint<T> = 0>
|
||||
template <typename T, time_internal::EnableIfFloat<T> = 0>
|
||||
Duration Minutes(T n) {
|
||||
return n * Minutes(1);
|
||||
}
|
||||
template <typename T, time_internal::IsFloatingPoint<T> = 0>
|
||||
template <typename T, time_internal::EnableIfFloat<T> = 0>
|
||||
Duration Hours(T n) {
|
||||
return n * Hours(1);
|
||||
}
|
||||
@ -1154,10 +1161,16 @@ constexpr Duration FromInt64(int64_t v, std::ratio<1, N>) {
|
||||
v / N, v % N * kTicksPerNanosecond * 1000 * 1000 * 1000 / N);
|
||||
}
|
||||
constexpr Duration FromInt64(int64_t v, std::ratio<60>) {
|
||||
return Minutes(v);
|
||||
return (v <= std::numeric_limits<int64_t>::max() / 60 &&
|
||||
v >= std::numeric_limits<int64_t>::min() / 60)
|
||||
? MakeDuration(v * 60)
|
||||
: v > 0 ? InfiniteDuration() : -InfiniteDuration();
|
||||
}
|
||||
constexpr Duration FromInt64(int64_t v, std::ratio<3600>) {
|
||||
return Hours(v);
|
||||
return (v <= std::numeric_limits<int64_t>::max() / 3600 &&
|
||||
v >= std::numeric_limits<int64_t>::min() / 3600)
|
||||
? MakeDuration(v * 3600)
|
||||
: v > 0 ? InfiniteDuration() : -InfiniteDuration();
|
||||
}
|
||||
|
||||
// IsValidRep64<T>(0) is true if the expression `int64_t{std::declval<T>()}` is
|
||||
@ -1220,6 +1233,24 @@ T ToChronoDuration(Duration d) {
|
||||
}
|
||||
|
||||
} // namespace time_internal
|
||||
constexpr Duration Nanoseconds(int64_t n) {
|
||||
return time_internal::FromInt64(n, std::nano{});
|
||||
}
|
||||
constexpr Duration Microseconds(int64_t n) {
|
||||
return time_internal::FromInt64(n, std::micro{});
|
||||
}
|
||||
constexpr Duration Milliseconds(int64_t n) {
|
||||
return time_internal::FromInt64(n, std::milli{});
|
||||
}
|
||||
constexpr Duration Seconds(int64_t n) {
|
||||
return time_internal::FromInt64(n, std::ratio<1>{});
|
||||
}
|
||||
constexpr Duration Minutes(int64_t n) {
|
||||
return time_internal::FromInt64(n, std::ratio<60>{});
|
||||
}
|
||||
constexpr Duration Hours(int64_t n) {
|
||||
return time_internal::FromInt64(n, std::ratio<3600>{});
|
||||
}
|
||||
|
||||
constexpr bool operator<(Duration lhs, Duration rhs) {
|
||||
return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs)
|
||||
@ -1261,39 +1292,6 @@ constexpr Duration operator-(Duration d) {
|
||||
time_internal::GetRepLo(d));
|
||||
}
|
||||
|
||||
constexpr Duration Nanoseconds(int64_t n) {
|
||||
return time_internal::MakeNormalizedDuration(
|
||||
n / (1000 * 1000 * 1000),
|
||||
n % (1000 * 1000 * 1000) * time_internal::kTicksPerNanosecond);
|
||||
}
|
||||
|
||||
constexpr Duration Microseconds(int64_t n) {
|
||||
return time_internal::MakeNormalizedDuration(
|
||||
n / (1000 * 1000),
|
||||
n % (1000 * 1000) * (1000 * time_internal::kTicksPerNanosecond));
|
||||
}
|
||||
|
||||
constexpr Duration Milliseconds(int64_t n) {
|
||||
return time_internal::MakeNormalizedDuration(
|
||||
n / 1000, n % 1000 * (1000 * 1000 * time_internal::kTicksPerNanosecond));
|
||||
}
|
||||
|
||||
constexpr Duration Seconds(int64_t n) { return time_internal::MakeDuration(n); }
|
||||
|
||||
constexpr Duration Minutes(int64_t n) {
|
||||
return (n <= std::numeric_limits<int64_t>::max() / 60 &&
|
||||
n >= std::numeric_limits<int64_t>::min() / 60)
|
||||
? time_internal::MakeDuration(n * 60)
|
||||
: n > 0 ? InfiniteDuration() : -InfiniteDuration();
|
||||
}
|
||||
|
||||
constexpr Duration Hours(int64_t n) {
|
||||
return (n <= std::numeric_limits<int64_t>::max() / 3600 &&
|
||||
n >= std::numeric_limits<int64_t>::min() / 3600)
|
||||
? time_internal::MakeDuration(n * 3600)
|
||||
: n > 0 ? InfiniteDuration() : -InfiniteDuration();
|
||||
}
|
||||
|
||||
constexpr Duration InfiniteDuration() {
|
||||
return time_internal::MakeDuration(std::numeric_limits<int64_t>::max(), ~0U);
|
||||
}
|
||||
|
||||
316
third_party/abseil-cpp/absl/time/time_benchmark.cc
vendored
Normal file
316
third_party/abseil-cpp/absl/time/time_benchmark.cc
vendored
Normal file
@ -0,0 +1,316 @@
|
||||
// Copyright 2018 The Abseil Authors.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://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/time/time.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <sys/time.h>
|
||||
#endif // _WIN32
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/internal/test_util.h"
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
namespace {
|
||||
|
||||
//
|
||||
// Addition/Subtraction of a duration
|
||||
//
|
||||
|
||||
void BM_Time_Arithmetic(benchmark::State& state) {
|
||||
const absl::Duration nano = absl::Nanoseconds(1);
|
||||
const absl::Duration sec = absl::Seconds(1);
|
||||
absl::Time t = absl::UnixEpoch();
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(t += nano);
|
||||
benchmark::DoNotOptimize(t -= sec);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_Arithmetic);
|
||||
|
||||
//
|
||||
// Time difference
|
||||
//
|
||||
|
||||
void BM_Time_Difference(benchmark::State& state) {
|
||||
absl::Time start = absl::Now();
|
||||
absl::Time end = start + absl::Nanoseconds(1);
|
||||
absl::Duration diff;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(diff += end - start);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_Difference);
|
||||
|
||||
//
|
||||
// ToDateTime
|
||||
//
|
||||
// In each "ToDateTime" benchmark we switch between two instants
|
||||
// separated by at least one transition in order to defeat any
|
||||
// internal caching of previous results (e.g., see local_time_hint_).
|
||||
//
|
||||
// The "UTC" variants use UTC instead of the Google/local time zone.
|
||||
//
|
||||
|
||||
void BM_Time_ToDateTime_Absl(benchmark::State& state) {
|
||||
const absl::TimeZone tz =
|
||||
absl::time_internal::LoadTimeZone("America/Los_Angeles");
|
||||
absl::Time t = absl::FromUnixSeconds(1384569027);
|
||||
absl::Time t2 = absl::FromUnixSeconds(1418962578);
|
||||
while (state.KeepRunning()) {
|
||||
std::swap(t, t2);
|
||||
t += absl::Seconds(1);
|
||||
benchmark::DoNotOptimize(t.In(tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToDateTime_Absl);
|
||||
|
||||
void BM_Time_ToDateTime_Libc(benchmark::State& state) {
|
||||
// No timezone support, so just use localtime.
|
||||
time_t t = 1384569027;
|
||||
time_t t2 = 1418962578;
|
||||
while (state.KeepRunning()) {
|
||||
std::swap(t, t2);
|
||||
t += 1;
|
||||
struct tm tm;
|
||||
#if !defined(_WIN32)
|
||||
benchmark::DoNotOptimize(localtime_r(&t, &tm));
|
||||
#else // _WIN32
|
||||
benchmark::DoNotOptimize(localtime_s(&tm, &t));
|
||||
#endif // _WIN32
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToDateTime_Libc);
|
||||
|
||||
void BM_Time_ToDateTimeUTC_Absl(benchmark::State& state) {
|
||||
const absl::TimeZone tz = absl::UTCTimeZone();
|
||||
absl::Time t = absl::FromUnixSeconds(1384569027);
|
||||
while (state.KeepRunning()) {
|
||||
t += absl::Seconds(1);
|
||||
benchmark::DoNotOptimize(t.In(tz));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToDateTimeUTC_Absl);
|
||||
|
||||
void BM_Time_ToDateTimeUTC_Libc(benchmark::State& state) {
|
||||
time_t t = 1384569027;
|
||||
while (state.KeepRunning()) {
|
||||
t += 1;
|
||||
struct tm tm;
|
||||
#if !defined(_WIN32)
|
||||
benchmark::DoNotOptimize(gmtime_r(&t, &tm));
|
||||
#else // _WIN32
|
||||
benchmark::DoNotOptimize(gmtime_s(&tm, &t));
|
||||
#endif // _WIN32
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToDateTimeUTC_Libc);
|
||||
|
||||
//
|
||||
// FromUnixMicros
|
||||
//
|
||||
|
||||
void BM_Time_FromUnixMicros(benchmark::State& state) {
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::FromUnixMicros(i));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromUnixMicros);
|
||||
|
||||
void BM_Time_ToUnixNanos(benchmark::State& state) {
|
||||
const absl::Time t = absl::UnixEpoch() + absl::Seconds(123);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(ToUnixNanos(t));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToUnixNanos);
|
||||
|
||||
void BM_Time_ToUnixMicros(benchmark::State& state) {
|
||||
const absl::Time t = absl::UnixEpoch() + absl::Seconds(123);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(ToUnixMicros(t));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToUnixMicros);
|
||||
|
||||
void BM_Time_ToUnixMillis(benchmark::State& state) {
|
||||
const absl::Time t = absl::UnixEpoch() + absl::Seconds(123);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(ToUnixMillis(t));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToUnixMillis);
|
||||
|
||||
void BM_Time_ToUnixSeconds(benchmark::State& state) {
|
||||
const absl::Time t = absl::UnixEpoch() + absl::Seconds(123);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ToUnixSeconds(t));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToUnixSeconds);
|
||||
|
||||
//
|
||||
// FromDateTime
|
||||
//
|
||||
// In each "FromDateTime" benchmark we switch between two YMDhms
|
||||
// values separated by at least one transition in order to defeat any
|
||||
// internal caching of previous results (e.g., see time_local_hint_).
|
||||
//
|
||||
// The "UTC" variants use UTC instead of the Google/local time zone.
|
||||
// The "Day0" variants require normalization of the day of month.
|
||||
//
|
||||
|
||||
void BM_Time_FromDateTime_Absl(benchmark::State& state) {
|
||||
const absl::TimeZone tz =
|
||||
absl::time_internal::LoadTimeZone("America/Los_Angeles");
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
if ((i & 1) == 0) {
|
||||
absl::FromDateTime(2014, 12, 18, 20, 16, 18, tz);
|
||||
} else {
|
||||
absl::FromDateTime(2013, 11, 15, 18, 30, 27, tz);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromDateTime_Absl);
|
||||
|
||||
void BM_Time_FromDateTime_Libc(benchmark::State& state) {
|
||||
// No timezone support, so just use localtime.
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
struct tm tm;
|
||||
if ((i & 1) == 0) {
|
||||
tm.tm_year = 2014 - 1900;
|
||||
tm.tm_mon = 12 - 1;
|
||||
tm.tm_mday = 18;
|
||||
tm.tm_hour = 20;
|
||||
tm.tm_min = 16;
|
||||
tm.tm_sec = 18;
|
||||
} else {
|
||||
tm.tm_year = 2013 - 1900;
|
||||
tm.tm_mon = 11 - 1;
|
||||
tm.tm_mday = 15;
|
||||
tm.tm_hour = 18;
|
||||
tm.tm_min = 30;
|
||||
tm.tm_sec = 27;
|
||||
}
|
||||
tm.tm_isdst = -1;
|
||||
mktime(&tm);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromDateTime_Libc);
|
||||
|
||||
void BM_Time_FromDateTimeUTC_Absl(benchmark::State& state) {
|
||||
const absl::TimeZone tz = absl::UTCTimeZone();
|
||||
while (state.KeepRunning()) {
|
||||
FromDateTime(2014, 12, 18, 20, 16, 18, tz);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromDateTimeUTC_Absl);
|
||||
|
||||
void BM_Time_FromDateTimeDay0_Absl(benchmark::State& state) {
|
||||
const absl::TimeZone tz =
|
||||
absl::time_internal::LoadTimeZone("America/Los_Angeles");
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
if ((i & 1) == 0) {
|
||||
absl::FromDateTime(2014, 12, 0, 20, 16, 18, tz);
|
||||
} else {
|
||||
absl::FromDateTime(2013, 11, 0, 18, 30, 27, tz);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromDateTimeDay0_Absl);
|
||||
|
||||
void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) {
|
||||
// No timezone support, so just use localtime.
|
||||
int i = 0;
|
||||
while (state.KeepRunning()) {
|
||||
struct tm tm;
|
||||
if ((i & 1) == 0) {
|
||||
tm.tm_year = 2014 - 1900;
|
||||
tm.tm_mon = 12 - 1;
|
||||
tm.tm_mday = 0;
|
||||
tm.tm_hour = 20;
|
||||
tm.tm_min = 16;
|
||||
tm.tm_sec = 18;
|
||||
} else {
|
||||
tm.tm_year = 2013 - 1900;
|
||||
tm.tm_mon = 11 - 1;
|
||||
tm.tm_mday = 0;
|
||||
tm.tm_hour = 18;
|
||||
tm.tm_min = 30;
|
||||
tm.tm_sec = 27;
|
||||
}
|
||||
tm.tm_isdst = -1;
|
||||
mktime(&tm);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromDateTimeDay0_Libc);
|
||||
|
||||
//
|
||||
// To/FromTimespec
|
||||
//
|
||||
|
||||
void BM_Time_ToTimespec(benchmark::State& state) {
|
||||
absl::Time now = absl::Now();
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::ToTimespec(now));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_ToTimespec);
|
||||
|
||||
void BM_Time_FromTimespec(benchmark::State& state) {
|
||||
timespec ts = absl::ToTimespec(absl::Now());
|
||||
while (state.KeepRunning()) {
|
||||
if (++ts.tv_nsec == 1000 * 1000 * 1000) {
|
||||
++ts.tv_sec;
|
||||
ts.tv_nsec = 0;
|
||||
}
|
||||
benchmark::DoNotOptimize(absl::TimeFromTimespec(ts));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_FromTimespec);
|
||||
|
||||
//
|
||||
// Comparison with InfiniteFuture/Past
|
||||
//
|
||||
|
||||
void BM_Time_InfiniteFuture(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::InfiniteFuture());
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_InfiniteFuture);
|
||||
|
||||
void BM_Time_InfinitePast(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(absl::InfinitePast());
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Time_InfinitePast);
|
||||
|
||||
} // namespace
|
||||
27
third_party/abseil-cpp/absl/types/BUILD.bazel
vendored
27
third_party/abseil-cpp/absl/types/BUILD.bazel
vendored
@ -28,7 +28,7 @@ licenses(["notice"]) # Apache 2.0
|
||||
cc_library(
|
||||
name = "any",
|
||||
hdrs = ["any.h"],
|
||||
copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG,
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
deps = [
|
||||
":bad_any_cast",
|
||||
"//absl/base:config",
|
||||
@ -40,9 +40,19 @@ cc_library(
|
||||
|
||||
cc_library(
|
||||
name = "bad_any_cast",
|
||||
srcs = ["bad_any_cast.cc"],
|
||||
hdrs = ["bad_any_cast.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
deps = [":bad_any_cast_impl"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "bad_any_cast_impl",
|
||||
srcs = [
|
||||
"bad_any_cast.cc",
|
||||
"bad_any_cast.h",
|
||||
],
|
||||
copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS,
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
@ -193,6 +203,19 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "optional_exception_safety_test",
|
||||
srcs = [
|
||||
"optional_exception_safety_test.cc",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
|
||||
deps = [
|
||||
":optional",
|
||||
"//absl/base:exception_safety_testing",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "variant",
|
||||
srcs = ["internal/variant.h"],
|
||||
|
||||
17
third_party/abseil-cpp/absl/types/BUILD.gn
vendored
17
third_party/abseil-cpp/absl/types/BUILD.gn
vendored
@ -35,6 +35,21 @@ source_set("any") {
|
||||
}
|
||||
|
||||
source_set("bad_any_cast") {
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
configs += [
|
||||
"//build/config/compiler:no_chromium_code",
|
||||
"//third_party/abseil-cpp:absl_default_cflags_cc",
|
||||
]
|
||||
public_configs = [ "//third_party/abseil-cpp:absl_include_config" ]
|
||||
public = [
|
||||
"bad_any_cast.h",
|
||||
]
|
||||
deps = [
|
||||
":bad_any_cast_impl",
|
||||
]
|
||||
}
|
||||
|
||||
source_set("bad_any_cast_impl") {
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
configs += [
|
||||
"//build/config/compiler:no_chromium_code",
|
||||
@ -51,6 +66,8 @@ source_set("bad_any_cast") {
|
||||
"../base",
|
||||
"../base:config",
|
||||
]
|
||||
visibility = []
|
||||
visibility += [ ":*" ]
|
||||
}
|
||||
|
||||
source_set("span") {
|
||||
|
||||
17
third_party/abseil-cpp/absl/types/CMakeLists.txt
vendored
17
third_party/abseil-cpp/absl/types/CMakeLists.txt
vendored
@ -209,3 +209,20 @@ absl_test(
|
||||
)
|
||||
|
||||
|
||||
# test optional_exception_safety_test
|
||||
set(OPTIONAL_EXCEPTION_SAFETY_TEST_SRC "optional_exception_safety_test.cc")
|
||||
set(OPTIONAL_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES
|
||||
absl::optional
|
||||
absl_base_internal_exception_safety_testing
|
||||
)
|
||||
|
||||
absl_test(
|
||||
TARGET
|
||||
optional_exception_safety_test
|
||||
SOURCES
|
||||
${OPTIONAL_EXCEPTION_SAFETY_TEST_SRC}
|
||||
PUBLIC_LIBRARIES
|
||||
${OPTIONAL_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES}
|
||||
PRIVATE_COMPILE_FLAGS
|
||||
${ABSL_EXCEPTIONS_FLAG}
|
||||
)
|
||||
|
||||
282
third_party/abseil-cpp/absl/types/optional_exception_safety_test.cc
vendored
Normal file
282
third_party/abseil-cpp/absl/types/optional_exception_safety_test.cc
vendored
Normal file
@ -0,0 +1,282 @@
|
||||
// Copyright 2017 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
|
||||
//
|
||||
// http://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/types/optional.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/internal/exception_safety_testing.h"
|
||||
|
||||
namespace absl {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::testing::AssertionFailure;
|
||||
using ::testing::AssertionResult;
|
||||
using ::testing::AssertionSuccess;
|
||||
using ::testing::MakeExceptionSafetyTester;
|
||||
|
||||
using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>;
|
||||
using Optional = absl::optional<Thrower>;
|
||||
|
||||
using MoveThrower = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>;
|
||||
using MoveOptional = absl::optional<MoveThrower>;
|
||||
|
||||
constexpr int kInitialInteger = 5;
|
||||
constexpr int kUpdatedInteger = 10;
|
||||
|
||||
template <typename OptionalT>
|
||||
bool ValueThrowsBadOptionalAccess(const OptionalT& optional) try {
|
||||
return (static_cast<void>(optional.value()), false);
|
||||
} catch (absl::bad_optional_access) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename OptionalT>
|
||||
AssertionResult CheckInvariants(OptionalT* optional_ptr) {
|
||||
// Check the current state post-throw for validity
|
||||
auto& optional = *optional_ptr;
|
||||
|
||||
if (optional.has_value() && ValueThrowsBadOptionalAccess(optional)) {
|
||||
return AssertionFailure()
|
||||
<< "Optional with value should not throw bad_optional_access when "
|
||||
"accessing the value.";
|
||||
}
|
||||
if (!optional.has_value() && !ValueThrowsBadOptionalAccess(optional)) {
|
||||
return AssertionFailure()
|
||||
<< "Optional without a value should throw bad_optional_access when "
|
||||
"accessing the value.";
|
||||
}
|
||||
|
||||
// Reset to a known state
|
||||
optional.reset();
|
||||
|
||||
// Confirm that the known post-reset state is valid
|
||||
if (optional.has_value()) {
|
||||
return AssertionFailure()
|
||||
<< "Optional should not contain a value after being reset.";
|
||||
}
|
||||
if (!ValueThrowsBadOptionalAccess(optional)) {
|
||||
return AssertionFailure() << "Optional should throw bad_optional_access "
|
||||
"when accessing the value after being reset.";
|
||||
}
|
||||
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
template <typename OptionalT>
|
||||
AssertionResult CheckDisengaged(OptionalT* optional_ptr) {
|
||||
auto& optional = *optional_ptr;
|
||||
|
||||
if (optional.has_value()) {
|
||||
return AssertionFailure()
|
||||
<< "Expected optional to not contain a value but a value was found.";
|
||||
}
|
||||
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
template <typename OptionalT>
|
||||
AssertionResult CheckEngaged(OptionalT* optional_ptr) {
|
||||
auto& optional = *optional_ptr;
|
||||
|
||||
if (!optional.has_value()) {
|
||||
return AssertionFailure()
|
||||
<< "Expected optional to contain a value but no value was found.";
|
||||
}
|
||||
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
TEST(OptionalExceptionSafety, ThrowingConstructors) {
|
||||
auto thrower_nonempty = Optional(Thrower(kInitialInteger));
|
||||
testing::TestThrowingCtor<Optional>(thrower_nonempty);
|
||||
|
||||
auto integer_nonempty = absl::optional<int>(kInitialInteger);
|
||||
testing::TestThrowingCtor<Optional>(integer_nonempty);
|
||||
testing::TestThrowingCtor<Optional>(std::move(integer_nonempty)); // NOLINT
|
||||
|
||||
testing::TestThrowingCtor<Optional>(kInitialInteger);
|
||||
using ThrowerVec = std::vector<Thrower, testing::ThrowingAllocator<Thrower>>;
|
||||
testing::TestThrowingCtor<absl::optional<ThrowerVec>>(
|
||||
absl::in_place,
|
||||
std::initializer_list<Thrower>{Thrower(), Thrower(), Thrower()},
|
||||
testing::ThrowingAllocator<Thrower>());
|
||||
}
|
||||
|
||||
TEST(OptionalExceptionSafety, NothrowConstructors) {
|
||||
// This constructor is marked noexcept. If it throws, the program will
|
||||
// terminate.
|
||||
testing::TestThrowingCtor<MoveOptional>(MoveOptional(kUpdatedInteger));
|
||||
}
|
||||
|
||||
TEST(OptionalExceptionSafety, Emplace) {
|
||||
// Test the basic guarantee plus test the result of optional::has_value()
|
||||
// is false in all cases
|
||||
auto disengaged_test = MakeExceptionSafetyTester().WithInvariants(
|
||||
CheckInvariants<Optional>, CheckDisengaged<Optional>);
|
||||
auto disengaged_test_empty = disengaged_test.WithInitialValue(Optional());
|
||||
auto disengaged_test_nonempty =
|
||||
disengaged_test.WithInitialValue(Optional(kInitialInteger));
|
||||
|
||||
auto emplace_thrower_directly = [](Optional* optional_ptr) {
|
||||
optional_ptr->emplace(kUpdatedInteger);
|
||||
};
|
||||
EXPECT_TRUE(disengaged_test_empty.Test(emplace_thrower_directly));
|
||||
EXPECT_TRUE(disengaged_test_nonempty.Test(emplace_thrower_directly));
|
||||
|
||||
auto emplace_thrower_copy = [](Optional* optional_ptr) {
|
||||
auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor);
|
||||
optional_ptr->emplace(thrower);
|
||||
};
|
||||
EXPECT_TRUE(disengaged_test_empty.Test(emplace_thrower_copy));
|
||||
EXPECT_TRUE(disengaged_test_nonempty.Test(emplace_thrower_copy));
|
||||
}
|
||||
|
||||
TEST(OptionalExceptionSafety, EverythingThrowsSwap) {
|
||||
// Test the basic guarantee plus test the result of optional::has_value()
|
||||
// remains the same
|
||||
auto test =
|
||||
MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>);
|
||||
auto disengaged_test_empty = test.WithInitialValue(Optional())
|
||||
.WithInvariants(CheckDisengaged<Optional>);
|
||||
auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
|
||||
.WithInvariants(CheckEngaged<Optional>);
|
||||
|
||||
auto swap_empty = [](Optional* optional_ptr) {
|
||||
auto empty = Optional();
|
||||
optional_ptr->swap(empty);
|
||||
};
|
||||
EXPECT_TRUE(engaged_test_nonempty.Test(swap_empty));
|
||||
|
||||
auto swap_nonempty = [](Optional* optional_ptr) {
|
||||
auto nonempty =
|
||||
Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor);
|
||||
optional_ptr->swap(nonempty);
|
||||
};
|
||||
EXPECT_TRUE(disengaged_test_empty.Test(swap_nonempty));
|
||||
EXPECT_TRUE(engaged_test_nonempty.Test(swap_nonempty));
|
||||
}
|
||||
|
||||
TEST(OptionalExceptionSafety, NoThrowMoveSwap) {
|
||||
// Tests the nothrow guarantee for optional of T with non-throwing move
|
||||
{
|
||||
auto empty = MoveOptional();
|
||||
auto nonempty = MoveOptional(kInitialInteger);
|
||||
EXPECT_TRUE(testing::TestNothrowOp([&]() { nonempty.swap(empty); }));
|
||||
}
|
||||
{
|
||||
auto nonempty = MoveOptional(kUpdatedInteger);
|
||||
auto empty = MoveOptional();
|
||||
EXPECT_TRUE(testing::TestNothrowOp([&]() { empty.swap(nonempty); }));
|
||||
}
|
||||
{
|
||||
auto nonempty_from = MoveOptional(kUpdatedInteger);
|
||||
auto nonempty_to = MoveOptional(kInitialInteger);
|
||||
EXPECT_TRUE(
|
||||
testing::TestNothrowOp([&]() { nonempty_to.swap(nonempty_from); }));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OptionalExceptionSafety, CopyAssign) {
|
||||
// Test the basic guarantee plus test the result of optional::has_value()
|
||||
// remains the same
|
||||
auto test =
|
||||
MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>);
|
||||
auto disengaged_test_empty = test.WithInitialValue(Optional())
|
||||
.WithInvariants(CheckDisengaged<Optional>);
|
||||
auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
|
||||
.WithInvariants(CheckEngaged<Optional>);
|
||||
|
||||
auto copyassign_nonempty = [](Optional* optional_ptr) {
|
||||
auto nonempty =
|
||||
Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor);
|
||||
*optional_ptr = nonempty;
|
||||
};
|
||||
EXPECT_TRUE(disengaged_test_empty.Test(copyassign_nonempty));
|
||||
EXPECT_TRUE(engaged_test_nonempty.Test(copyassign_nonempty));
|
||||
|
||||
auto copyassign_thrower = [](Optional* optional_ptr) {
|
||||
auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor);
|
||||
*optional_ptr = thrower;
|
||||
};
|
||||
EXPECT_TRUE(disengaged_test_empty.Test(copyassign_thrower));
|
||||
EXPECT_TRUE(engaged_test_nonempty.Test(copyassign_thrower));
|
||||
}
|
||||
|
||||
TEST(OptionalExceptionSafety, MoveAssign) {
|
||||
// Test the basic guarantee plus test the result of optional::has_value()
|
||||
// remains the same
|
||||
auto test =
|
||||
MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>);
|
||||
auto disengaged_test_empty = test.WithInitialValue(Optional())
|
||||
.WithInvariants(CheckDisengaged<Optional>);
|
||||
auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
|
||||
.WithInvariants(CheckEngaged<Optional>);
|
||||
|
||||
auto moveassign_empty = [](Optional* optional_ptr) {
|
||||
auto empty = Optional();
|
||||
*optional_ptr = std::move(empty);
|
||||
};
|
||||
EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_empty));
|
||||
|
||||
auto moveassign_nonempty = [](Optional* optional_ptr) {
|
||||
auto nonempty =
|
||||
Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor);
|
||||
*optional_ptr = std::move(nonempty);
|
||||
};
|
||||
EXPECT_TRUE(disengaged_test_empty.Test(moveassign_nonempty));
|
||||
EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_nonempty));
|
||||
|
||||
auto moveassign_thrower = [](Optional* optional_ptr) {
|
||||
auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor);
|
||||
*optional_ptr = std::move(thrower);
|
||||
};
|
||||
EXPECT_TRUE(disengaged_test_empty.Test(moveassign_thrower));
|
||||
EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_thrower));
|
||||
}
|
||||
|
||||
TEST(OptionalExceptionSafety, NothrowMoveAssign) {
|
||||
// Tests the nothrow guarantee for optional of T with non-throwing move
|
||||
{
|
||||
auto empty = MoveOptional();
|
||||
auto nonempty = MoveOptional(kInitialInteger);
|
||||
EXPECT_TRUE(testing::TestNothrowOp([&]() { nonempty = std::move(empty); }));
|
||||
}
|
||||
{
|
||||
auto nonempty = MoveOptional(kInitialInteger);
|
||||
auto empty = MoveOptional();
|
||||
EXPECT_TRUE(testing::TestNothrowOp([&]() { empty = std::move(nonempty); }));
|
||||
}
|
||||
{
|
||||
auto nonempty_from = MoveOptional(kUpdatedInteger);
|
||||
auto nonempty_to = MoveOptional(kInitialInteger);
|
||||
EXPECT_TRUE(testing::TestNothrowOp(
|
||||
[&]() { nonempty_to = std::move(nonempty_from); }));
|
||||
}
|
||||
{
|
||||
auto thrower = MoveThrower(kUpdatedInteger);
|
||||
auto empty = MoveOptional();
|
||||
EXPECT_TRUE(testing::TestNothrowOp([&]() { empty = std::move(thrower); }));
|
||||
}
|
||||
{
|
||||
auto thrower = MoveThrower(kUpdatedInteger);
|
||||
auto nonempty = MoveOptional(kInitialInteger);
|
||||
EXPECT_TRUE(
|
||||
testing::TestNothrowOp([&]() { nonempty = std::move(thrower); }));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace absl
|
||||
2
third_party/abseil-cpp/absl/types/span.h
vendored
2
third_party/abseil-cpp/absl/types/span.h
vendored
@ -279,7 +279,7 @@ class Span {
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
static const size_type npos = ~size_type{0};
|
||||
static const size_type npos = ~(size_type(0));
|
||||
|
||||
constexpr Span() noexcept : Span(nullptr, 0) {}
|
||||
constexpr Span(pointer array, size_type length) noexcept
|
||||
|
||||
@ -27,8 +27,8 @@ namespace absl {
|
||||
namespace {
|
||||
|
||||
using ::testing::MakeExceptionSafetyTester;
|
||||
using ::testing::nothrow_guarantee;
|
||||
using ::testing::strong_guarantee;
|
||||
using ::testing::TestNothrowOp;
|
||||
using ::testing::TestThrowingCtor;
|
||||
|
||||
using Thrower = testing::ThrowingValue<>;
|
||||
@ -120,7 +120,11 @@ testing::AssertionResult CheckInvariants(ThrowingVariant* v) {
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
Thrower ExpectedThrower() { return Thrower(42); }
|
||||
template <typename... Args>
|
||||
Thrower ExpectedThrower(Args&&... args) {
|
||||
return Thrower(42, args...);
|
||||
}
|
||||
|
||||
ThrowerVec ExpectedThrowerVec() { return {Thrower(100), Thrower(200)}; }
|
||||
ThrowingVariant ValuelessByException() {
|
||||
ThrowingVariant v;
|
||||
@ -193,18 +197,14 @@ TEST(VariantExceptionSafetyTest, CopyAssign) {
|
||||
{
|
||||
// - neither *this nor rhs holds a value
|
||||
const ThrowingVariant rhs = ValuelessByException();
|
||||
EXPECT_TRUE(MakeExceptionSafetyTester()
|
||||
.WithInitialValue(ValuelessByException())
|
||||
.WithInvariants(nothrow_guarantee)
|
||||
.Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }));
|
||||
ThrowingVariant lhs = ValuelessByException();
|
||||
EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; }));
|
||||
}
|
||||
{
|
||||
// - *this holds a value but rhs does not
|
||||
const ThrowingVariant rhs = ValuelessByException();
|
||||
EXPECT_TRUE(MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithThrower())
|
||||
.WithInvariants(nothrow_guarantee)
|
||||
.Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }));
|
||||
ThrowingVariant lhs = WithThrower();
|
||||
EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; }));
|
||||
}
|
||||
// - index() == j
|
||||
{
|
||||
@ -237,10 +237,8 @@ TEST(VariantExceptionSafetyTest, CopyAssign) {
|
||||
// should not throw because emplace() invokes Tj's copy ctor
|
||||
// which should not throw.
|
||||
const ThrowingVariant rhs(CopyNothrow{});
|
||||
EXPECT_TRUE(MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithThrower())
|
||||
.WithInvariants(nothrow_guarantee)
|
||||
.Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }));
|
||||
ThrowingVariant lhs = WithThrower();
|
||||
EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; }));
|
||||
}
|
||||
{
|
||||
// is_nothrow_copy_constructible<Tj> == false &&
|
||||
@ -281,23 +279,14 @@ TEST(VariantExceptionSafetyTest, MoveAssign) {
|
||||
{
|
||||
// - neither *this nor rhs holds a value
|
||||
ThrowingVariant rhs = ValuelessByException();
|
||||
|
||||
EXPECT_TRUE(MakeExceptionSafetyTester()
|
||||
.WithInitialValue(ValuelessByException())
|
||||
.WithInvariants(nothrow_guarantee)
|
||||
.Test([rhs](ThrowingVariant* lhs) mutable {
|
||||
*lhs = std::move(rhs);
|
||||
}));
|
||||
ThrowingVariant lhs = ValuelessByException();
|
||||
EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); }));
|
||||
}
|
||||
{
|
||||
// - *this holds a value but rhs does not
|
||||
ThrowingVariant rhs = ValuelessByException();
|
||||
EXPECT_TRUE(MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithThrower())
|
||||
.WithInvariants(nothrow_guarantee)
|
||||
.Test([rhs](ThrowingVariant* lhs) mutable {
|
||||
*lhs = std::move(rhs);
|
||||
}));
|
||||
ThrowingVariant lhs = WithThrower();
|
||||
EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); }));
|
||||
}
|
||||
{
|
||||
// - index() == j
|
||||
@ -310,13 +299,14 @@ TEST(VariantExceptionSafetyTest, MoveAssign) {
|
||||
// Since Thrower's move assignment has basic guarantee, so should variant's.
|
||||
auto tester = MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithThrower())
|
||||
.WithOperation([rhs](ThrowingVariant* lhs) mutable {
|
||||
*lhs = std::move(rhs);
|
||||
.WithOperation([&](ThrowingVariant* lhs) {
|
||||
auto copy = rhs;
|
||||
*lhs = std::move(copy);
|
||||
});
|
||||
EXPECT_TRUE(tester
|
||||
.WithInvariants(
|
||||
CheckInvariants,
|
||||
[j](ThrowingVariant* lhs) { return lhs->index() == j; })
|
||||
[&](ThrowingVariant* lhs) { return lhs->index() == j; })
|
||||
.Test());
|
||||
EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test());
|
||||
}
|
||||
@ -332,8 +322,9 @@ TEST(VariantExceptionSafetyTest, MoveAssign) {
|
||||
[](ThrowingVariant* lhs) {
|
||||
return lhs->valueless_by_exception();
|
||||
})
|
||||
.Test([rhs](ThrowingVariant* lhs) mutable {
|
||||
*lhs = std::move(rhs);
|
||||
.Test([&](ThrowingVariant* lhs) {
|
||||
auto copy = rhs;
|
||||
*lhs = std::move(copy);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -365,8 +356,9 @@ TEST(VariantExceptionSafetyTest, ValueAssign) {
|
||||
// move assign
|
||||
auto move_tester = MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithThrower())
|
||||
.WithOperation([rhs](ThrowingVariant* lhs) mutable {
|
||||
*lhs = std::move(rhs);
|
||||
.WithOperation([&](ThrowingVariant* lhs) {
|
||||
auto copy = rhs;
|
||||
*lhs = std::move(copy);
|
||||
});
|
||||
EXPECT_TRUE(move_tester
|
||||
.WithInvariants(CheckInvariants,
|
||||
@ -388,19 +380,13 @@ TEST(VariantExceptionSafetyTest, ValueAssign) {
|
||||
// invokes the copy/move constructor and it should not throw.
|
||||
{
|
||||
const CopyNothrow rhs;
|
||||
EXPECT_TRUE(MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithThrower())
|
||||
.WithInvariants(nothrow_guarantee)
|
||||
.Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }));
|
||||
ThrowingVariant lhs = WithThrower();
|
||||
EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; }));
|
||||
}
|
||||
{
|
||||
MoveNothrow rhs;
|
||||
EXPECT_TRUE(MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithThrower())
|
||||
.WithInvariants(nothrow_guarantee)
|
||||
.Test([rhs](ThrowingVariant* lhs) mutable {
|
||||
*lhs = std::move(rhs);
|
||||
}));
|
||||
ThrowingVariant lhs = WithThrower();
|
||||
EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); }));
|
||||
}
|
||||
// if is_nothrow_constructible_v<Tj, T> == false &&
|
||||
// is_nothrow_move_constructible<Tj> == false
|
||||
@ -423,8 +409,8 @@ TEST(VariantExceptionSafetyTest, ValueAssign) {
|
||||
// move
|
||||
auto move_tester = MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithCopyNoThrow())
|
||||
.WithOperation([rhs](ThrowingVariant* lhs) mutable {
|
||||
*lhs = std::move(rhs);
|
||||
.WithOperation([](ThrowingVariant* lhs) {
|
||||
*lhs = ExpectedThrower(testing::nothrow_ctor);
|
||||
});
|
||||
EXPECT_TRUE(move_tester
|
||||
.WithInvariants(CheckInvariants,
|
||||
@ -477,21 +463,20 @@ TEST(VariantExceptionSafetyTest, Swap) {
|
||||
// if both are valueless_by_exception(), no effect
|
||||
{
|
||||
ThrowingVariant rhs = ValuelessByException();
|
||||
EXPECT_TRUE(
|
||||
MakeExceptionSafetyTester()
|
||||
.WithInitialValue(ValuelessByException())
|
||||
.WithInvariants(nothrow_guarantee)
|
||||
.Test([rhs](ThrowingVariant* lhs) mutable { lhs->swap(rhs); }));
|
||||
ThrowingVariant lhs = ValuelessByException();
|
||||
EXPECT_TRUE(TestNothrowOp([&]() { lhs.swap(rhs); }));
|
||||
}
|
||||
// if index() == rhs.index(), calls swap(get<i>(*this), get<i>(rhs))
|
||||
// where i is index().
|
||||
{
|
||||
ThrowingVariant rhs = ExpectedThrower();
|
||||
EXPECT_TRUE(
|
||||
MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithThrower())
|
||||
.WithInvariants(CheckInvariants)
|
||||
.Test([rhs](ThrowingVariant* lhs) mutable { lhs->swap(rhs); }));
|
||||
EXPECT_TRUE(MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithThrower())
|
||||
.WithInvariants(CheckInvariants)
|
||||
.Test([&](ThrowingVariant* lhs) {
|
||||
auto copy = rhs;
|
||||
lhs->swap(copy);
|
||||
}));
|
||||
}
|
||||
// Otherwise, exchanges the value of rhs and *this. The exception safety
|
||||
// involves variant in moved-from state which is not specified in the
|
||||
@ -499,19 +484,23 @@ TEST(VariantExceptionSafetyTest, Swap) {
|
||||
// overall strong guarantee. So, we are only checking basic guarantee here.
|
||||
{
|
||||
ThrowingVariant rhs = ExpectedThrower();
|
||||
EXPECT_TRUE(
|
||||
MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithCopyNoThrow())
|
||||
.WithInvariants(CheckInvariants)
|
||||
.Test([rhs](ThrowingVariant* lhs) mutable { lhs->swap(rhs); }));
|
||||
EXPECT_TRUE(MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithCopyNoThrow())
|
||||
.WithInvariants(CheckInvariants)
|
||||
.Test([&](ThrowingVariant* lhs) {
|
||||
auto copy = rhs;
|
||||
lhs->swap(copy);
|
||||
}));
|
||||
}
|
||||
{
|
||||
ThrowingVariant rhs = ExpectedThrower();
|
||||
EXPECT_TRUE(
|
||||
MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithCopyNoThrow())
|
||||
.WithInvariants(CheckInvariants)
|
||||
.Test([rhs](ThrowingVariant* lhs) mutable { rhs.swap(*lhs); }));
|
||||
EXPECT_TRUE(MakeExceptionSafetyTester()
|
||||
.WithInitialValue(WithCopyNoThrow())
|
||||
.WithInvariants(CheckInvariants)
|
||||
.Test([&](ThrowingVariant* lhs) {
|
||||
auto copy = rhs;
|
||||
copy.swap(*lhs);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,14 +14,6 @@
|
||||
'target_name': 'compiled_resources2',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
'<(DEPTH)/chrome/browser/resources/chromeos/braille_ime/compiled_resources2.gyp:*',
|
||||
'<(DEPTH)/chrome/browser/resources/chromeos/compiled_resources2.gyp:*',
|
||||
'<(DEPTH)/chrome/browser/resources/chromeos/login/compiled_resources2.gyp:*',
|
||||
'<(DEPTH)/chrome/browser/resources/chromeos/multidevice_setup/compiled_resources2.gyp:*',
|
||||
'<(DEPTH)/chrome/browser/resources/chromeos/network_ui/compiled_resources2.gyp:*',
|
||||
'<(DEPTH)/chrome/browser/resources/chromeos/select_to_speak/compiled_resources2.gyp:*',
|
||||
'<(DEPTH)/chrome/browser/resources/chromeos/switch_access/compiled_resources2.gyp:*',
|
||||
'<(DEPTH)/chrome/browser/resources/chromeos/sys_internals/compiled_resources2.gyp:*',
|
||||
'<(DEPTH)/ui/webui/resources/cr_components/compiled_resources2.gyp:*',
|
||||
'<(DEPTH)/ui/webui/resources/cr_elements/compiled_resources2.gyp:*',
|
||||
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:*',
|
||||
|
||||
@ -265,7 +265,6 @@ chrome.automation.StateType = {
|
||||
EXPANDED: 'expanded',
|
||||
FOCUSABLE: 'focusable',
|
||||
FOCUSED: 'focused',
|
||||
HAS_POPUP: 'hasPopup',
|
||||
HORIZONTAL: 'horizontal',
|
||||
HOVERED: 'hovered',
|
||||
IGNORED: 'ignored',
|
||||
|
||||
@ -250,7 +250,12 @@ chrome.fileManagerPrivate.FileTask;
|
||||
* starred: (boolean|undefined),
|
||||
* externalFileUrl: (string|undefined),
|
||||
* alternateUrl: (string|undefined),
|
||||
* shareUrl: (string|undefined)
|
||||
* shareUrl: (string|undefined),
|
||||
* canCopy: (boolean|undefined),
|
||||
* canDelete: (boolean|undefined),
|
||||
* canRename: (boolean|undefined),
|
||||
* canAddChildren: (boolean|undefined),
|
||||
* canShare: (boolean|undefined)
|
||||
* }}
|
||||
*/
|
||||
chrome.fileManagerPrivate.EntryProperties;
|
||||
|
||||
4
third_party/freetype/README.chromium
vendored
4
third_party/freetype/README.chromium
vendored
@ -1,7 +1,7 @@
|
||||
Name: FreeType
|
||||
URL: http://www.freetype.org/
|
||||
Version: VER-2-9-1-36
|
||||
Revision: 0589f6e6ee6e9bfe0c7139374fc8812e849e7bf7
|
||||
Version: VER-2-9-1-56
|
||||
Revision: 8f1ed54877ffab4fc2cf2be329446c748a885842
|
||||
License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
|
||||
JPEG Group) licenses"
|
||||
License File: src/docs/FTL.TXT
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1
third_party/googletest/BUILD.gn
vendored
1
third_party/googletest/BUILD.gn
vendored
@ -111,7 +111,6 @@ source_set("gtest") {
|
||||
if (is_fuchsia) {
|
||||
deps += [
|
||||
"//third_party/fuchsia-sdk:fdio",
|
||||
"//third_party/fuchsia-sdk:launchpad",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user