Revert "Roll chromium_revision e1ef7d4b6b..b47e7752c6 (568794:569173)"
This reverts commit fd2457b10fc2713bfd5d86952216cf89b6283a90. Reason for revert: <INSERT REASONING HERE> Original change's description: > Roll chromium_revision e1ef7d4b6b..b47e7752c6 (568794:569173) > > Change log:e1ef7d4b6b..b47e7752c6> Full diff:e1ef7d4b6b..b47e7752c6> > Roll chromium third_party ab9fbe29c9..630af48a96 > Change log:ab9fbe29c9..630af48a96> > Changed dependencies: > * src/base:03e1bc561f..6070b24b9f> * src/build:bb306be407..511e258eee> * src/ios:48697bf3a1..ce1db7deb1> * src/testing:6440c4ea3a..80a4cfaab7> * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/f153b902be..f3c454475a > * src/third_party/depot_tools:1cabdc4643..a28b14f122> * src/tools:66f1089d0c..f6bb2a6fb4> DEPS diff:e1ef7d4b6b..b47e7752c6/DEPS > > No update to Clang. > > TBR=buildbot@webrtc.org, > BUG=None > CQ_INCLUDE_TRYBOTS=master.internal.tryserver.corp.webrtc:linux_internal > NO_AUTOIMPORT_DEPS_CHECK=true > > Change-Id: I7553549111225f2c5bc769dec114cd058ae699d5 > Reviewed-on: https://webrtc-review.googlesource.com/84600 > Reviewed-by: WebRTC Buildbot <buildbot@webrtc.org> > Commit-Queue: WebRTC Buildbot <buildbot@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#23692} TBR=buildbot@webrtc.org Change-Id: I7d136553622fe4c4e49dbd9c60406811a8b11bd8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: None Cq-Include-Trybots: master.internal.tryserver.corp.webrtc:linux_internal Reviewed-on: https://webrtc-review.googlesource.com/84720 Reviewed-by: Artem Titov <titovartem@webrtc.org> Commit-Queue: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23708}
This commit is contained in:
parent
0bc58cf876
commit
cb76c70534
18
DEPS
18
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': 'b47e7752c62752e9f97cd658c7aa9532ef688c11',
|
||||
'chromium_revision': 'e1ef7d4b6ba51e51817556f44f71b95d0c64f106',
|
||||
'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': 'f3c454475aeea9450e3f90de9e9430a335795496',
|
||||
'catapult_revision': 'f153b902bec3811dd5faa9e807240b059e7bbc8c',
|
||||
# Three lines of non-changing comments so that
|
||||
# the commit queue can handle CLs rolling libFuzzer
|
||||
# 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': '630af48a96cff39e916a4fe8407a416ced2f903d',
|
||||
'chromium_third_party_revision': 'ab9fbe29c97f030a4787abf517e4902895c757f1',
|
||||
}
|
||||
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' + '@' + '6070b24b9f085d50c902f49117813f7f88f9df3a',
|
||||
Var('chromium_git') + '/chromium/src/base' + '@' + '03e1bc561f08357987d0a3b1a6306b378cd61c04',
|
||||
'src/build':
|
||||
Var('chromium_git') + '/chromium/src/build' + '@' + '511e258eee11fe61e6da8ea709bd9f6d0d5724a9',
|
||||
Var('chromium_git') + '/chromium/src/build' + '@' + 'bb306be4076914cdd287517d8480851a410d7788',
|
||||
'src/buildtools':
|
||||
Var('chromium_git') + '/chromium/buildtools.git' + '@' + '5941c1b3df96c1db756a2834343533335c394c4a',
|
||||
# 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' + '@' + 'ce1db7deb10ab0338f08fa987802fed7643e2f72',
|
||||
'url': Var('chromium_git') + '/chromium/src/ios' + '@' + '48697bf3a10f61dbd71c30722640efbbec82d3e2',
|
||||
'condition': 'checkout_ios',
|
||||
},
|
||||
'src/testing':
|
||||
Var('chromium_git') + '/chromium/src/testing' + '@' + '80a4cfaab736971e0bf001e16af6dfd625e48955',
|
||||
Var('chromium_git') + '/chromium/src/testing' + '@' + '6440c4ea3ae95d9142ae72fdd55c6406ad0df00b',
|
||||
# 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' + '@' + 'a28b14f122463a6d73c623e77c9dea4e228322dc',
|
||||
Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1cabdc464313eee47fdc52a95b3f8e028680000d',
|
||||
'src/third_party/errorprone/lib': {
|
||||
'url': Var('chromium_git') + '/chromium/third_party/errorprone.git' + '@' + '980d49e839aa4984015efed34b0134d4b2c9b6d7',
|
||||
'condition': 'checkout_android',
|
||||
@ -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' + '@' + 'f6bb2a6fb4184f9078751592a7174cb389b94fef',
|
||||
Var('chromium_git') + '/chromium/src/tools' + '@' + '66f1089d0cd8b57081b77d828ee6f6c46a64a0c0',
|
||||
'src/tools/swarming_client':
|
||||
Var('chromium_git') + '/infra/luci/client-py.git' + '@' + Var('swarming_revision'),
|
||||
|
||||
|
||||
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: bd40a41cc142b36c73b881099d08a9d83f7f4780
|
||||
Revision: e5be80532b5d998813f9db952d2cc5401b1532df
|
||||
Security Critical: yes
|
||||
|
||||
Description:
|
||||
|
||||
17
third_party/abseil-cpp/WORKSPACE
vendored
17
third_party/abseil-cpp/WORKSPACE
vendored
@ -1,13 +1,13 @@
|
||||
workspace(name = "com_google_absl")
|
||||
# Bazel toolchains
|
||||
http_archive(
|
||||
name = "bazel_toolchains",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/2cec6c9f6d12224e93d9b3f337b24e41602de3ba.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-toolchains/archive/2cec6c9f6d12224e93d9b3f337b24e41602de3ba.tar.gz",
|
||||
],
|
||||
strip_prefix = "bazel-toolchains-2cec6c9f6d12224e93d9b3f337b24e41602de3ba",
|
||||
sha256 = "9b8d85b61d8945422e86ac31e4d4d2d967542c080d1da1b45364da7fd6bdd638",
|
||||
name = "bazel_toolchains",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/f8847f64e6950e8ab9fde1c0aba768550b0d9ab2.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-toolchains/archive/f8847f64e6950e8ab9fde1c0aba768550b0d9ab2.tar.gz",
|
||||
],
|
||||
strip_prefix = "bazel-toolchains-f8847f64e6950e8ab9fde1c0aba768550b0d9ab2",
|
||||
sha256 = "794366f51fea224b3656a0b0f8f1518e739748646523a572fcd3d68614a0e670",
|
||||
)
|
||||
|
||||
# GoogleTest/GoogleMock framework. Used by most unit-tests.
|
||||
@ -15,7 +15,6 @@ http_archive(
|
||||
name = "com_google_googletest",
|
||||
urls = ["https://github.com/google/googletest/archive/4e4df226fc197c0dda6e37f5c8c3845ca1e73a49.zip"],
|
||||
strip_prefix = "googletest-4e4df226fc197c0dda6e37f5c8c3845ca1e73a49",
|
||||
sha256 = "d4179caf54410968d1fff0b869e7d74803dd30209ee6645ccf1ca65ab6cf5e5a",
|
||||
)
|
||||
|
||||
# Google benchmark.
|
||||
@ -23,7 +22,6 @@ http_archive(
|
||||
name = "com_github_google_benchmark",
|
||||
urls = ["https://github.com/google/benchmark/archive/16703ff83c1ae6d53e5155df3bb3ab0bc96083be.zip"],
|
||||
strip_prefix = "benchmark-16703ff83c1ae6d53e5155df3bb3ab0bc96083be",
|
||||
sha256 = "59f918c8ccd4d74b6ac43484467b500f1d64b40cc1010daa055375b322a43ba3",
|
||||
)
|
||||
|
||||
# RE2 regular-expression framework. Used by some unit-tests.
|
||||
@ -31,5 +29,4 @@ http_archive(
|
||||
name = "com_googlesource_code_re2",
|
||||
urls = ["https://github.com/google/re2/archive/6cf8ccd82dbaab2668e9b13596c68183c9ecd13f.zip"],
|
||||
strip_prefix = "re2-6cf8ccd82dbaab2668e9b13596c68183c9ecd13f",
|
||||
sha256 = "279a852219dbfc504501775596089d30e9c0b29664ce4128b0ac4c841471a16a",
|
||||
)
|
||||
|
||||
13
third_party/abseil-cpp/absl/LTS.md
vendored
13
third_party/abseil-cpp/absl/LTS.md
vendored
@ -1,13 +0,0 @@
|
||||
# Long Term Support (LTS) Branches
|
||||
|
||||
This repository contains periodic snapshots of the Abseil codebase that are
|
||||
Long Term Support (LTS) branches. An LTS branch allows you to use a known
|
||||
version of Abseil without interfering with other projects which may also, in
|
||||
turn, use Abseil. (For more information about our releases, see the
|
||||
[Abseil Release Management](https://abseil.io/about/releases) guide.
|
||||
|
||||
## LTS Branches
|
||||
|
||||
The following lists LTS branches and the date they have been released:
|
||||
|
||||
* [LTS Branch June 18, 2018](https://github.com/abseil/abseil-cpp/tree/lts_2018_06_18/)
|
||||
5
third_party/abseil-cpp/absl/base/BUILD.bazel
vendored
5
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",
|
||||
|
||||
@ -27,7 +27,7 @@ struct identity {
|
||||
template <typename T>
|
||||
using identity_t = typename identity<T>::type;
|
||||
|
||||
} // namespace internal
|
||||
} // namespace absl
|
||||
} // namespace internal
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_BASE_INTERNAL_IDENTITY_H_
|
||||
|
||||
@ -84,7 +84,7 @@ inline void absl::base_internal::SpinLockWake(std::atomic<uint32_t> *w,
|
||||
|
||||
inline void absl::base_internal::SpinLockDelay(
|
||||
std::atomic<uint32_t> *w, uint32_t value, int loop,
|
||||
absl::base_internal::SchedulingMode scheduling_mode) {
|
||||
base_internal::SchedulingMode scheduling_mode) {
|
||||
AbslInternalSpinLockDelay(w, value, loop, scheduling_mode);
|
||||
}
|
||||
|
||||
|
||||
5
third_party/abseil-cpp/absl/base/macros.h
vendored
5
third_party/abseil-cpp/absl/base/macros.h
vendored
@ -194,9 +194,8 @@ enum LinkerInitialized {
|
||||
#if defined(NDEBUG)
|
||||
#define ABSL_ASSERT(expr) (false ? (void)(expr) : (void)0)
|
||||
#else
|
||||
#define ABSL_ASSERT(expr) \
|
||||
(ABSL_PREDICT_TRUE((expr)) ? (void)0 \
|
||||
: [] { assert(false && #expr); }()) // NOLINT
|
||||
#define ABSL_ASSERT(expr) \
|
||||
(ABSL_PREDICT_TRUE((expr)) ? (void)0 : [] { assert(false && #expr); }())
|
||||
#endif
|
||||
|
||||
#endif // ABSL_BASE_MACROS_H_
|
||||
|
||||
@ -63,34 +63,18 @@ void BM_StdVectorFill(benchmark::State& state) {
|
||||
}
|
||||
BENCHMARK(BM_StdVectorFill)->Range(0, 1024);
|
||||
|
||||
// The purpose of the next two benchmarks is to verify that
|
||||
// absl::InlinedVector is efficient when moving is more efficent than
|
||||
// copying. To do so, we use strings that are larger than the short
|
||||
// std::string optimization.
|
||||
bool StringRepresentedInline(std::string s) {
|
||||
const char* chars = s.data();
|
||||
std::string s1 = std::move(s);
|
||||
return s1.data() != chars;
|
||||
}
|
||||
|
||||
int GetNonShortStringOptimizationSize() {
|
||||
for (int i = 24; i <= 192; i *= 2) {
|
||||
if (!StringRepresentedInline(std::string(i, 'A'))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
ABSL_RAW_LOG(
|
||||
FATAL,
|
||||
"Failed to find a std::string larger than the short std::string optimization");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void BM_InlinedVectorFillString(benchmark::State& state) {
|
||||
const int len = state.range(0);
|
||||
const int no_sso = GetNonShortStringOptimizationSize();
|
||||
std::string strings[4] = {std::string(no_sso, 'A'), std::string(no_sso, 'B'),
|
||||
std::string(no_sso, 'C'), std::string(no_sso, 'D')};
|
||||
|
||||
std::string strings[4] = {"a quite long string",
|
||||
"another long string",
|
||||
"012345678901234567",
|
||||
"to cause allocation"};
|
||||
for (auto _ : state) {
|
||||
absl::InlinedVector<std::string, 8> v;
|
||||
for (int i = 0; i < len; i++) {
|
||||
@ -103,10 +87,10 @@ BENCHMARK(BM_InlinedVectorFillString)->Range(0, 1024);
|
||||
|
||||
void BM_StdVectorFillString(benchmark::State& state) {
|
||||
const int len = state.range(0);
|
||||
const int no_sso = GetNonShortStringOptimizationSize();
|
||||
std::string strings[4] = {std::string(no_sso, 'A'), std::string(no_sso, 'B'),
|
||||
std::string(no_sso, 'C'), std::string(no_sso, 'D')};
|
||||
|
||||
std::string strings[4] = {"a quite long string",
|
||||
"another long string",
|
||||
"012345678901234567",
|
||||
"to cause allocation"};
|
||||
for (auto _ : state) {
|
||||
std::vector<std::string> v;
|
||||
for (int i = 0; i < len; i++) {
|
||||
@ -114,6 +98,11 @@ void BM_StdVectorFillString(benchmark::State& state) {
|
||||
}
|
||||
}
|
||||
state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len);
|
||||
// The purpose of the benchmark is to verify that inlined vector is
|
||||
// efficient when moving is more efficent than copying. To do so, we
|
||||
// use strings that are larger than the small std::string optimization.
|
||||
ABSL_RAW_CHECK(!StringRepresentedInline(strings[0]),
|
||||
"benchmarked with strings that are too small");
|
||||
}
|
||||
BENCHMARK(BM_StdVectorFillString)->Range(0, 1024);
|
||||
|
||||
|
||||
14
third_party/abseil-cpp/absl/memory/BUILD.bazel
vendored
14
third_party/abseil-cpp/absl/memory/BUILD.bazel
vendored
@ -18,7 +18,6 @@ load(
|
||||
"//absl:copts.bzl",
|
||||
"ABSL_DEFAULT_COPTS",
|
||||
"ABSL_TEST_COPTS",
|
||||
"ABSL_EXCEPTIONS_FLAG",
|
||||
)
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
@ -46,16 +45,3 @@ cc_test(
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "memory_exception_safety_test",
|
||||
srcs = [
|
||||
"memory_exception_safety_test.cc",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
|
||||
deps = [
|
||||
":memory",
|
||||
"//absl/base:exception_safety_testing",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@ -49,23 +49,4 @@ absl_test(
|
||||
)
|
||||
|
||||
|
||||
# test memory_exception_safety_test
|
||||
set(MEMORY_EXCEPTION_SAFETY_TEST_SRC "memory_exception_safety_test.cc")
|
||||
set(MEMORY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES
|
||||
absl::memory
|
||||
absl_base_internal_exception_safety_testing
|
||||
)
|
||||
|
||||
absl_test(
|
||||
TARGET
|
||||
memory_exception_safety_test
|
||||
SOURCES
|
||||
${MEMORY_EXCEPTION_SAFETY_TEST_SRC}
|
||||
PUBLIC_LIBRARIES
|
||||
${MEMORY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES}
|
||||
PRIVATE_COMPILE_FLAGS
|
||||
${ABSL_EXCEPTIONS_FLAG}
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
// 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/memory/memory.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/internal/exception_safety_testing.h"
|
||||
|
||||
namespace absl {
|
||||
namespace {
|
||||
|
||||
using Thrower = ::testing::ThrowingValue<>;
|
||||
|
||||
TEST(MakeUnique, CheckForLeaks) {
|
||||
constexpr int kValue = 321;
|
||||
constexpr size_t kLength = 10;
|
||||
auto tester = testing::MakeExceptionSafetyTester()
|
||||
.WithInitialValue(Thrower(kValue))
|
||||
// Ensures make_unique does not modify the input. The real
|
||||
// test, though, is ConstructorTracker checking for leaks.
|
||||
.WithInvariants(testing::strong_guarantee);
|
||||
|
||||
EXPECT_TRUE(tester.Test([](Thrower* thrower) {
|
||||
static_cast<void>(absl::make_unique<Thrower>(*thrower));
|
||||
}));
|
||||
|
||||
EXPECT_TRUE(tester.Test([](Thrower* thrower) {
|
||||
static_cast<void>(absl::make_unique<Thrower>(std::move(*thrower)));
|
||||
}));
|
||||
|
||||
// Test T[n] overload
|
||||
EXPECT_TRUE(tester.Test([&](Thrower*) {
|
||||
static_cast<void>(absl::make_unique<Thrower[]>(kLength));
|
||||
}));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace absl
|
||||
74
third_party/abseil-cpp/absl/strings/BUILD.bazel
vendored
74
third_party/abseil-cpp/absl/strings/BUILD.bazel
vendored
@ -32,12 +32,7 @@ cc_library(
|
||||
name = "strings",
|
||||
srcs = [
|
||||
"ascii.cc",
|
||||
"charconv.cc",
|
||||
"escaping.cc",
|
||||
"internal/charconv_bigint.cc",
|
||||
"internal/charconv_bigint.h",
|
||||
"internal/charconv_parse.cc",
|
||||
"internal/charconv_parse.h",
|
||||
"internal/memutil.cc",
|
||||
"internal/memutil.h",
|
||||
"internal/stl_type_traits.h",
|
||||
@ -53,7 +48,6 @@ cc_library(
|
||||
],
|
||||
hdrs = [
|
||||
"ascii.h",
|
||||
"charconv.h",
|
||||
"escaping.h",
|
||||
"match.h",
|
||||
"numbers.h",
|
||||
@ -150,6 +144,11 @@ cc_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",
|
||||
@ -399,6 +398,12 @@ cc_test(
|
||||
"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"],
|
||||
deps = [
|
||||
":strings",
|
||||
@ -424,6 +429,11 @@ 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",
|
||||
@ -440,55 +450,3 @@ cc_test(
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "charconv_test",
|
||||
srcs = ["charconv_test.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
deps = [
|
||||
":strings",
|
||||
"//absl/base",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "charconv_parse_test",
|
||||
srcs = [
|
||||
"internal/charconv_parse.h",
|
||||
"internal/charconv_parse_test.cc",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
deps = [
|
||||
":strings",
|
||||
"//absl/base",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "charconv_bigint_test",
|
||||
srcs = [
|
||||
"internal/charconv_bigint.h",
|
||||
"internal/charconv_bigint_test.cc",
|
||||
"internal/charconv_parse.h",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
deps = [
|
||||
":strings",
|
||||
"//absl/base",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "charconv_benchmark",
|
||||
srcs = [
|
||||
"charconv_benchmark.cc",
|
||||
],
|
||||
deps = [
|
||||
":strings",
|
||||
"//absl/base",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
6
third_party/abseil-cpp/absl/strings/BUILD.gn
vendored
6
third_party/abseil-cpp/absl/strings/BUILD.gn
vendored
@ -22,12 +22,7 @@ source_set("strings") {
|
||||
public_configs = [ "//third_party/abseil-cpp:absl_include_config" ]
|
||||
sources = [
|
||||
"ascii.cc",
|
||||
"charconv.cc",
|
||||
"escaping.cc",
|
||||
"internal/charconv_bigint.cc",
|
||||
"internal/charconv_bigint.h",
|
||||
"internal/charconv_parse.cc",
|
||||
"internal/charconv_parse.h",
|
||||
"internal/memutil.cc",
|
||||
"internal/memutil.h",
|
||||
"internal/stl_type_traits.h",
|
||||
@ -43,7 +38,6 @@ source_set("strings") {
|
||||
]
|
||||
public = [
|
||||
"ascii.h",
|
||||
"charconv.h",
|
||||
"escaping.h",
|
||||
"match.h",
|
||||
"numbers.h",
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
|
||||
list(APPEND STRINGS_PUBLIC_HEADERS
|
||||
"ascii.h"
|
||||
"charconv.h"
|
||||
"escaping.h"
|
||||
"match.h"
|
||||
"numbers.h"
|
||||
@ -34,8 +33,6 @@ list(APPEND STRINGS_PUBLIC_HEADERS
|
||||
list(APPEND STRINGS_INTERNAL_HEADERS
|
||||
"internal/bits.h"
|
||||
"internal/char_map.h"
|
||||
"internal/charconv_bigint.h"
|
||||
"internal/charconv_parse.h"
|
||||
"internal/memutil.h"
|
||||
"internal/ostringstream.h"
|
||||
"internal/resize_uninitialized.h"
|
||||
@ -50,10 +47,7 @@ list(APPEND STRINGS_INTERNAL_HEADERS
|
||||
# add string library
|
||||
list(APPEND STRINGS_SRC
|
||||
"ascii.cc"
|
||||
"charconv.cc"
|
||||
"escaping.cc"
|
||||
"internal/charconv_bigint.cc"
|
||||
"internal/charconv_parse.cc"
|
||||
"internal/memutil.cc"
|
||||
"internal/memutil.h"
|
||||
"internal/utf8.cc"
|
||||
@ -307,43 +301,5 @@ absl_test(
|
||||
)
|
||||
|
||||
|
||||
# test charconv_test
|
||||
set(CHARCONV_TEST_SRC "charconv_test.cc")
|
||||
set(CHARCONV_TEST_PUBLIC_LIBRARIES absl::strings)
|
||||
|
||||
absl_test(
|
||||
TARGET
|
||||
charconv_test
|
||||
SOURCES
|
||||
${CHARCONV_TEST_SRC}
|
||||
PUBLIC_LIBRARIES
|
||||
${CHARCONV_TEST_PUBLIC_LIBRARIES}
|
||||
)
|
||||
|
||||
|
||||
# test charconv_parse_test
|
||||
set(CHARCONV_PARSE_TEST_SRC "internal/charconv_parse_test.cc")
|
||||
set(CHARCONV_PARSE_TEST_PUBLIC_LIBRARIES absl::strings)
|
||||
|
||||
absl_test(
|
||||
TARGET
|
||||
charconv_parse_test
|
||||
SOURCES
|
||||
${CHARCONV_PARSE_TEST_SRC}
|
||||
PUBLIC_LIBRARIES
|
||||
${CHARCONV_PARSE_TEST_PUBLIC_LIBRARIES}
|
||||
)
|
||||
|
||||
|
||||
# test charconv_bigint_test
|
||||
set(CHARCONV_BIGINT_TEST_SRC "internal/charconv_bigint_test.cc")
|
||||
set(CHARCONV_BIGINT_TEST_PUBLIC_LIBRARIES absl::strings)
|
||||
|
||||
absl_test(
|
||||
TARGET
|
||||
charconv_bigint_test
|
||||
SOURCES
|
||||
${CHARCONV_BIGINT_TEST_SRC}
|
||||
PUBLIC_LIBRARIES
|
||||
${CHARCONV_BIGINT_TEST_PUBLIC_LIBRARIES}
|
||||
)
|
||||
|
||||
982
third_party/abseil-cpp/absl/strings/charconv.cc
vendored
982
third_party/abseil-cpp/absl/strings/charconv.cc
vendored
@ -1,982 +0,0 @@
|
||||
// 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/charconv.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#include "absl/base/casts.h"
|
||||
#include "absl/numeric/int128.h"
|
||||
#include "absl/strings/internal/bits.h"
|
||||
#include "absl/strings/internal/charconv_bigint.h"
|
||||
#include "absl/strings/internal/charconv_parse.h"
|
||||
|
||||
// The macro ABSL_BIT_PACK_FLOATS is defined on x86-64, where IEEE floating
|
||||
// point numbers have the same endianness in memory as a bitfield struct
|
||||
// containing the corresponding parts.
|
||||
//
|
||||
// When set, we replace calls to ldexp() with manual bit packing, which is
|
||||
// faster and is unaffected by floating point environment.
|
||||
#ifdef ABSL_BIT_PACK_FLOATS
|
||||
#error ABSL_BIT_PACK_FLOATS cannot be directly set
|
||||
#elif defined(__x86_64__) || defined(_M_X64)
|
||||
#define ABSL_BIT_PACK_FLOATS 1
|
||||
#endif
|
||||
|
||||
// A note about subnormals:
|
||||
//
|
||||
// The code below talks about "normals" and "subnormals". A normal IEEE float
|
||||
// has a fixed-width mantissa and power of two exponent. For example, a normal
|
||||
// `double` has a 53-bit mantissa. Because the high bit is always 1, it is not
|
||||
// stored in the representation. The implicit bit buys an extra bit of
|
||||
// resolution in the datatype.
|
||||
//
|
||||
// The downside of this scheme is that there is a large gap between DBL_MIN and
|
||||
// zero. (Large, at least, relative to the different between DBL_MIN and the
|
||||
// next representable number). This gap is softened by the "subnormal" numbers,
|
||||
// which have the same power-of-two exponent as DBL_MIN, but no implicit 53rd
|
||||
// bit. An all-bits-zero exponent in the encoding represents subnormals. (Zero
|
||||
// is represented as a subnormal with an all-bits-zero mantissa.)
|
||||
//
|
||||
// The code below, in calculations, represents the mantissa as a uint64_t. The
|
||||
// end result normally has the 53rd bit set. It represents subnormals by using
|
||||
// narrower mantissas.
|
||||
|
||||
namespace absl {
|
||||
namespace {
|
||||
|
||||
template <typename FloatType>
|
||||
struct FloatTraits;
|
||||
|
||||
template <>
|
||||
struct FloatTraits<double> {
|
||||
// The number of mantissa bits in the given float type. This includes the
|
||||
// implied high bit.
|
||||
static constexpr int kTargetMantissaBits = 53;
|
||||
|
||||
// The largest supported IEEE exponent, in our integral mantissa
|
||||
// representation.
|
||||
//
|
||||
// If `m` is the largest possible int kTargetMantissaBits bits wide, then
|
||||
// m * 2**kMaxExponent is exactly equal to DBL_MAX.
|
||||
static constexpr int kMaxExponent = 971;
|
||||
|
||||
// The smallest supported IEEE normal exponent, in our integral mantissa
|
||||
// representation.
|
||||
//
|
||||
// If `m` is the smallest possible int kTargetMantissaBits bits wide, then
|
||||
// m * 2**kMinNormalExponent is exactly equal to DBL_MIN.
|
||||
static constexpr int kMinNormalExponent = -1074;
|
||||
|
||||
static double MakeNan(const char* tagp) {
|
||||
// Support nan no matter which namespace it's in. Some platforms
|
||||
// incorrectly don't put it in namespace std.
|
||||
using namespace std; // NOLINT
|
||||
return nan(tagp);
|
||||
}
|
||||
|
||||
// Builds a nonzero floating point number out of the provided parts.
|
||||
//
|
||||
// This is intended to do the same operation as ldexp(mantissa, exponent),
|
||||
// but using purely integer math, to avoid -ffastmath and floating
|
||||
// point environment issues. Using type punning is also faster. We fall back
|
||||
// to ldexp on a per-platform basis for portability.
|
||||
//
|
||||
// `exponent` must be between kMinNormalExponent and kMaxExponent.
|
||||
//
|
||||
// `mantissa` must either be exactly kTargetMantissaBits wide, in which case
|
||||
// a normal value is made, or it must be less narrow than that, in which case
|
||||
// `exponent` must be exactly kMinNormalExponent, and a subnormal value is
|
||||
// made.
|
||||
static double Make(uint64_t mantissa, int exponent, bool sign) {
|
||||
#ifndef ABSL_BIT_PACK_FLOATS
|
||||
// Support ldexp no matter which namespace it's in. Some platforms
|
||||
// incorrectly don't put it in namespace std.
|
||||
using namespace std; // NOLINT
|
||||
return sign ? -ldexp(mantissa, exponent) : ldexp(mantissa, exponent);
|
||||
#else
|
||||
constexpr uint64_t kMantissaMask =
|
||||
(uint64_t(1) << (kTargetMantissaBits - 1)) - 1;
|
||||
uint64_t dbl = static_cast<uint64_t>(sign) << 63;
|
||||
if (mantissa > kMantissaMask) {
|
||||
// Normal value.
|
||||
// Adjust by 1023 for the exponent representation bias, and an additional
|
||||
// 52 due to the implied decimal point in the IEEE mantissa represenation.
|
||||
dbl += uint64_t{exponent + 1023u + kTargetMantissaBits - 1} << 52;
|
||||
mantissa &= kMantissaMask;
|
||||
} else {
|
||||
// subnormal value
|
||||
assert(exponent == kMinNormalExponent);
|
||||
}
|
||||
dbl += mantissa;
|
||||
return absl::bit_cast<double>(dbl);
|
||||
#endif // ABSL_BIT_PACK_FLOATS
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization of floating point traits for the `float` type. See the
|
||||
// FloatTraits<double> specialization above for meaning of each of the following
|
||||
// members and methods.
|
||||
template <>
|
||||
struct FloatTraits<float> {
|
||||
static constexpr int kTargetMantissaBits = 24;
|
||||
static constexpr int kMaxExponent = 104;
|
||||
static constexpr int kMinNormalExponent = -149;
|
||||
static float MakeNan(const char* tagp) {
|
||||
// Support nanf no matter which namespace it's in. Some platforms
|
||||
// incorrectly don't put it in namespace std.
|
||||
using namespace std; // NOLINT
|
||||
return nanf(tagp);
|
||||
}
|
||||
static float Make(uint32_t mantissa, int exponent, bool sign) {
|
||||
#ifndef ABSL_BIT_PACK_FLOATS
|
||||
// Support ldexpf no matter which namespace it's in. Some platforms
|
||||
// incorrectly don't put it in namespace std.
|
||||
using namespace std; // NOLINT
|
||||
return sign ? -ldexpf(mantissa, exponent) : ldexpf(mantissa, exponent);
|
||||
#else
|
||||
constexpr uint32_t kMantissaMask =
|
||||
(uint32_t(1) << (kTargetMantissaBits - 1)) - 1;
|
||||
uint32_t flt = static_cast<uint32_t>(sign) << 31;
|
||||
if (mantissa > kMantissaMask) {
|
||||
// Normal value.
|
||||
// Adjust by 127 for the exponent representation bias, and an additional
|
||||
// 23 due to the implied decimal point in the IEEE mantissa represenation.
|
||||
flt += uint32_t{exponent + 127u + kTargetMantissaBits - 1} << 23;
|
||||
mantissa &= kMantissaMask;
|
||||
} else {
|
||||
// subnormal value
|
||||
assert(exponent == kMinNormalExponent);
|
||||
}
|
||||
flt += mantissa;
|
||||
return absl::bit_cast<float>(flt);
|
||||
#endif // ABSL_BIT_PACK_FLOATS
|
||||
}
|
||||
};
|
||||
|
||||
// Decimal-to-binary conversions require coercing powers of 10 into a mantissa
|
||||
// and a power of 2. The two helper functions Power10Mantissa(n) and
|
||||
// Power10Exponent(n) perform this task. Together, these represent a hand-
|
||||
// rolled floating point value which is equal to or just less than 10**n.
|
||||
//
|
||||
// The return values satisfy two range guarantees:
|
||||
//
|
||||
// Power10Mantissa(n) * 2**Power10Exponent(n) <= 10**n
|
||||
// < (Power10Mantissa(n) + 1) * 2**Power10Exponent(n)
|
||||
//
|
||||
// 2**63 <= Power10Mantissa(n) < 2**64.
|
||||
//
|
||||
// Lookups into the power-of-10 table must first check the Power10Overflow() and
|
||||
// Power10Underflow() functions, to avoid out-of-bounds table access.
|
||||
//
|
||||
// Indexes into these tables are biased by -kPower10TableMin, and the table has
|
||||
// values in the range [kPower10TableMin, kPower10TableMax].
|
||||
extern const uint64_t kPower10MantissaTable[];
|
||||
extern const int16_t kPower10ExponentTable[];
|
||||
|
||||
// The smallest allowed value for use with the Power10Mantissa() and
|
||||
// Power10Exponent() functions below. (If a smaller exponent is needed in
|
||||
// calculations, the end result is guaranteed to underflow.)
|
||||
constexpr int kPower10TableMin = -342;
|
||||
|
||||
// The largest allowed value for use with the Power10Mantissa() and
|
||||
// Power10Exponent() functions below. (If a smaller exponent is needed in
|
||||
// calculations, the end result is guaranteed to overflow.)
|
||||
constexpr int kPower10TableMax = 308;
|
||||
|
||||
uint64_t Power10Mantissa(int n) {
|
||||
return kPower10MantissaTable[n - kPower10TableMin];
|
||||
}
|
||||
|
||||
int Power10Exponent(int n) {
|
||||
return kPower10ExponentTable[n - kPower10TableMin];
|
||||
}
|
||||
|
||||
// Returns true if n is large enough that 10**n always results in an IEEE
|
||||
// overflow.
|
||||
bool Power10Overflow(int n) { return n > kPower10TableMax; }
|
||||
|
||||
// Returns true if n is small enough that 10**n times a ParsedFloat mantissa
|
||||
// always results in an IEEE underflow.
|
||||
bool Power10Underflow(int n) { return n < kPower10TableMin; }
|
||||
|
||||
// Returns true if Power10Mantissa(n) * 2**Power10Exponent(n) is exactly equal
|
||||
// to 10**n numerically. Put another way, this returns true if there is no
|
||||
// truncation error in Power10Mantissa(n).
|
||||
bool Power10Exact(int n) { return n >= 0 && n <= 27; }
|
||||
|
||||
// Sentinel exponent values for representing numbers too large or too close to
|
||||
// zero to represent in a double.
|
||||
constexpr int kOverflow = 99999;
|
||||
constexpr int kUnderflow = -99999;
|
||||
|
||||
// Struct representing the calculated conversion result of a positive (nonzero)
|
||||
// floating point number.
|
||||
//
|
||||
// The calculated number is mantissa * 2**exponent (mantissa is treated as an
|
||||
// integer.) `mantissa` is chosen to be the correct width for the IEEE float
|
||||
// representation being calculated. (`mantissa` will always have the same bit
|
||||
// width for normal values, and narrower bit widths for subnormals.)
|
||||
//
|
||||
// If the result of conversion was an underflow or overflow, exponent is set
|
||||
// to kUnderflow or kOverflow.
|
||||
struct CalculatedFloat {
|
||||
uint64_t mantissa = 0;
|
||||
int exponent = 0;
|
||||
};
|
||||
|
||||
// Returns the bit width of the given uint128. (Equivalently, returns 128
|
||||
// minus the number of leading zero bits.)
|
||||
int BitWidth(uint128 value) {
|
||||
if (Uint128High64(value) == 0) {
|
||||
return 64 - strings_internal::CountLeadingZeros64(Uint128Low64(value));
|
||||
}
|
||||
return 128 - strings_internal::CountLeadingZeros64(Uint128High64(value));
|
||||
}
|
||||
|
||||
// Calculates how far to the right a mantissa needs to be shifted to create a
|
||||
// properly adjusted mantissa for an IEEE floating point number.
|
||||
//
|
||||
// `mantissa_width` is the bit width of the mantissa to be shifted, and
|
||||
// `binary_exponent` is the exponent of the number before the shift.
|
||||
//
|
||||
// This accounts for subnormal values, and will return a larger-than-normal
|
||||
// shift if binary_exponent would otherwise be too low.
|
||||
template <typename FloatType>
|
||||
int NormalizedShiftSize(int mantissa_width, int binary_exponent) {
|
||||
const int normal_shift =
|
||||
mantissa_width - FloatTraits<FloatType>::kTargetMantissaBits;
|
||||
const int minimum_shift =
|
||||
FloatTraits<FloatType>::kMinNormalExponent - binary_exponent;
|
||||
return std::max(normal_shift, minimum_shift);
|
||||
}
|
||||
|
||||
// Right shifts a uint128 so that it has the requested bit width. (The
|
||||
// resulting value will have 128 - bit_width leading zeroes.) The initial
|
||||
// `value` must be wider than the requested bit width.
|
||||
//
|
||||
// Returns the number of bits shifted.
|
||||
int TruncateToBitWidth(int bit_width, uint128* value) {
|
||||
const int current_bit_width = BitWidth(*value);
|
||||
const int shift = current_bit_width - bit_width;
|
||||
*value >>= shift;
|
||||
return shift;
|
||||
}
|
||||
|
||||
// Checks if the given ParsedFloat represents one of the edge cases that are
|
||||
// not dependent on number base: zero, infinity, or NaN. If so, sets *value
|
||||
// the appropriate double, and returns true.
|
||||
template <typename FloatType>
|
||||
bool HandleEdgeCase(const strings_internal::ParsedFloat& input, bool negative,
|
||||
FloatType* value) {
|
||||
if (input.type == strings_internal::FloatType::kNan) {
|
||||
// A bug in both clang and gcc would cause the compiler to optimize away the
|
||||
// buffer we are building below. Declaring the buffer volatile avoids the
|
||||
// issue, and has no measurable performance impact in microbenchmarks.
|
||||
//
|
||||
// https://bugs.llvm.org/show_bug.cgi?id=37778
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86113
|
||||
constexpr ptrdiff_t kNanBufferSize = 128;
|
||||
volatile char n_char_sequence[kNanBufferSize];
|
||||
if (input.subrange_begin == nullptr) {
|
||||
n_char_sequence[0] = '\0';
|
||||
} else {
|
||||
ptrdiff_t nan_size = input.subrange_end - input.subrange_begin;
|
||||
nan_size = std::min(nan_size, kNanBufferSize - 1);
|
||||
std::copy_n(input.subrange_begin, nan_size, n_char_sequence);
|
||||
n_char_sequence[nan_size] = '\0';
|
||||
}
|
||||
char* nan_argument = const_cast<char*>(n_char_sequence);
|
||||
*value = negative ? -FloatTraits<FloatType>::MakeNan(nan_argument)
|
||||
: FloatTraits<FloatType>::MakeNan(nan_argument);
|
||||
return true;
|
||||
}
|
||||
if (input.type == strings_internal::FloatType::kInfinity) {
|
||||
*value = negative ? -std::numeric_limits<FloatType>::infinity()
|
||||
: std::numeric_limits<FloatType>::infinity();
|
||||
return true;
|
||||
}
|
||||
if (input.mantissa == 0) {
|
||||
*value = negative ? -0.0 : 0.0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Given a CalculatedFloat result of a from_chars conversion, generate the
|
||||
// correct output values.
|
||||
//
|
||||
// CalculatedFloat can represent an underflow or overflow, in which case the
|
||||
// error code in *result is set. Otherwise, the calculated floating point
|
||||
// number is stored in *value.
|
||||
template <typename FloatType>
|
||||
void EncodeResult(const CalculatedFloat& calculated, bool negative,
|
||||
absl::from_chars_result* result, FloatType* value) {
|
||||
if (calculated.exponent == kOverflow) {
|
||||
result->ec = std::errc::result_out_of_range;
|
||||
*value = negative ? -std::numeric_limits<FloatType>::max()
|
||||
: std::numeric_limits<FloatType>::max();
|
||||
return;
|
||||
} else if (calculated.mantissa == 0 || calculated.exponent == kUnderflow) {
|
||||
result->ec = std::errc::result_out_of_range;
|
||||
*value = negative ? -0.0 : 0.0;
|
||||
return;
|
||||
}
|
||||
*value = FloatTraits<FloatType>::Make(calculated.mantissa,
|
||||
calculated.exponent, negative);
|
||||
}
|
||||
|
||||
// Returns the given uint128 shifted to the right by `shift` bits, and rounds
|
||||
// the remaining bits using round_to_nearest logic. The value is returned as a
|
||||
// uint64_t, since this is the type used by this library for storing calculated
|
||||
// floating point mantissas.
|
||||
//
|
||||
// It is expected that the width of the input value shifted by `shift` will
|
||||
// be the correct bit-width for the target mantissa, which is strictly narrower
|
||||
// than a uint64_t.
|
||||
//
|
||||
// If `input_exact` is false, then a nonzero error epsilon is assumed. For
|
||||
// rounding purposes, the true value being rounded is strictly greater than the
|
||||
// input value. The error may represent a single lost carry bit.
|
||||
//
|
||||
// When input_exact, shifted bits of the form 1000000... represent a tie, which
|
||||
// is broken by rounding to even -- the rounding direction is chosen so the low
|
||||
// bit of the returned value is 0.
|
||||
//
|
||||
// When !input_exact, shifted bits of the form 10000000... represent a value
|
||||
// strictly greater than one half (due to the error epsilon), and so ties are
|
||||
// always broken by rounding up.
|
||||
//
|
||||
// When !input_exact, shifted bits of the form 01111111... are uncertain;
|
||||
// the true value may or may not be greater than 10000000..., due to the
|
||||
// possible lost carry bit. The correct rounding direction is unknown. In this
|
||||
// case, the result is rounded down, and `output_exact` is set to false.
|
||||
//
|
||||
// Zero and negative values of `shift` are accepted, in which case the word is
|
||||
// shifted left, as necessary.
|
||||
uint64_t ShiftRightAndRound(uint128 value, int shift, bool input_exact,
|
||||
bool* output_exact) {
|
||||
if (shift <= 0) {
|
||||
*output_exact = input_exact;
|
||||
return static_cast<uint64_t>(value << -shift);
|
||||
}
|
||||
if (shift >= 128) {
|
||||
// Exponent is so small that we are shifting away all significant bits.
|
||||
// Answer will not be representable, even as a subnormal, so return a zero
|
||||
// mantissa (which represents underflow).
|
||||
*output_exact = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*output_exact = true;
|
||||
const uint128 shift_mask = (uint128(1) << shift) - 1;
|
||||
const uint128 halfway_point = uint128(1) << (shift - 1);
|
||||
|
||||
const uint128 shifted_bits = value & shift_mask;
|
||||
value >>= shift;
|
||||
if (shifted_bits > halfway_point) {
|
||||
// Shifted bits greater than 10000... require rounding up.
|
||||
return static_cast<uint64_t>(value + 1);
|
||||
}
|
||||
if (shifted_bits == halfway_point) {
|
||||
// In exact mode, shifted bits of 10000... mean we're exactly halfway
|
||||
// between two numbers, and we must round to even. So only round up if
|
||||
// the low bit of `value` is set.
|
||||
//
|
||||
// In inexact mode, the nonzero error means the actual value is greater
|
||||
// than the halfway point and we must alway round up.
|
||||
if ((value & 1) == 1 || !input_exact) {
|
||||
++value;
|
||||
}
|
||||
return static_cast<uint64_t>(value);
|
||||
}
|
||||
if (!input_exact && shifted_bits == halfway_point - 1) {
|
||||
// Rounding direction is unclear, due to error.
|
||||
*output_exact = false;
|
||||
}
|
||||
// Otherwise, round down.
|
||||
return static_cast<uint64_t>(value);
|
||||
}
|
||||
|
||||
// Checks if a floating point guess needs to be rounded up, using high precision
|
||||
// math.
|
||||
//
|
||||
// `guess_mantissa` and `guess_exponent` represent a candidate guess for the
|
||||
// number represented by `parsed_decimal`.
|
||||
//
|
||||
// The exact number represented by `parsed_decimal` must lie between the two
|
||||
// numbers:
|
||||
// A = `guess_mantissa * 2**guess_exponent`
|
||||
// B = `(guess_mantissa + 1) * 2**guess_exponent`
|
||||
//
|
||||
// This function returns false if `A` is the better guess, and true if `B` is
|
||||
// the better guess, with rounding ties broken by rounding to even.
|
||||
bool MustRoundUp(uint64_t guess_mantissa, int guess_exponent,
|
||||
const strings_internal::ParsedFloat& parsed_decimal) {
|
||||
// 768 is the number of digits needed in the worst case. We could determine a
|
||||
// better limit dynamically based on the value of parsed_decimal.exponent.
|
||||
// This would optimize pathological input cases only. (Sane inputs won't have
|
||||
// hundreds of digits of mantissa.)
|
||||
absl::strings_internal::BigUnsigned<84> exact_mantissa;
|
||||
int exact_exponent = exact_mantissa.ReadFloatMantissa(parsed_decimal, 768);
|
||||
|
||||
// Adjust the `guess` arguments to be halfway between A and B.
|
||||
guess_mantissa = guess_mantissa * 2 + 1;
|
||||
guess_exponent -= 1;
|
||||
|
||||
// In our comparison:
|
||||
// lhs = exact = exact_mantissa * 10**exact_exponent
|
||||
// = exact_mantissa * 5**exact_exponent * 2**exact_exponent
|
||||
// rhs = guess = guess_mantissa * 2**guess_exponent
|
||||
//
|
||||
// Because we are doing integer math, we can't directly deal with negative
|
||||
// exponents. We instead move these to the other side of the inequality.
|
||||
absl::strings_internal::BigUnsigned<84>& lhs = exact_mantissa;
|
||||
int comparison;
|
||||
if (exact_exponent >= 0) {
|
||||
lhs.MultiplyByFiveToTheNth(exact_exponent);
|
||||
absl::strings_internal::BigUnsigned<84> rhs(guess_mantissa);
|
||||
// There are powers of 2 on both sides of the inequality; reduce this to
|
||||
// a single bit-shift.
|
||||
if (exact_exponent > guess_exponent) {
|
||||
lhs.ShiftLeft(exact_exponent - guess_exponent);
|
||||
} else {
|
||||
rhs.ShiftLeft(guess_exponent - exact_exponent);
|
||||
}
|
||||
comparison = Compare(lhs, rhs);
|
||||
} else {
|
||||
// Move the power of 5 to the other side of the equation, giving us:
|
||||
// lhs = exact_mantissa * 2**exact_exponent
|
||||
// rhs = guess_mantissa * 5**(-exact_exponent) * 2**guess_exponent
|
||||
absl::strings_internal::BigUnsigned<84> rhs =
|
||||
absl::strings_internal::BigUnsigned<84>::FiveToTheNth(-exact_exponent);
|
||||
rhs.MultiplyBy(guess_mantissa);
|
||||
if (exact_exponent > guess_exponent) {
|
||||
lhs.ShiftLeft(exact_exponent - guess_exponent);
|
||||
} else {
|
||||
rhs.ShiftLeft(guess_exponent - exact_exponent);
|
||||
}
|
||||
comparison = Compare(lhs, rhs);
|
||||
}
|
||||
if (comparison < 0) {
|
||||
return false;
|
||||
} else if (comparison > 0) {
|
||||
return true;
|
||||
} else {
|
||||
// When lhs == rhs, the decimal input is exactly between A and B.
|
||||
// Round towards even -- round up only if the low bit of the initial
|
||||
// `guess_mantissa` was a 1. We shifted guess_mantissa left 1 bit at
|
||||
// the beginning of this function, so test the 2nd bit here.
|
||||
return (guess_mantissa & 2) == 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Constructs a CalculatedFloat from a given mantissa and exponent, but
|
||||
// with the following normalizations applied:
|
||||
//
|
||||
// If rounding has caused mantissa to increase just past the allowed bit
|
||||
// width, shift and adjust exponent.
|
||||
//
|
||||
// If exponent is too high, sets kOverflow.
|
||||
//
|
||||
// If mantissa is zero (representing a non-zero value not representable, even
|
||||
// as a subnormal), sets kUnderflow.
|
||||
template <typename FloatType>
|
||||
CalculatedFloat CalculatedFloatFromRawValues(uint64_t mantissa, int exponent) {
|
||||
CalculatedFloat result;
|
||||
if (mantissa == uint64_t(1) << FloatTraits<FloatType>::kTargetMantissaBits) {
|
||||
mantissa >>= 1;
|
||||
exponent += 1;
|
||||
}
|
||||
if (exponent > FloatTraits<FloatType>::kMaxExponent) {
|
||||
result.exponent = kOverflow;
|
||||
} else if (mantissa == 0) {
|
||||
result.exponent = kUnderflow;
|
||||
} else {
|
||||
result.exponent = exponent;
|
||||
result.mantissa = mantissa;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename FloatType>
|
||||
CalculatedFloat CalculateFromParsedHexadecimal(
|
||||
const strings_internal::ParsedFloat& parsed_hex) {
|
||||
uint64_t mantissa = parsed_hex.mantissa;
|
||||
int exponent = parsed_hex.exponent;
|
||||
int mantissa_width = 64 - strings_internal::CountLeadingZeros64(mantissa);
|
||||
const int shift = NormalizedShiftSize<FloatType>(mantissa_width, exponent);
|
||||
bool result_exact;
|
||||
exponent += shift;
|
||||
mantissa = ShiftRightAndRound(mantissa, shift,
|
||||
/* input exact= */ true, &result_exact);
|
||||
// ParseFloat handles rounding in the hexadecimal case, so we don't have to
|
||||
// check `result_exact` here.
|
||||
return CalculatedFloatFromRawValues<FloatType>(mantissa, exponent);
|
||||
}
|
||||
|
||||
template <typename FloatType>
|
||||
CalculatedFloat CalculateFromParsedDecimal(
|
||||
const strings_internal::ParsedFloat& parsed_decimal) {
|
||||
CalculatedFloat result;
|
||||
|
||||
// Large or small enough decimal exponents will always result in overflow
|
||||
// or underflow.
|
||||
if (Power10Underflow(parsed_decimal.exponent)) {
|
||||
result.exponent = kUnderflow;
|
||||
return result;
|
||||
} else if (Power10Overflow(parsed_decimal.exponent)) {
|
||||
result.exponent = kOverflow;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Otherwise convert our power of 10 into a power of 2 times an integer
|
||||
// mantissa, and multiply this by our parsed decimal mantissa.
|
||||
uint128 wide_binary_mantissa = parsed_decimal.mantissa;
|
||||
wide_binary_mantissa *= Power10Mantissa(parsed_decimal.exponent);
|
||||
int binary_exponent = Power10Exponent(parsed_decimal.exponent);
|
||||
|
||||
// Discard bits that are inaccurate due to truncation error. The magic
|
||||
// `mantissa_width` constants below are justified in charconv_algorithm.md.
|
||||
// They represent the number of bits in `wide_binary_mantissa` that are
|
||||
// guaranteed to be unaffected by error propagation.
|
||||
bool mantissa_exact;
|
||||
int mantissa_width;
|
||||
if (parsed_decimal.subrange_begin) {
|
||||
// Truncated mantissa
|
||||
mantissa_width = 58;
|
||||
mantissa_exact = false;
|
||||
binary_exponent +=
|
||||
TruncateToBitWidth(mantissa_width, &wide_binary_mantissa);
|
||||
} else if (!Power10Exact(parsed_decimal.exponent)) {
|
||||
// Exact mantissa, truncated power of ten
|
||||
mantissa_width = 63;
|
||||
mantissa_exact = false;
|
||||
binary_exponent +=
|
||||
TruncateToBitWidth(mantissa_width, &wide_binary_mantissa);
|
||||
} else {
|
||||
// Product is exact
|
||||
mantissa_width = BitWidth(wide_binary_mantissa);
|
||||
mantissa_exact = true;
|
||||
}
|
||||
|
||||
// Shift into an FloatType-sized mantissa, and round to nearest.
|
||||
const int shift =
|
||||
NormalizedShiftSize<FloatType>(mantissa_width, binary_exponent);
|
||||
bool result_exact;
|
||||
binary_exponent += shift;
|
||||
uint64_t binary_mantissa = ShiftRightAndRound(wide_binary_mantissa, shift,
|
||||
mantissa_exact, &result_exact);
|
||||
if (!result_exact) {
|
||||
// We could not determine the rounding direction using int128 math. Use
|
||||
// full resolution math instead.
|
||||
if (MustRoundUp(binary_mantissa, binary_exponent, parsed_decimal)) {
|
||||
binary_mantissa += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return CalculatedFloatFromRawValues<FloatType>(binary_mantissa,
|
||||
binary_exponent);
|
||||
}
|
||||
|
||||
template <typename FloatType>
|
||||
from_chars_result FromCharsImpl(const char* first, const char* last,
|
||||
FloatType& value, chars_format fmt_flags) {
|
||||
from_chars_result result;
|
||||
result.ptr = first; // overwritten on successful parse
|
||||
result.ec = std::errc();
|
||||
|
||||
bool negative = false;
|
||||
if (first != last && *first == '-') {
|
||||
++first;
|
||||
negative = true;
|
||||
}
|
||||
// If the `hex` flag is *not* set, then we will accept a 0x prefix and try
|
||||
// to parse a hexadecimal float.
|
||||
if ((fmt_flags & chars_format::hex) == chars_format{} && last - first >= 2 &&
|
||||
*first == '0' && (first[1] == 'x' || first[1] == 'X')) {
|
||||
const char* hex_first = first + 2;
|
||||
strings_internal::ParsedFloat hex_parse =
|
||||
strings_internal::ParseFloat<16>(hex_first, last, fmt_flags);
|
||||
if (hex_parse.end == nullptr ||
|
||||
hex_parse.type != strings_internal::FloatType::kNumber) {
|
||||
// Either we failed to parse a hex float after the "0x", or we read
|
||||
// "0xinf" or "0xnan" which we don't want to match.
|
||||
//
|
||||
// However, a std::string that begins with "0x" also begins with "0", which
|
||||
// is normally a valid match for the number zero. So we want these
|
||||
// strings to match zero unless fmt_flags is `scientific`. (This flag
|
||||
// means an exponent is required, which the std::string "0" does not have.)
|
||||
if (fmt_flags == chars_format::scientific) {
|
||||
result.ec = std::errc::invalid_argument;
|
||||
} else {
|
||||
result.ptr = first + 1;
|
||||
value = negative ? -0.0 : 0.0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// We matched a value.
|
||||
result.ptr = hex_parse.end;
|
||||
if (HandleEdgeCase(hex_parse, negative, &value)) {
|
||||
return result;
|
||||
}
|
||||
CalculatedFloat calculated =
|
||||
CalculateFromParsedHexadecimal<FloatType>(hex_parse);
|
||||
EncodeResult(calculated, negative, &result, &value);
|
||||
return result;
|
||||
}
|
||||
// Otherwise, we choose the number base based on the flags.
|
||||
if ((fmt_flags & chars_format::hex) == chars_format::hex) {
|
||||
strings_internal::ParsedFloat hex_parse =
|
||||
strings_internal::ParseFloat<16>(first, last, fmt_flags);
|
||||
if (hex_parse.end == nullptr) {
|
||||
result.ec = std::errc::invalid_argument;
|
||||
return result;
|
||||
}
|
||||
result.ptr = hex_parse.end;
|
||||
if (HandleEdgeCase(hex_parse, negative, &value)) {
|
||||
return result;
|
||||
}
|
||||
CalculatedFloat calculated =
|
||||
CalculateFromParsedHexadecimal<FloatType>(hex_parse);
|
||||
EncodeResult(calculated, negative, &result, &value);
|
||||
return result;
|
||||
} else {
|
||||
strings_internal::ParsedFloat decimal_parse =
|
||||
strings_internal::ParseFloat<10>(first, last, fmt_flags);
|
||||
if (decimal_parse.end == nullptr) {
|
||||
result.ec = std::errc::invalid_argument;
|
||||
return result;
|
||||
}
|
||||
result.ptr = decimal_parse.end;
|
||||
if (HandleEdgeCase(decimal_parse, negative, &value)) {
|
||||
return result;
|
||||
}
|
||||
CalculatedFloat calculated =
|
||||
CalculateFromParsedDecimal<FloatType>(decimal_parse);
|
||||
EncodeResult(calculated, negative, &result, &value);
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
from_chars_result from_chars(const char* first, const char* last, double& value,
|
||||
chars_format fmt) {
|
||||
return FromCharsImpl(first, last, value, fmt);
|
||||
}
|
||||
|
||||
from_chars_result from_chars(const char* first, const char* last, float& value,
|
||||
chars_format fmt) {
|
||||
return FromCharsImpl(first, last, value, fmt);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Table of powers of 10, from kPower10TableMin to kPower10TableMax.
|
||||
//
|
||||
// kPower10MantissaTable[i - kPower10TableMin] stores the 64-bit mantissa (high
|
||||
// bit always on), and kPower10ExponentTable[i - kPower10TableMin] stores the
|
||||
// power-of-two exponent. For a given number i, this gives the unique mantissa
|
||||
// and exponent such that mantissa * 2**exponent <= 10**i < (mantissa + 1) *
|
||||
// 2**exponent.
|
||||
|
||||
const uint64_t kPower10MantissaTable[] = {
|
||||
0xeef453d6923bd65aU, 0x9558b4661b6565f8U, 0xbaaee17fa23ebf76U,
|
||||
0xe95a99df8ace6f53U, 0x91d8a02bb6c10594U, 0xb64ec836a47146f9U,
|
||||
0xe3e27a444d8d98b7U, 0x8e6d8c6ab0787f72U, 0xb208ef855c969f4fU,
|
||||
0xde8b2b66b3bc4723U, 0x8b16fb203055ac76U, 0xaddcb9e83c6b1793U,
|
||||
0xd953e8624b85dd78U, 0x87d4713d6f33aa6bU, 0xa9c98d8ccb009506U,
|
||||
0xd43bf0effdc0ba48U, 0x84a57695fe98746dU, 0xa5ced43b7e3e9188U,
|
||||
0xcf42894a5dce35eaU, 0x818995ce7aa0e1b2U, 0xa1ebfb4219491a1fU,
|
||||
0xca66fa129f9b60a6U, 0xfd00b897478238d0U, 0x9e20735e8cb16382U,
|
||||
0xc5a890362fddbc62U, 0xf712b443bbd52b7bU, 0x9a6bb0aa55653b2dU,
|
||||
0xc1069cd4eabe89f8U, 0xf148440a256e2c76U, 0x96cd2a865764dbcaU,
|
||||
0xbc807527ed3e12bcU, 0xeba09271e88d976bU, 0x93445b8731587ea3U,
|
||||
0xb8157268fdae9e4cU, 0xe61acf033d1a45dfU, 0x8fd0c16206306babU,
|
||||
0xb3c4f1ba87bc8696U, 0xe0b62e2929aba83cU, 0x8c71dcd9ba0b4925U,
|
||||
0xaf8e5410288e1b6fU, 0xdb71e91432b1a24aU, 0x892731ac9faf056eU,
|
||||
0xab70fe17c79ac6caU, 0xd64d3d9db981787dU, 0x85f0468293f0eb4eU,
|
||||
0xa76c582338ed2621U, 0xd1476e2c07286faaU, 0x82cca4db847945caU,
|
||||
0xa37fce126597973cU, 0xcc5fc196fefd7d0cU, 0xff77b1fcbebcdc4fU,
|
||||
0x9faacf3df73609b1U, 0xc795830d75038c1dU, 0xf97ae3d0d2446f25U,
|
||||
0x9becce62836ac577U, 0xc2e801fb244576d5U, 0xf3a20279ed56d48aU,
|
||||
0x9845418c345644d6U, 0xbe5691ef416bd60cU, 0xedec366b11c6cb8fU,
|
||||
0x94b3a202eb1c3f39U, 0xb9e08a83a5e34f07U, 0xe858ad248f5c22c9U,
|
||||
0x91376c36d99995beU, 0xb58547448ffffb2dU, 0xe2e69915b3fff9f9U,
|
||||
0x8dd01fad907ffc3bU, 0xb1442798f49ffb4aU, 0xdd95317f31c7fa1dU,
|
||||
0x8a7d3eef7f1cfc52U, 0xad1c8eab5ee43b66U, 0xd863b256369d4a40U,
|
||||
0x873e4f75e2224e68U, 0xa90de3535aaae202U, 0xd3515c2831559a83U,
|
||||
0x8412d9991ed58091U, 0xa5178fff668ae0b6U, 0xce5d73ff402d98e3U,
|
||||
0x80fa687f881c7f8eU, 0xa139029f6a239f72U, 0xc987434744ac874eU,
|
||||
0xfbe9141915d7a922U, 0x9d71ac8fada6c9b5U, 0xc4ce17b399107c22U,
|
||||
0xf6019da07f549b2bU, 0x99c102844f94e0fbU, 0xc0314325637a1939U,
|
||||
0xf03d93eebc589f88U, 0x96267c7535b763b5U, 0xbbb01b9283253ca2U,
|
||||
0xea9c227723ee8bcbU, 0x92a1958a7675175fU, 0xb749faed14125d36U,
|
||||
0xe51c79a85916f484U, 0x8f31cc0937ae58d2U, 0xb2fe3f0b8599ef07U,
|
||||
0xdfbdcece67006ac9U, 0x8bd6a141006042bdU, 0xaecc49914078536dU,
|
||||
0xda7f5bf590966848U, 0x888f99797a5e012dU, 0xaab37fd7d8f58178U,
|
||||
0xd5605fcdcf32e1d6U, 0x855c3be0a17fcd26U, 0xa6b34ad8c9dfc06fU,
|
||||
0xd0601d8efc57b08bU, 0x823c12795db6ce57U, 0xa2cb1717b52481edU,
|
||||
0xcb7ddcdda26da268U, 0xfe5d54150b090b02U, 0x9efa548d26e5a6e1U,
|
||||
0xc6b8e9b0709f109aU, 0xf867241c8cc6d4c0U, 0x9b407691d7fc44f8U,
|
||||
0xc21094364dfb5636U, 0xf294b943e17a2bc4U, 0x979cf3ca6cec5b5aU,
|
||||
0xbd8430bd08277231U, 0xece53cec4a314ebdU, 0x940f4613ae5ed136U,
|
||||
0xb913179899f68584U, 0xe757dd7ec07426e5U, 0x9096ea6f3848984fU,
|
||||
0xb4bca50b065abe63U, 0xe1ebce4dc7f16dfbU, 0x8d3360f09cf6e4bdU,
|
||||
0xb080392cc4349decU, 0xdca04777f541c567U, 0x89e42caaf9491b60U,
|
||||
0xac5d37d5b79b6239U, 0xd77485cb25823ac7U, 0x86a8d39ef77164bcU,
|
||||
0xa8530886b54dbdebU, 0xd267caa862a12d66U, 0x8380dea93da4bc60U,
|
||||
0xa46116538d0deb78U, 0xcd795be870516656U, 0x806bd9714632dff6U,
|
||||
0xa086cfcd97bf97f3U, 0xc8a883c0fdaf7df0U, 0xfad2a4b13d1b5d6cU,
|
||||
0x9cc3a6eec6311a63U, 0xc3f490aa77bd60fcU, 0xf4f1b4d515acb93bU,
|
||||
0x991711052d8bf3c5U, 0xbf5cd54678eef0b6U, 0xef340a98172aace4U,
|
||||
0x9580869f0e7aac0eU, 0xbae0a846d2195712U, 0xe998d258869facd7U,
|
||||
0x91ff83775423cc06U, 0xb67f6455292cbf08U, 0xe41f3d6a7377eecaU,
|
||||
0x8e938662882af53eU, 0xb23867fb2a35b28dU, 0xdec681f9f4c31f31U,
|
||||
0x8b3c113c38f9f37eU, 0xae0b158b4738705eU, 0xd98ddaee19068c76U,
|
||||
0x87f8a8d4cfa417c9U, 0xa9f6d30a038d1dbcU, 0xd47487cc8470652bU,
|
||||
0x84c8d4dfd2c63f3bU, 0xa5fb0a17c777cf09U, 0xcf79cc9db955c2ccU,
|
||||
0x81ac1fe293d599bfU, 0xa21727db38cb002fU, 0xca9cf1d206fdc03bU,
|
||||
0xfd442e4688bd304aU, 0x9e4a9cec15763e2eU, 0xc5dd44271ad3cdbaU,
|
||||
0xf7549530e188c128U, 0x9a94dd3e8cf578b9U, 0xc13a148e3032d6e7U,
|
||||
0xf18899b1bc3f8ca1U, 0x96f5600f15a7b7e5U, 0xbcb2b812db11a5deU,
|
||||
0xebdf661791d60f56U, 0x936b9fcebb25c995U, 0xb84687c269ef3bfbU,
|
||||
0xe65829b3046b0afaU, 0x8ff71a0fe2c2e6dcU, 0xb3f4e093db73a093U,
|
||||
0xe0f218b8d25088b8U, 0x8c974f7383725573U, 0xafbd2350644eeacfU,
|
||||
0xdbac6c247d62a583U, 0x894bc396ce5da772U, 0xab9eb47c81f5114fU,
|
||||
0xd686619ba27255a2U, 0x8613fd0145877585U, 0xa798fc4196e952e7U,
|
||||
0xd17f3b51fca3a7a0U, 0x82ef85133de648c4U, 0xa3ab66580d5fdaf5U,
|
||||
0xcc963fee10b7d1b3U, 0xffbbcfe994e5c61fU, 0x9fd561f1fd0f9bd3U,
|
||||
0xc7caba6e7c5382c8U, 0xf9bd690a1b68637bU, 0x9c1661a651213e2dU,
|
||||
0xc31bfa0fe5698db8U, 0xf3e2f893dec3f126U, 0x986ddb5c6b3a76b7U,
|
||||
0xbe89523386091465U, 0xee2ba6c0678b597fU, 0x94db483840b717efU,
|
||||
0xba121a4650e4ddebU, 0xe896a0d7e51e1566U, 0x915e2486ef32cd60U,
|
||||
0xb5b5ada8aaff80b8U, 0xe3231912d5bf60e6U, 0x8df5efabc5979c8fU,
|
||||
0xb1736b96b6fd83b3U, 0xddd0467c64bce4a0U, 0x8aa22c0dbef60ee4U,
|
||||
0xad4ab7112eb3929dU, 0xd89d64d57a607744U, 0x87625f056c7c4a8bU,
|
||||
0xa93af6c6c79b5d2dU, 0xd389b47879823479U, 0x843610cb4bf160cbU,
|
||||
0xa54394fe1eedb8feU, 0xce947a3da6a9273eU, 0x811ccc668829b887U,
|
||||
0xa163ff802a3426a8U, 0xc9bcff6034c13052U, 0xfc2c3f3841f17c67U,
|
||||
0x9d9ba7832936edc0U, 0xc5029163f384a931U, 0xf64335bcf065d37dU,
|
||||
0x99ea0196163fa42eU, 0xc06481fb9bcf8d39U, 0xf07da27a82c37088U,
|
||||
0x964e858c91ba2655U, 0xbbe226efb628afeaU, 0xeadab0aba3b2dbe5U,
|
||||
0x92c8ae6b464fc96fU, 0xb77ada0617e3bbcbU, 0xe55990879ddcaabdU,
|
||||
0x8f57fa54c2a9eab6U, 0xb32df8e9f3546564U, 0xdff9772470297ebdU,
|
||||
0x8bfbea76c619ef36U, 0xaefae51477a06b03U, 0xdab99e59958885c4U,
|
||||
0x88b402f7fd75539bU, 0xaae103b5fcd2a881U, 0xd59944a37c0752a2U,
|
||||
0x857fcae62d8493a5U, 0xa6dfbd9fb8e5b88eU, 0xd097ad07a71f26b2U,
|
||||
0x825ecc24c873782fU, 0xa2f67f2dfa90563bU, 0xcbb41ef979346bcaU,
|
||||
0xfea126b7d78186bcU, 0x9f24b832e6b0f436U, 0xc6ede63fa05d3143U,
|
||||
0xf8a95fcf88747d94U, 0x9b69dbe1b548ce7cU, 0xc24452da229b021bU,
|
||||
0xf2d56790ab41c2a2U, 0x97c560ba6b0919a5U, 0xbdb6b8e905cb600fU,
|
||||
0xed246723473e3813U, 0x9436c0760c86e30bU, 0xb94470938fa89bceU,
|
||||
0xe7958cb87392c2c2U, 0x90bd77f3483bb9b9U, 0xb4ecd5f01a4aa828U,
|
||||
0xe2280b6c20dd5232U, 0x8d590723948a535fU, 0xb0af48ec79ace837U,
|
||||
0xdcdb1b2798182244U, 0x8a08f0f8bf0f156bU, 0xac8b2d36eed2dac5U,
|
||||
0xd7adf884aa879177U, 0x86ccbb52ea94baeaU, 0xa87fea27a539e9a5U,
|
||||
0xd29fe4b18e88640eU, 0x83a3eeeef9153e89U, 0xa48ceaaab75a8e2bU,
|
||||
0xcdb02555653131b6U, 0x808e17555f3ebf11U, 0xa0b19d2ab70e6ed6U,
|
||||
0xc8de047564d20a8bU, 0xfb158592be068d2eU, 0x9ced737bb6c4183dU,
|
||||
0xc428d05aa4751e4cU, 0xf53304714d9265dfU, 0x993fe2c6d07b7fabU,
|
||||
0xbf8fdb78849a5f96U, 0xef73d256a5c0f77cU, 0x95a8637627989aadU,
|
||||
0xbb127c53b17ec159U, 0xe9d71b689dde71afU, 0x9226712162ab070dU,
|
||||
0xb6b00d69bb55c8d1U, 0xe45c10c42a2b3b05U, 0x8eb98a7a9a5b04e3U,
|
||||
0xb267ed1940f1c61cU, 0xdf01e85f912e37a3U, 0x8b61313bbabce2c6U,
|
||||
0xae397d8aa96c1b77U, 0xd9c7dced53c72255U, 0x881cea14545c7575U,
|
||||
0xaa242499697392d2U, 0xd4ad2dbfc3d07787U, 0x84ec3c97da624ab4U,
|
||||
0xa6274bbdd0fadd61U, 0xcfb11ead453994baU, 0x81ceb32c4b43fcf4U,
|
||||
0xa2425ff75e14fc31U, 0xcad2f7f5359a3b3eU, 0xfd87b5f28300ca0dU,
|
||||
0x9e74d1b791e07e48U, 0xc612062576589ddaU, 0xf79687aed3eec551U,
|
||||
0x9abe14cd44753b52U, 0xc16d9a0095928a27U, 0xf1c90080baf72cb1U,
|
||||
0x971da05074da7beeU, 0xbce5086492111aeaU, 0xec1e4a7db69561a5U,
|
||||
0x9392ee8e921d5d07U, 0xb877aa3236a4b449U, 0xe69594bec44de15bU,
|
||||
0x901d7cf73ab0acd9U, 0xb424dc35095cd80fU, 0xe12e13424bb40e13U,
|
||||
0x8cbccc096f5088cbU, 0xafebff0bcb24aafeU, 0xdbe6fecebdedd5beU,
|
||||
0x89705f4136b4a597U, 0xabcc77118461cefcU, 0xd6bf94d5e57a42bcU,
|
||||
0x8637bd05af6c69b5U, 0xa7c5ac471b478423U, 0xd1b71758e219652bU,
|
||||
0x83126e978d4fdf3bU, 0xa3d70a3d70a3d70aU, 0xccccccccccccccccU,
|
||||
0x8000000000000000U, 0xa000000000000000U, 0xc800000000000000U,
|
||||
0xfa00000000000000U, 0x9c40000000000000U, 0xc350000000000000U,
|
||||
0xf424000000000000U, 0x9896800000000000U, 0xbebc200000000000U,
|
||||
0xee6b280000000000U, 0x9502f90000000000U, 0xba43b74000000000U,
|
||||
0xe8d4a51000000000U, 0x9184e72a00000000U, 0xb5e620f480000000U,
|
||||
0xe35fa931a0000000U, 0x8e1bc9bf04000000U, 0xb1a2bc2ec5000000U,
|
||||
0xde0b6b3a76400000U, 0x8ac7230489e80000U, 0xad78ebc5ac620000U,
|
||||
0xd8d726b7177a8000U, 0x878678326eac9000U, 0xa968163f0a57b400U,
|
||||
0xd3c21bcecceda100U, 0x84595161401484a0U, 0xa56fa5b99019a5c8U,
|
||||
0xcecb8f27f4200f3aU, 0x813f3978f8940984U, 0xa18f07d736b90be5U,
|
||||
0xc9f2c9cd04674edeU, 0xfc6f7c4045812296U, 0x9dc5ada82b70b59dU,
|
||||
0xc5371912364ce305U, 0xf684df56c3e01bc6U, 0x9a130b963a6c115cU,
|
||||
0xc097ce7bc90715b3U, 0xf0bdc21abb48db20U, 0x96769950b50d88f4U,
|
||||
0xbc143fa4e250eb31U, 0xeb194f8e1ae525fdU, 0x92efd1b8d0cf37beU,
|
||||
0xb7abc627050305adU, 0xe596b7b0c643c719U, 0x8f7e32ce7bea5c6fU,
|
||||
0xb35dbf821ae4f38bU, 0xe0352f62a19e306eU, 0x8c213d9da502de45U,
|
||||
0xaf298d050e4395d6U, 0xdaf3f04651d47b4cU, 0x88d8762bf324cd0fU,
|
||||
0xab0e93b6efee0053U, 0xd5d238a4abe98068U, 0x85a36366eb71f041U,
|
||||
0xa70c3c40a64e6c51U, 0xd0cf4b50cfe20765U, 0x82818f1281ed449fU,
|
||||
0xa321f2d7226895c7U, 0xcbea6f8ceb02bb39U, 0xfee50b7025c36a08U,
|
||||
0x9f4f2726179a2245U, 0xc722f0ef9d80aad6U, 0xf8ebad2b84e0d58bU,
|
||||
0x9b934c3b330c8577U, 0xc2781f49ffcfa6d5U, 0xf316271c7fc3908aU,
|
||||
0x97edd871cfda3a56U, 0xbde94e8e43d0c8ecU, 0xed63a231d4c4fb27U,
|
||||
0x945e455f24fb1cf8U, 0xb975d6b6ee39e436U, 0xe7d34c64a9c85d44U,
|
||||
0x90e40fbeea1d3a4aU, 0xb51d13aea4a488ddU, 0xe264589a4dcdab14U,
|
||||
0x8d7eb76070a08aecU, 0xb0de65388cc8ada8U, 0xdd15fe86affad912U,
|
||||
0x8a2dbf142dfcc7abU, 0xacb92ed9397bf996U, 0xd7e77a8f87daf7fbU,
|
||||
0x86f0ac99b4e8dafdU, 0xa8acd7c0222311bcU, 0xd2d80db02aabd62bU,
|
||||
0x83c7088e1aab65dbU, 0xa4b8cab1a1563f52U, 0xcde6fd5e09abcf26U,
|
||||
0x80b05e5ac60b6178U, 0xa0dc75f1778e39d6U, 0xc913936dd571c84cU,
|
||||
0xfb5878494ace3a5fU, 0x9d174b2dcec0e47bU, 0xc45d1df942711d9aU,
|
||||
0xf5746577930d6500U, 0x9968bf6abbe85f20U, 0xbfc2ef456ae276e8U,
|
||||
0xefb3ab16c59b14a2U, 0x95d04aee3b80ece5U, 0xbb445da9ca61281fU,
|
||||
0xea1575143cf97226U, 0x924d692ca61be758U, 0xb6e0c377cfa2e12eU,
|
||||
0xe498f455c38b997aU, 0x8edf98b59a373fecU, 0xb2977ee300c50fe7U,
|
||||
0xdf3d5e9bc0f653e1U, 0x8b865b215899f46cU, 0xae67f1e9aec07187U,
|
||||
0xda01ee641a708de9U, 0x884134fe908658b2U, 0xaa51823e34a7eedeU,
|
||||
0xd4e5e2cdc1d1ea96U, 0x850fadc09923329eU, 0xa6539930bf6bff45U,
|
||||
0xcfe87f7cef46ff16U, 0x81f14fae158c5f6eU, 0xa26da3999aef7749U,
|
||||
0xcb090c8001ab551cU, 0xfdcb4fa002162a63U, 0x9e9f11c4014dda7eU,
|
||||
0xc646d63501a1511dU, 0xf7d88bc24209a565U, 0x9ae757596946075fU,
|
||||
0xc1a12d2fc3978937U, 0xf209787bb47d6b84U, 0x9745eb4d50ce6332U,
|
||||
0xbd176620a501fbffU, 0xec5d3fa8ce427affU, 0x93ba47c980e98cdfU,
|
||||
0xb8a8d9bbe123f017U, 0xe6d3102ad96cec1dU, 0x9043ea1ac7e41392U,
|
||||
0xb454e4a179dd1877U, 0xe16a1dc9d8545e94U, 0x8ce2529e2734bb1dU,
|
||||
0xb01ae745b101e9e4U, 0xdc21a1171d42645dU, 0x899504ae72497ebaU,
|
||||
0xabfa45da0edbde69U, 0xd6f8d7509292d603U, 0x865b86925b9bc5c2U,
|
||||
0xa7f26836f282b732U, 0xd1ef0244af2364ffU, 0x8335616aed761f1fU,
|
||||
0xa402b9c5a8d3a6e7U, 0xcd036837130890a1U, 0x802221226be55a64U,
|
||||
0xa02aa96b06deb0fdU, 0xc83553c5c8965d3dU, 0xfa42a8b73abbf48cU,
|
||||
0x9c69a97284b578d7U, 0xc38413cf25e2d70dU, 0xf46518c2ef5b8cd1U,
|
||||
0x98bf2f79d5993802U, 0xbeeefb584aff8603U, 0xeeaaba2e5dbf6784U,
|
||||
0x952ab45cfa97a0b2U, 0xba756174393d88dfU, 0xe912b9d1478ceb17U,
|
||||
0x91abb422ccb812eeU, 0xb616a12b7fe617aaU, 0xe39c49765fdf9d94U,
|
||||
0x8e41ade9fbebc27dU, 0xb1d219647ae6b31cU, 0xde469fbd99a05fe3U,
|
||||
0x8aec23d680043beeU, 0xada72ccc20054ae9U, 0xd910f7ff28069da4U,
|
||||
0x87aa9aff79042286U, 0xa99541bf57452b28U, 0xd3fa922f2d1675f2U,
|
||||
0x847c9b5d7c2e09b7U, 0xa59bc234db398c25U, 0xcf02b2c21207ef2eU,
|
||||
0x8161afb94b44f57dU, 0xa1ba1ba79e1632dcU, 0xca28a291859bbf93U,
|
||||
0xfcb2cb35e702af78U, 0x9defbf01b061adabU, 0xc56baec21c7a1916U,
|
||||
0xf6c69a72a3989f5bU, 0x9a3c2087a63f6399U, 0xc0cb28a98fcf3c7fU,
|
||||
0xf0fdf2d3f3c30b9fU, 0x969eb7c47859e743U, 0xbc4665b596706114U,
|
||||
0xeb57ff22fc0c7959U, 0x9316ff75dd87cbd8U, 0xb7dcbf5354e9beceU,
|
||||
0xe5d3ef282a242e81U, 0x8fa475791a569d10U, 0xb38d92d760ec4455U,
|
||||
0xe070f78d3927556aU, 0x8c469ab843b89562U, 0xaf58416654a6babbU,
|
||||
0xdb2e51bfe9d0696aU, 0x88fcf317f22241e2U, 0xab3c2fddeeaad25aU,
|
||||
0xd60b3bd56a5586f1U, 0x85c7056562757456U, 0xa738c6bebb12d16cU,
|
||||
0xd106f86e69d785c7U, 0x82a45b450226b39cU, 0xa34d721642b06084U,
|
||||
0xcc20ce9bd35c78a5U, 0xff290242c83396ceU, 0x9f79a169bd203e41U,
|
||||
0xc75809c42c684dd1U, 0xf92e0c3537826145U, 0x9bbcc7a142b17ccbU,
|
||||
0xc2abf989935ddbfeU, 0xf356f7ebf83552feU, 0x98165af37b2153deU,
|
||||
0xbe1bf1b059e9a8d6U, 0xeda2ee1c7064130cU, 0x9485d4d1c63e8be7U,
|
||||
0xb9a74a0637ce2ee1U, 0xe8111c87c5c1ba99U, 0x910ab1d4db9914a0U,
|
||||
0xb54d5e4a127f59c8U, 0xe2a0b5dc971f303aU, 0x8da471a9de737e24U,
|
||||
0xb10d8e1456105dadU, 0xdd50f1996b947518U, 0x8a5296ffe33cc92fU,
|
||||
0xace73cbfdc0bfb7bU, 0xd8210befd30efa5aU, 0x8714a775e3e95c78U,
|
||||
0xa8d9d1535ce3b396U, 0xd31045a8341ca07cU, 0x83ea2b892091e44dU,
|
||||
0xa4e4b66b68b65d60U, 0xce1de40642e3f4b9U, 0x80d2ae83e9ce78f3U,
|
||||
0xa1075a24e4421730U, 0xc94930ae1d529cfcU, 0xfb9b7cd9a4a7443cU,
|
||||
0x9d412e0806e88aa5U, 0xc491798a08a2ad4eU, 0xf5b5d7ec8acb58a2U,
|
||||
0x9991a6f3d6bf1765U, 0xbff610b0cc6edd3fU, 0xeff394dcff8a948eU,
|
||||
0x95f83d0a1fb69cd9U, 0xbb764c4ca7a4440fU, 0xea53df5fd18d5513U,
|
||||
0x92746b9be2f8552cU, 0xb7118682dbb66a77U, 0xe4d5e82392a40515U,
|
||||
0x8f05b1163ba6832dU, 0xb2c71d5bca9023f8U, 0xdf78e4b2bd342cf6U,
|
||||
0x8bab8eefb6409c1aU, 0xae9672aba3d0c320U, 0xda3c0f568cc4f3e8U,
|
||||
0x8865899617fb1871U, 0xaa7eebfb9df9de8dU, 0xd51ea6fa85785631U,
|
||||
0x8533285c936b35deU, 0xa67ff273b8460356U, 0xd01fef10a657842cU,
|
||||
0x8213f56a67f6b29bU, 0xa298f2c501f45f42U, 0xcb3f2f7642717713U,
|
||||
0xfe0efb53d30dd4d7U, 0x9ec95d1463e8a506U, 0xc67bb4597ce2ce48U,
|
||||
0xf81aa16fdc1b81daU, 0x9b10a4e5e9913128U, 0xc1d4ce1f63f57d72U,
|
||||
0xf24a01a73cf2dccfU, 0x976e41088617ca01U, 0xbd49d14aa79dbc82U,
|
||||
0xec9c459d51852ba2U, 0x93e1ab8252f33b45U, 0xb8da1662e7b00a17U,
|
||||
0xe7109bfba19c0c9dU, 0x906a617d450187e2U, 0xb484f9dc9641e9daU,
|
||||
0xe1a63853bbd26451U, 0x8d07e33455637eb2U, 0xb049dc016abc5e5fU,
|
||||
0xdc5c5301c56b75f7U, 0x89b9b3e11b6329baU, 0xac2820d9623bf429U,
|
||||
0xd732290fbacaf133U, 0x867f59a9d4bed6c0U, 0xa81f301449ee8c70U,
|
||||
0xd226fc195c6a2f8cU, 0x83585d8fd9c25db7U, 0xa42e74f3d032f525U,
|
||||
0xcd3a1230c43fb26fU, 0x80444b5e7aa7cf85U, 0xa0555e361951c366U,
|
||||
0xc86ab5c39fa63440U, 0xfa856334878fc150U, 0x9c935e00d4b9d8d2U,
|
||||
0xc3b8358109e84f07U, 0xf4a642e14c6262c8U, 0x98e7e9cccfbd7dbdU,
|
||||
0xbf21e44003acdd2cU, 0xeeea5d5004981478U, 0x95527a5202df0ccbU,
|
||||
0xbaa718e68396cffdU, 0xe950df20247c83fdU, 0x91d28b7416cdd27eU,
|
||||
0xb6472e511c81471dU, 0xe3d8f9e563a198e5U, 0x8e679c2f5e44ff8fU,
|
||||
};
|
||||
|
||||
const int16_t kPower10ExponentTable[] = {
|
||||
-1200, -1196, -1193, -1190, -1186, -1183, -1180, -1176, -1173, -1170, -1166,
|
||||
-1163, -1160, -1156, -1153, -1150, -1146, -1143, -1140, -1136, -1133, -1130,
|
||||
-1127, -1123, -1120, -1117, -1113, -1110, -1107, -1103, -1100, -1097, -1093,
|
||||
-1090, -1087, -1083, -1080, -1077, -1073, -1070, -1067, -1063, -1060, -1057,
|
||||
-1053, -1050, -1047, -1043, -1040, -1037, -1034, -1030, -1027, -1024, -1020,
|
||||
-1017, -1014, -1010, -1007, -1004, -1000, -997, -994, -990, -987, -984,
|
||||
-980, -977, -974, -970, -967, -964, -960, -957, -954, -950, -947,
|
||||
-944, -940, -937, -934, -931, -927, -924, -921, -917, -914, -911,
|
||||
-907, -904, -901, -897, -894, -891, -887, -884, -881, -877, -874,
|
||||
-871, -867, -864, -861, -857, -854, -851, -847, -844, -841, -838,
|
||||
-834, -831, -828, -824, -821, -818, -814, -811, -808, -804, -801,
|
||||
-798, -794, -791, -788, -784, -781, -778, -774, -771, -768, -764,
|
||||
-761, -758, -754, -751, -748, -744, -741, -738, -735, -731, -728,
|
||||
-725, -721, -718, -715, -711, -708, -705, -701, -698, -695, -691,
|
||||
-688, -685, -681, -678, -675, -671, -668, -665, -661, -658, -655,
|
||||
-651, -648, -645, -642, -638, -635, -632, -628, -625, -622, -618,
|
||||
-615, -612, -608, -605, -602, -598, -595, -592, -588, -585, -582,
|
||||
-578, -575, -572, -568, -565, -562, -558, -555, -552, -549, -545,
|
||||
-542, -539, -535, -532, -529, -525, -522, -519, -515, -512, -509,
|
||||
-505, -502, -499, -495, -492, -489, -485, -482, -479, -475, -472,
|
||||
-469, -465, -462, -459, -455, -452, -449, -446, -442, -439, -436,
|
||||
-432, -429, -426, -422, -419, -416, -412, -409, -406, -402, -399,
|
||||
-396, -392, -389, -386, -382, -379, -376, -372, -369, -366, -362,
|
||||
-359, -356, -353, -349, -346, -343, -339, -336, -333, -329, -326,
|
||||
-323, -319, -316, -313, -309, -306, -303, -299, -296, -293, -289,
|
||||
-286, -283, -279, -276, -273, -269, -266, -263, -259, -256, -253,
|
||||
-250, -246, -243, -240, -236, -233, -230, -226, -223, -220, -216,
|
||||
-213, -210, -206, -203, -200, -196, -193, -190, -186, -183, -180,
|
||||
-176, -173, -170, -166, -163, -160, -157, -153, -150, -147, -143,
|
||||
-140, -137, -133, -130, -127, -123, -120, -117, -113, -110, -107,
|
||||
-103, -100, -97, -93, -90, -87, -83, -80, -77, -73, -70,
|
||||
-67, -63, -60, -57, -54, -50, -47, -44, -40, -37, -34,
|
||||
-30, -27, -24, -20, -17, -14, -10, -7, -4, 0, 3,
|
||||
6, 10, 13, 16, 20, 23, 26, 30, 33, 36, 39,
|
||||
43, 46, 49, 53, 56, 59, 63, 66, 69, 73, 76,
|
||||
79, 83, 86, 89, 93, 96, 99, 103, 106, 109, 113,
|
||||
116, 119, 123, 126, 129, 132, 136, 139, 142, 146, 149,
|
||||
152, 156, 159, 162, 166, 169, 172, 176, 179, 182, 186,
|
||||
189, 192, 196, 199, 202, 206, 209, 212, 216, 219, 222,
|
||||
226, 229, 232, 235, 239, 242, 245, 249, 252, 255, 259,
|
||||
262, 265, 269, 272, 275, 279, 282, 285, 289, 292, 295,
|
||||
299, 302, 305, 309, 312, 315, 319, 322, 325, 328, 332,
|
||||
335, 338, 342, 345, 348, 352, 355, 358, 362, 365, 368,
|
||||
372, 375, 378, 382, 385, 388, 392, 395, 398, 402, 405,
|
||||
408, 412, 415, 418, 422, 425, 428, 431, 435, 438, 441,
|
||||
445, 448, 451, 455, 458, 461, 465, 468, 471, 475, 478,
|
||||
481, 485, 488, 491, 495, 498, 501, 505, 508, 511, 515,
|
||||
518, 521, 524, 528, 531, 534, 538, 541, 544, 548, 551,
|
||||
554, 558, 561, 564, 568, 571, 574, 578, 581, 584, 588,
|
||||
591, 594, 598, 601, 604, 608, 611, 614, 617, 621, 624,
|
||||
627, 631, 634, 637, 641, 644, 647, 651, 654, 657, 661,
|
||||
664, 667, 671, 674, 677, 681, 684, 687, 691, 694, 697,
|
||||
701, 704, 707, 711, 714, 717, 720, 724, 727, 730, 734,
|
||||
737, 740, 744, 747, 750, 754, 757, 760, 764, 767, 770,
|
||||
774, 777, 780, 784, 787, 790, 794, 797, 800, 804, 807,
|
||||
810, 813, 817, 820, 823, 827, 830, 833, 837, 840, 843,
|
||||
847, 850, 853, 857, 860, 863, 867, 870, 873, 877, 880,
|
||||
883, 887, 890, 893, 897, 900, 903, 907, 910, 913, 916,
|
||||
920, 923, 926, 930, 933, 936, 940, 943, 946, 950, 953,
|
||||
956, 960,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace absl
|
||||
115
third_party/abseil-cpp/absl/strings/charconv.h
vendored
115
third_party/abseil-cpp/absl/strings/charconv.h
vendored
@ -1,115 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifndef ABSL_STRINGS_CHARCONV_H_
|
||||
#define ABSL_STRINGS_CHARCONV_H_
|
||||
|
||||
#include <system_error> // NOLINT(build/c++11)
|
||||
|
||||
namespace absl {
|
||||
|
||||
// Workalike compatibilty version of std::chars_format from C++17.
|
||||
//
|
||||
// This is an bitfield enumerator which can be passed to absl::from_chars to
|
||||
// configure the std::string-to-float conversion.
|
||||
enum class chars_format {
|
||||
scientific = 1,
|
||||
fixed = 2,
|
||||
hex = 4,
|
||||
general = fixed | scientific,
|
||||
};
|
||||
|
||||
// The return result of a std::string-to-number conversion.
|
||||
//
|
||||
// `ec` will be set to `invalid_argument` if a well-formed number was not found
|
||||
// at the start of the input range, `result_out_of_range` if a well-formed
|
||||
// number was found, but it was out of the representable range of the requested
|
||||
// type, or to std::errc() otherwise.
|
||||
//
|
||||
// If a well-formed number was found, `ptr` is set to one past the sequence of
|
||||
// characters that were successfully parsed. If none was found, `ptr` is set
|
||||
// to the `first` argument to from_chars.
|
||||
struct from_chars_result {
|
||||
const char* ptr;
|
||||
std::errc ec;
|
||||
};
|
||||
|
||||
// Workalike compatibilty version of std::from_chars from C++17. Currently
|
||||
// this only supports the `double` and `float` types.
|
||||
//
|
||||
// This interface incorporates the proposed resolutions for library issues
|
||||
// DR 3800 and DR 3801. If these are adopted with different wording,
|
||||
// Abseil's behavior will change to match the standard. (The behavior most
|
||||
// likely to change is for DR 3801, which says what `value` will be set to in
|
||||
// the case of overflow and underflow. Code that wants to avoid possible
|
||||
// breaking changes in this area should not depend on `value` when the returned
|
||||
// from_chars_result indicates a range error.)
|
||||
//
|
||||
// Searches the range [first, last) for the longest matching pattern beginning
|
||||
// at `first` that represents a floating point number. If one is found, store
|
||||
// the result in `value`.
|
||||
//
|
||||
// The matching pattern format is almost the same as that of strtod(), except
|
||||
// that C locale is not respected, and an initial '+' character in the input
|
||||
// range will never be matched.
|
||||
//
|
||||
// If `fmt` is set, it must be one of the enumerator values of the chars_format.
|
||||
// (This is despite the fact that chars_format is a bitmask type.) If set to
|
||||
// `scientific`, a matching number must contain an exponent. If set to `fixed`,
|
||||
// then an exponent will never match. (For example, the std::string "1e5" will be
|
||||
// parsed as "1".) If set to `hex`, then a hexadecimal float is parsed in the
|
||||
// format that strtod() accepts, except that a "0x" prefix is NOT matched.
|
||||
// (In particular, in `hex` mode, the input "0xff" results in the largest
|
||||
// matching pattern "0".)
|
||||
absl::from_chars_result from_chars(const char* first, const char* last,
|
||||
double& value, // NOLINT
|
||||
chars_format fmt = chars_format::general);
|
||||
|
||||
absl::from_chars_result from_chars(const char* first, const char* last,
|
||||
float& value, // NOLINT
|
||||
chars_format fmt = chars_format::general);
|
||||
|
||||
// std::chars_format is specified as a bitmask type, which means the following
|
||||
// operations must be provided:
|
||||
inline constexpr chars_format operator&(chars_format lhs, chars_format rhs) {
|
||||
return static_cast<chars_format>(static_cast<int>(lhs) &
|
||||
static_cast<int>(rhs));
|
||||
}
|
||||
inline constexpr chars_format operator|(chars_format lhs, chars_format rhs) {
|
||||
return static_cast<chars_format>(static_cast<int>(lhs) |
|
||||
static_cast<int>(rhs));
|
||||
}
|
||||
inline constexpr chars_format operator^(chars_format lhs, chars_format rhs) {
|
||||
return static_cast<chars_format>(static_cast<int>(lhs) ^
|
||||
static_cast<int>(rhs));
|
||||
}
|
||||
inline constexpr chars_format operator~(chars_format arg) {
|
||||
return static_cast<chars_format>(~static_cast<int>(arg));
|
||||
}
|
||||
inline chars_format& operator&=(chars_format& lhs, chars_format rhs) {
|
||||
lhs = lhs & rhs;
|
||||
return lhs;
|
||||
}
|
||||
inline chars_format& operator|=(chars_format& lhs, chars_format rhs) {
|
||||
lhs = lhs | rhs;
|
||||
return lhs;
|
||||
}
|
||||
inline chars_format& operator^=(chars_format& lhs, chars_format rhs) {
|
||||
lhs = lhs ^ rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_STRINGS_CHARCONV_H_
|
||||
@ -1,204 +0,0 @@
|
||||
// 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/charconv.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void BM_Strtod_Pi(benchmark::State& state) {
|
||||
const char* pi = "3.14159";
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(pi);
|
||||
benchmark::DoNotOptimize(strtod(pi, nullptr));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Strtod_Pi);
|
||||
|
||||
void BM_Absl_Pi(benchmark::State& state) {
|
||||
const char* pi = "3.14159";
|
||||
const char* pi_end = pi + strlen(pi);
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(pi);
|
||||
double v;
|
||||
absl::from_chars(pi, pi_end, v);
|
||||
benchmark::DoNotOptimize(v);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Absl_Pi);
|
||||
|
||||
void BM_Strtod_Pi_float(benchmark::State& state) {
|
||||
const char* pi = "3.14159";
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(pi);
|
||||
benchmark::DoNotOptimize(strtof(pi, nullptr));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Strtod_Pi_float);
|
||||
|
||||
void BM_Absl_Pi_float(benchmark::State& state) {
|
||||
const char* pi = "3.14159";
|
||||
const char* pi_end = pi + strlen(pi);
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(pi);
|
||||
float v;
|
||||
absl::from_chars(pi, pi_end, v);
|
||||
benchmark::DoNotOptimize(v);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Absl_Pi_float);
|
||||
|
||||
void BM_Strtod_HardLarge(benchmark::State& state) {
|
||||
const char* num = "272104041512242479.e200";
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(num);
|
||||
benchmark::DoNotOptimize(strtod(num, nullptr));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Strtod_HardLarge);
|
||||
|
||||
void BM_Absl_HardLarge(benchmark::State& state) {
|
||||
const char* numstr = "272104041512242479.e200";
|
||||
const char* numstr_end = numstr + strlen(numstr);
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(numstr);
|
||||
double v;
|
||||
absl::from_chars(numstr, numstr_end, v);
|
||||
benchmark::DoNotOptimize(v);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Absl_HardLarge);
|
||||
|
||||
void BM_Strtod_HardSmall(benchmark::State& state) {
|
||||
const char* num = "94080055902682397.e-242";
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(num);
|
||||
benchmark::DoNotOptimize(strtod(num, nullptr));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Strtod_HardSmall);
|
||||
|
||||
void BM_Absl_HardSmall(benchmark::State& state) {
|
||||
const char* numstr = "94080055902682397.e-242";
|
||||
const char* numstr_end = numstr + strlen(numstr);
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(numstr);
|
||||
double v;
|
||||
absl::from_chars(numstr, numstr_end, v);
|
||||
benchmark::DoNotOptimize(v);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Absl_HardSmall);
|
||||
|
||||
void BM_Strtod_HugeMantissa(benchmark::State& state) {
|
||||
std::string huge(200, '3');
|
||||
const char* num = huge.c_str();
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(num);
|
||||
benchmark::DoNotOptimize(strtod(num, nullptr));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Strtod_HugeMantissa);
|
||||
|
||||
void BM_Absl_HugeMantissa(benchmark::State& state) {
|
||||
std::string huge(200, '3');
|
||||
const char* num = huge.c_str();
|
||||
const char* num_end = num + 200;
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(num);
|
||||
double v;
|
||||
absl::from_chars(num, num_end, v);
|
||||
benchmark::DoNotOptimize(v);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Absl_HugeMantissa);
|
||||
|
||||
std::string MakeHardCase(int length) {
|
||||
// The number 1.1521...e-297 is exactly halfway between 12345 * 2**-1000 and
|
||||
// the next larger representable number. The digits of this number are in
|
||||
// the std::string below.
|
||||
const std::string digits =
|
||||
"1."
|
||||
"152113937042223790993097181572444900347587985074226836242307364987727724"
|
||||
"831384300183638649152607195040591791364113930628852279348613864894524591"
|
||||
"272746490313676832900762939595690019745859128071117417798540258114233761"
|
||||
"012939937017879509401007964861774960297319002612457273148497158989073482"
|
||||
"171377406078223015359818300988676687994537274548940612510414856761641652"
|
||||
"513434981938564294004070500716200446656421722229202383105446378511678258"
|
||||
"370570631774499359748259931676320916632111681001853983492795053244971606"
|
||||
"922718923011680846577744433974087653954904214152517799883551075537146316"
|
||||
"168973685866425605046988661997658648354773076621610279716804960009043764"
|
||||
"038392994055171112475093876476783502487512538082706095923790634572014823"
|
||||
"78877699375152587890625" +
|
||||
std::string(5000, '0');
|
||||
// generate the hard cases on either side for the given length.
|
||||
// Lengths between 3 and 1000 are reasonable.
|
||||
return digits.substr(0, length) + "1e-297";
|
||||
}
|
||||
|
||||
void BM_Strtod_Big_And_Difficult(benchmark::State& state) {
|
||||
std::string testcase = MakeHardCase(state.range(0));
|
||||
const char* begin = testcase.c_str();
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(begin);
|
||||
benchmark::DoNotOptimize(strtod(begin, nullptr));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Strtod_Big_And_Difficult)->Range(3, 5000);
|
||||
|
||||
void BM_Absl_Big_And_Difficult(benchmark::State& state) {
|
||||
std::string testcase = MakeHardCase(state.range(0));
|
||||
const char* begin = testcase.c_str();
|
||||
const char* end = begin + testcase.size();
|
||||
for (auto s : state) {
|
||||
benchmark::DoNotOptimize(begin);
|
||||
double v;
|
||||
absl::from_chars(begin, end, v);
|
||||
benchmark::DoNotOptimize(v);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Absl_Big_And_Difficult)->Range(3, 5000);
|
||||
|
||||
} // namespace
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Benchmark Time CPU Iterations
|
||||
// ------------------------------------------------------------------------
|
||||
// BM_Strtod_Pi 96 ns 96 ns 6337454
|
||||
// BM_Absl_Pi 35 ns 35 ns 20031996
|
||||
// BM_Strtod_Pi_float 91 ns 91 ns 7745851
|
||||
// BM_Absl_Pi_float 35 ns 35 ns 20430298
|
||||
// BM_Strtod_HardLarge 133 ns 133 ns 5288341
|
||||
// BM_Absl_HardLarge 181 ns 181 ns 3855615
|
||||
// BM_Strtod_HardSmall 279 ns 279 ns 2517243
|
||||
// BM_Absl_HardSmall 287 ns 287 ns 2458744
|
||||
// BM_Strtod_HugeMantissa 433 ns 433 ns 1604293
|
||||
// BM_Absl_HugeMantissa 160 ns 160 ns 4403671
|
||||
// BM_Strtod_Big_And_Difficult/3 236 ns 236 ns 2942496
|
||||
// BM_Strtod_Big_And_Difficult/8 232 ns 232 ns 2983796
|
||||
// BM_Strtod_Big_And_Difficult/64 437 ns 437 ns 1591951
|
||||
// BM_Strtod_Big_And_Difficult/512 1738 ns 1738 ns 402519
|
||||
// BM_Strtod_Big_And_Difficult/4096 3943 ns 3943 ns 176128
|
||||
// BM_Strtod_Big_And_Difficult/5000 4397 ns 4397 ns 157878
|
||||
// BM_Absl_Big_And_Difficult/3 39 ns 39 ns 17799583
|
||||
// BM_Absl_Big_And_Difficult/8 43 ns 43 ns 16096859
|
||||
// BM_Absl_Big_And_Difficult/64 550 ns 550 ns 1259717
|
||||
// BM_Absl_Big_And_Difficult/512 4167 ns 4167 ns 171414
|
||||
// BM_Absl_Big_And_Difficult/4096 9160 ns 9159 ns 76297
|
||||
// BM_Absl_Big_And_Difficult/5000 9738 ns 9738 ns 70140
|
||||
766
third_party/abseil-cpp/absl/strings/charconv_test.cc
vendored
766
third_party/abseil-cpp/absl/strings/charconv_test.cc
vendored
@ -1,766 +0,0 @@
|
||||
// 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/charconv.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
|
||||
#ifdef _MSC_FULL_VER
|
||||
#define ABSL_COMPILER_DOES_EXACT_ROUNDING 0
|
||||
#define ABSL_STRTOD_HANDLES_NAN_CORRECTLY 0
|
||||
#else
|
||||
#define ABSL_COMPILER_DOES_EXACT_ROUNDING 1
|
||||
#define ABSL_STRTOD_HANDLES_NAN_CORRECTLY 1
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
#if ABSL_COMPILER_DOES_EXACT_ROUNDING
|
||||
|
||||
// Tests that the given std::string is accepted by absl::from_chars, and that it
|
||||
// converts exactly equal to the given number.
|
||||
void TestDoubleParse(absl::string_view str, double expected_number) {
|
||||
SCOPED_TRACE(str);
|
||||
double actual_number = 0.0;
|
||||
absl::from_chars_result result =
|
||||
absl::from_chars(str.data(), str.data() + str.length(), actual_number);
|
||||
EXPECT_EQ(result.ec, std::errc());
|
||||
EXPECT_EQ(result.ptr, str.data() + str.length());
|
||||
EXPECT_EQ(actual_number, expected_number);
|
||||
}
|
||||
|
||||
void TestFloatParse(absl::string_view str, float expected_number) {
|
||||
SCOPED_TRACE(str);
|
||||
float actual_number = 0.0;
|
||||
absl::from_chars_result result =
|
||||
absl::from_chars(str.data(), str.data() + str.length(), actual_number);
|
||||
EXPECT_EQ(result.ec, std::errc());
|
||||
EXPECT_EQ(result.ptr, str.data() + str.length());
|
||||
EXPECT_EQ(actual_number, expected_number);
|
||||
}
|
||||
|
||||
// Tests that the given double or single precision floating point literal is
|
||||
// parsed correctly by absl::from_chars.
|
||||
//
|
||||
// These convenience macros assume that the C++ compiler being used also does
|
||||
// fully correct decimal-to-binary conversions.
|
||||
#define FROM_CHARS_TEST_DOUBLE(number) \
|
||||
{ \
|
||||
TestDoubleParse(#number, number); \
|
||||
TestDoubleParse("-" #number, -number); \
|
||||
}
|
||||
|
||||
#define FROM_CHARS_TEST_FLOAT(number) \
|
||||
{ \
|
||||
TestFloatParse(#number, number##f); \
|
||||
TestFloatParse("-" #number, -number##f); \
|
||||
}
|
||||
|
||||
TEST(FromChars, NearRoundingCases) {
|
||||
// Cases from "A Program for Testing IEEE Decimal-Binary Conversion"
|
||||
// by Vern Paxson.
|
||||
|
||||
// Forms that should round towards zero. (These are the hardest cases for
|
||||
// each decimal mantissa size.)
|
||||
FROM_CHARS_TEST_DOUBLE(5.e125);
|
||||
FROM_CHARS_TEST_DOUBLE(69.e267);
|
||||
FROM_CHARS_TEST_DOUBLE(999.e-026);
|
||||
FROM_CHARS_TEST_DOUBLE(7861.e-034);
|
||||
FROM_CHARS_TEST_DOUBLE(75569.e-254);
|
||||
FROM_CHARS_TEST_DOUBLE(928609.e-261);
|
||||
FROM_CHARS_TEST_DOUBLE(9210917.e080);
|
||||
FROM_CHARS_TEST_DOUBLE(84863171.e114);
|
||||
FROM_CHARS_TEST_DOUBLE(653777767.e273);
|
||||
FROM_CHARS_TEST_DOUBLE(5232604057.e-298);
|
||||
FROM_CHARS_TEST_DOUBLE(27235667517.e-109);
|
||||
FROM_CHARS_TEST_DOUBLE(653532977297.e-123);
|
||||
FROM_CHARS_TEST_DOUBLE(3142213164987.e-294);
|
||||
FROM_CHARS_TEST_DOUBLE(46202199371337.e-072);
|
||||
FROM_CHARS_TEST_DOUBLE(231010996856685.e-073);
|
||||
FROM_CHARS_TEST_DOUBLE(9324754620109615.e212);
|
||||
FROM_CHARS_TEST_DOUBLE(78459735791271921.e049);
|
||||
FROM_CHARS_TEST_DOUBLE(272104041512242479.e200);
|
||||
FROM_CHARS_TEST_DOUBLE(6802601037806061975.e198);
|
||||
FROM_CHARS_TEST_DOUBLE(20505426358836677347.e-221);
|
||||
FROM_CHARS_TEST_DOUBLE(836168422905420598437.e-234);
|
||||
FROM_CHARS_TEST_DOUBLE(4891559871276714924261.e222);
|
||||
FROM_CHARS_TEST_FLOAT(5.e-20);
|
||||
FROM_CHARS_TEST_FLOAT(67.e14);
|
||||
FROM_CHARS_TEST_FLOAT(985.e15);
|
||||
FROM_CHARS_TEST_FLOAT(7693.e-42);
|
||||
FROM_CHARS_TEST_FLOAT(55895.e-16);
|
||||
FROM_CHARS_TEST_FLOAT(996622.e-44);
|
||||
FROM_CHARS_TEST_FLOAT(7038531.e-32);
|
||||
FROM_CHARS_TEST_FLOAT(60419369.e-46);
|
||||
FROM_CHARS_TEST_FLOAT(702990899.e-20);
|
||||
FROM_CHARS_TEST_FLOAT(6930161142.e-48);
|
||||
FROM_CHARS_TEST_FLOAT(25933168707.e-13);
|
||||
FROM_CHARS_TEST_FLOAT(596428896559.e20);
|
||||
|
||||
// Similarly, forms that should round away from zero.
|
||||
FROM_CHARS_TEST_DOUBLE(9.e-265);
|
||||
FROM_CHARS_TEST_DOUBLE(85.e-037);
|
||||
FROM_CHARS_TEST_DOUBLE(623.e100);
|
||||
FROM_CHARS_TEST_DOUBLE(3571.e263);
|
||||
FROM_CHARS_TEST_DOUBLE(81661.e153);
|
||||
FROM_CHARS_TEST_DOUBLE(920657.e-023);
|
||||
FROM_CHARS_TEST_DOUBLE(4603285.e-024);
|
||||
FROM_CHARS_TEST_DOUBLE(87575437.e-309);
|
||||
FROM_CHARS_TEST_DOUBLE(245540327.e122);
|
||||
FROM_CHARS_TEST_DOUBLE(6138508175.e120);
|
||||
FROM_CHARS_TEST_DOUBLE(83356057653.e193);
|
||||
FROM_CHARS_TEST_DOUBLE(619534293513.e124);
|
||||
FROM_CHARS_TEST_DOUBLE(2335141086879.e218);
|
||||
FROM_CHARS_TEST_DOUBLE(36167929443327.e-159);
|
||||
FROM_CHARS_TEST_DOUBLE(609610927149051.e-255);
|
||||
FROM_CHARS_TEST_DOUBLE(3743626360493413.e-165);
|
||||
FROM_CHARS_TEST_DOUBLE(94080055902682397.e-242);
|
||||
FROM_CHARS_TEST_DOUBLE(899810892172646163.e283);
|
||||
FROM_CHARS_TEST_DOUBLE(7120190517612959703.e120);
|
||||
FROM_CHARS_TEST_DOUBLE(25188282901709339043.e-252);
|
||||
FROM_CHARS_TEST_DOUBLE(308984926168550152811.e-052);
|
||||
FROM_CHARS_TEST_DOUBLE(6372891218502368041059.e064);
|
||||
FROM_CHARS_TEST_FLOAT(3.e-23);
|
||||
FROM_CHARS_TEST_FLOAT(57.e18);
|
||||
FROM_CHARS_TEST_FLOAT(789.e-35);
|
||||
FROM_CHARS_TEST_FLOAT(2539.e-18);
|
||||
FROM_CHARS_TEST_FLOAT(76173.e28);
|
||||
FROM_CHARS_TEST_FLOAT(887745.e-11);
|
||||
FROM_CHARS_TEST_FLOAT(5382571.e-37);
|
||||
FROM_CHARS_TEST_FLOAT(82381273.e-35);
|
||||
FROM_CHARS_TEST_FLOAT(750486563.e-38);
|
||||
FROM_CHARS_TEST_FLOAT(3752432815.e-39);
|
||||
FROM_CHARS_TEST_FLOAT(75224575729.e-45);
|
||||
FROM_CHARS_TEST_FLOAT(459926601011.e15);
|
||||
}
|
||||
|
||||
#undef FROM_CHARS_TEST_DOUBLE
|
||||
#undef FROM_CHARS_TEST_FLOAT
|
||||
#endif
|
||||
|
||||
float ToFloat(absl::string_view s) {
|
||||
float f;
|
||||
absl::from_chars(s.data(), s.data() + s.size(), f);
|
||||
return f;
|
||||
}
|
||||
|
||||
double ToDouble(absl::string_view s) {
|
||||
double d;
|
||||
absl::from_chars(s.data(), s.data() + s.size(), d);
|
||||
return d;
|
||||
}
|
||||
|
||||
// A duplication of the test cases in "NearRoundingCases" above, but with
|
||||
// expected values expressed with integers, using ldexp/ldexpf. These test
|
||||
// cases will work even on compilers that do not accurately round floating point
|
||||
// literals.
|
||||
TEST(FromChars, NearRoundingCasesExplicit) {
|
||||
EXPECT_EQ(ToDouble("5.e125"), ldexp(6653062250012735, 365));
|
||||
EXPECT_EQ(ToDouble("69.e267"), ldexp(4705683757438170, 841));
|
||||
EXPECT_EQ(ToDouble("999.e-026"), ldexp(6798841691080350, -129));
|
||||
EXPECT_EQ(ToDouble("7861.e-034"), ldexp(8975675289889240, -153));
|
||||
EXPECT_EQ(ToDouble("75569.e-254"), ldexp(6091718967192243, -880));
|
||||
EXPECT_EQ(ToDouble("928609.e-261"), ldexp(7849264900213743, -900));
|
||||
EXPECT_EQ(ToDouble("9210917.e080"), ldexp(8341110837370930, 236));
|
||||
EXPECT_EQ(ToDouble("84863171.e114"), ldexp(4625202867375927, 353));
|
||||
EXPECT_EQ(ToDouble("653777767.e273"), ldexp(5068902999763073, 884));
|
||||
EXPECT_EQ(ToDouble("5232604057.e-298"), ldexp(5741343011915040, -1010));
|
||||
EXPECT_EQ(ToDouble("27235667517.e-109"), ldexp(6707124626673586, -380));
|
||||
EXPECT_EQ(ToDouble("653532977297.e-123"), ldexp(7078246407265384, -422));
|
||||
EXPECT_EQ(ToDouble("3142213164987.e-294"), ldexp(8219991337640559, -988));
|
||||
EXPECT_EQ(ToDouble("46202199371337.e-072"), ldexp(5224462102115359, -246));
|
||||
EXPECT_EQ(ToDouble("231010996856685.e-073"), ldexp(5224462102115359, -247));
|
||||
EXPECT_EQ(ToDouble("9324754620109615.e212"), ldexp(5539753864394442, 705));
|
||||
EXPECT_EQ(ToDouble("78459735791271921.e049"), ldexp(8388176519442766, 166));
|
||||
EXPECT_EQ(ToDouble("272104041512242479.e200"), ldexp(5554409530847367, 670));
|
||||
EXPECT_EQ(ToDouble("6802601037806061975.e198"), ldexp(5554409530847367, 668));
|
||||
EXPECT_EQ(ToDouble("20505426358836677347.e-221"),
|
||||
ldexp(4524032052079546, -722));
|
||||
EXPECT_EQ(ToDouble("836168422905420598437.e-234"),
|
||||
ldexp(5070963299887562, -760));
|
||||
EXPECT_EQ(ToDouble("4891559871276714924261.e222"),
|
||||
ldexp(6452687840519111, 757));
|
||||
EXPECT_EQ(ToFloat("5.e-20"), ldexpf(15474250, -88));
|
||||
EXPECT_EQ(ToFloat("67.e14"), ldexpf(12479722, 29));
|
||||
EXPECT_EQ(ToFloat("985.e15"), ldexpf(14333636, 36));
|
||||
EXPECT_EQ(ToFloat("7693.e-42"), ldexpf(10979816, -150));
|
||||
EXPECT_EQ(ToFloat("55895.e-16"), ldexpf(12888509, -61));
|
||||
EXPECT_EQ(ToFloat("996622.e-44"), ldexpf(14224264, -150));
|
||||
EXPECT_EQ(ToFloat("7038531.e-32"), ldexpf(11420669, -107));
|
||||
EXPECT_EQ(ToFloat("60419369.e-46"), ldexpf(8623340, -150));
|
||||
EXPECT_EQ(ToFloat("702990899.e-20"), ldexpf(16209866, -61));
|
||||
EXPECT_EQ(ToFloat("6930161142.e-48"), ldexpf(9891056, -150));
|
||||
EXPECT_EQ(ToFloat("25933168707.e-13"), ldexpf(11138211, -32));
|
||||
EXPECT_EQ(ToFloat("596428896559.e20"), ldexpf(12333860, 82));
|
||||
|
||||
|
||||
EXPECT_EQ(ToDouble("9.e-265"), ldexp(8168427841980010, -930));
|
||||
EXPECT_EQ(ToDouble("85.e-037"), ldexp(6360455125664090, -169));
|
||||
EXPECT_EQ(ToDouble("623.e100"), ldexp(6263531988747231, 289));
|
||||
EXPECT_EQ(ToDouble("3571.e263"), ldexp(6234526311072170, 833));
|
||||
EXPECT_EQ(ToDouble("81661.e153"), ldexp(6696636728760206, 472));
|
||||
EXPECT_EQ(ToDouble("920657.e-023"), ldexp(5975405561110124, -109));
|
||||
EXPECT_EQ(ToDouble("4603285.e-024"), ldexp(5975405561110124, -110));
|
||||
EXPECT_EQ(ToDouble("87575437.e-309"), ldexp(8452160731874668, -1053));
|
||||
EXPECT_EQ(ToDouble("245540327.e122"), ldexp(4985336549131723, 381));
|
||||
EXPECT_EQ(ToDouble("6138508175.e120"), ldexp(4985336549131723, 379));
|
||||
EXPECT_EQ(ToDouble("83356057653.e193"), ldexp(5986732817132056, 625));
|
||||
EXPECT_EQ(ToDouble("619534293513.e124"), ldexp(4798406992060657, 399));
|
||||
EXPECT_EQ(ToDouble("2335141086879.e218"), ldexp(5419088166961646, 713));
|
||||
EXPECT_EQ(ToDouble("36167929443327.e-159"), ldexp(8135819834632444, -536));
|
||||
EXPECT_EQ(ToDouble("609610927149051.e-255"), ldexp(4576664294594737, -850));
|
||||
EXPECT_EQ(ToDouble("3743626360493413.e-165"), ldexp(6898586531774201, -549));
|
||||
EXPECT_EQ(ToDouble("94080055902682397.e-242"), ldexp(6273271706052298, -800));
|
||||
EXPECT_EQ(ToDouble("899810892172646163.e283"), ldexp(7563892574477827, 947));
|
||||
EXPECT_EQ(ToDouble("7120190517612959703.e120"), ldexp(5385467232557565, 409));
|
||||
EXPECT_EQ(ToDouble("25188282901709339043.e-252"),
|
||||
ldexp(5635662608542340, -825));
|
||||
EXPECT_EQ(ToDouble("308984926168550152811.e-052"),
|
||||
ldexp(5644774693823803, -157));
|
||||
EXPECT_EQ(ToDouble("6372891218502368041059.e064"),
|
||||
ldexp(4616868614322430, 233));
|
||||
|
||||
EXPECT_EQ(ToFloat("3.e-23"), ldexpf(9507380, -98));
|
||||
EXPECT_EQ(ToFloat("57.e18"), ldexpf(12960300, 42));
|
||||
EXPECT_EQ(ToFloat("789.e-35"), ldexpf(10739312, -130));
|
||||
EXPECT_EQ(ToFloat("2539.e-18"), ldexpf(11990089, -72));
|
||||
EXPECT_EQ(ToFloat("76173.e28"), ldexpf(9845130, 86));
|
||||
EXPECT_EQ(ToFloat("887745.e-11"), ldexpf(9760860, -40));
|
||||
EXPECT_EQ(ToFloat("5382571.e-37"), ldexpf(11447463, -124));
|
||||
EXPECT_EQ(ToFloat("82381273.e-35"), ldexpf(8554961, -113));
|
||||
EXPECT_EQ(ToFloat("750486563.e-38"), ldexpf(9975678, -120));
|
||||
EXPECT_EQ(ToFloat("3752432815.e-39"), ldexpf(9975678, -121));
|
||||
EXPECT_EQ(ToFloat("75224575729.e-45"), ldexpf(13105970, -137));
|
||||
EXPECT_EQ(ToFloat("459926601011.e15"), ldexpf(12466336, 65));
|
||||
}
|
||||
|
||||
// Common test logic for converting a std::string which lies exactly halfway between
|
||||
// two target floats.
|
||||
//
|
||||
// mantissa and exponent represent the precise value between two floating point
|
||||
// numbers, `expected_low` and `expected_high`. The floating point
|
||||
// representation to parse in `StrCat(mantissa, "e", exponent)`.
|
||||
//
|
||||
// This function checks that an input just slightly less than the exact value
|
||||
// is rounded down to `expected_low`, and an input just slightly greater than
|
||||
// the exact value is rounded up to `expected_high`.
|
||||
//
|
||||
// The exact value should round to `expected_half`, which must be either
|
||||
// `expected_low` or `expected_high`.
|
||||
template <typename FloatType>
|
||||
void TestHalfwayValue(const std::string& mantissa, int exponent,
|
||||
FloatType expected_low, FloatType expected_high,
|
||||
FloatType expected_half) {
|
||||
std::string low_rep = mantissa;
|
||||
low_rep[low_rep.size() - 1] -= 1;
|
||||
absl::StrAppend(&low_rep, std::string(1000, '9'), "e", exponent);
|
||||
|
||||
FloatType actual_low = 0;
|
||||
absl::from_chars(low_rep.data(), low_rep.data() + low_rep.size(), actual_low);
|
||||
EXPECT_EQ(expected_low, actual_low);
|
||||
|
||||
std::string high_rep = absl::StrCat(mantissa, std::string(1000, '0'), "1e", exponent);
|
||||
FloatType actual_high = 0;
|
||||
absl::from_chars(high_rep.data(), high_rep.data() + high_rep.size(),
|
||||
actual_high);
|
||||
EXPECT_EQ(expected_high, actual_high);
|
||||
|
||||
std::string halfway_rep = absl::StrCat(mantissa, "e", exponent);
|
||||
FloatType actual_half = 0;
|
||||
absl::from_chars(halfway_rep.data(), halfway_rep.data() + halfway_rep.size(),
|
||||
actual_half);
|
||||
EXPECT_EQ(expected_half, actual_half);
|
||||
}
|
||||
|
||||
TEST(FromChars, DoubleRounding) {
|
||||
const double zero = 0.0;
|
||||
const double first_subnormal = nextafter(zero, 1.0);
|
||||
const double second_subnormal = nextafter(first_subnormal, 1.0);
|
||||
|
||||
const double first_normal = DBL_MIN;
|
||||
const double last_subnormal = nextafter(first_normal, 0.0);
|
||||
const double second_normal = nextafter(first_normal, 1.0);
|
||||
|
||||
const double last_normal = DBL_MAX;
|
||||
const double penultimate_normal = nextafter(last_normal, 0.0);
|
||||
|
||||
// Various test cases for numbers between two representable floats. Each
|
||||
// call to TestHalfwayValue tests a number just below and just above the
|
||||
// halfway point, as well as the number exactly between them.
|
||||
|
||||
// Test between zero and first_subnormal. Round-to-even tie rounds down.
|
||||
TestHalfwayValue(
|
||||
"2."
|
||||
"470328229206232720882843964341106861825299013071623822127928412503377536"
|
||||
"351043759326499181808179961898982823477228588654633283551779698981993873"
|
||||
"980053909390631503565951557022639229085839244910518443593180284993653615"
|
||||
"250031937045767824921936562366986365848075700158576926990370631192827955"
|
||||
"855133292783433840935197801553124659726357957462276646527282722005637400"
|
||||
"648549997709659947045402082816622623785739345073633900796776193057750674"
|
||||
"017632467360096895134053553745851666113422376667860416215968046191446729"
|
||||
"184030053005753084904876539171138659164623952491262365388187963623937328"
|
||||
"042389101867234849766823508986338858792562830275599565752445550725518931"
|
||||
"369083625477918694866799496832404970582102851318545139621383772282614543"
|
||||
"7693412532098591327667236328125",
|
||||
-324, zero, first_subnormal, zero);
|
||||
|
||||
// first_subnormal and second_subnormal. Round-to-even tie rounds up.
|
||||
TestHalfwayValue(
|
||||
"7."
|
||||
"410984687618698162648531893023320585475897039214871466383785237510132609"
|
||||
"053131277979497545424539885696948470431685765963899850655339096945981621"
|
||||
"940161728171894510697854671067917687257517734731555330779540854980960845"
|
||||
"750095811137303474765809687100959097544227100475730780971111893578483867"
|
||||
"565399878350301522805593404659373979179073872386829939581848166016912201"
|
||||
"945649993128979841136206248449867871357218035220901702390328579173252022"
|
||||
"052897402080290685402160661237554998340267130003581248647904138574340187"
|
||||
"552090159017259254714629617513415977493871857473787096164563890871811984"
|
||||
"127167305601704549300470526959016576377688490826798697257336652176556794"
|
||||
"107250876433756084600398490497214911746308553955635418864151316847843631"
|
||||
"3080237596295773983001708984375",
|
||||
-324, first_subnormal, second_subnormal, second_subnormal);
|
||||
|
||||
// last_subnormal and first_normal. Round-to-even tie rounds up.
|
||||
TestHalfwayValue(
|
||||
"2."
|
||||
"225073858507201136057409796709131975934819546351645648023426109724822222"
|
||||
"021076945516529523908135087914149158913039621106870086438694594645527657"
|
||||
"207407820621743379988141063267329253552286881372149012981122451451889849"
|
||||
"057222307285255133155755015914397476397983411801999323962548289017107081"
|
||||
"850690630666655994938275772572015763062690663332647565300009245888316433"
|
||||
"037779791869612049497390377829704905051080609940730262937128958950003583"
|
||||
"799967207254304360284078895771796150945516748243471030702609144621572289"
|
||||
"880258182545180325707018860872113128079512233426288368622321503775666622"
|
||||
"503982534335974568884423900265498198385487948292206894721689831099698365"
|
||||
"846814022854243330660339850886445804001034933970427567186443383770486037"
|
||||
"86162277173854562306587467901408672332763671875",
|
||||
-308, last_subnormal, first_normal, first_normal);
|
||||
|
||||
// first_normal and second_normal. Round-to-even tie rounds down.
|
||||
TestHalfwayValue(
|
||||
"2."
|
||||
"225073858507201630123055637955676152503612414573018013083228724049586647"
|
||||
"606759446192036794116886953213985520549032000903434781884412325572184367"
|
||||
"563347617020518175998922941393629966742598285899994830148971433555578567"
|
||||
"693279306015978183162142425067962460785295885199272493577688320732492479"
|
||||
"924816869232247165964934329258783950102250973957579510571600738343645738"
|
||||
"494324192997092179207389919761694314131497173265255020084997973676783743"
|
||||
"155205818804439163810572367791175177756227497413804253387084478193655533"
|
||||
"073867420834526162513029462022730109054820067654020201547112002028139700"
|
||||
"141575259123440177362244273712468151750189745559978653234255886219611516"
|
||||
"335924167958029604477064946470184777360934300451421683607013647479513962"
|
||||
"13837722826145437693412532098591327667236328125",
|
||||
-308, first_normal, second_normal, first_normal);
|
||||
|
||||
// penultimate_normal and last_normal. Round-to-even rounds down.
|
||||
TestHalfwayValue(
|
||||
"1."
|
||||
"797693134862315608353258760581052985162070023416521662616611746258695532"
|
||||
"672923265745300992879465492467506314903358770175220871059269879629062776"
|
||||
"047355692132901909191523941804762171253349609463563872612866401980290377"
|
||||
"995141836029815117562837277714038305214839639239356331336428021390916694"
|
||||
"57927874464075218944",
|
||||
308, penultimate_normal, last_normal, penultimate_normal);
|
||||
}
|
||||
|
||||
// Same test cases as DoubleRounding, now with new and improved Much Smaller
|
||||
// Precision!
|
||||
TEST(FromChars, FloatRounding) {
|
||||
const float zero = 0.0;
|
||||
const float first_subnormal = nextafterf(zero, 1.0);
|
||||
const float second_subnormal = nextafterf(first_subnormal, 1.0);
|
||||
|
||||
const float first_normal = FLT_MIN;
|
||||
const float last_subnormal = nextafterf(first_normal, 0.0);
|
||||
const float second_normal = nextafterf(first_normal, 1.0);
|
||||
|
||||
const float last_normal = FLT_MAX;
|
||||
const float penultimate_normal = nextafterf(last_normal, 0.0);
|
||||
|
||||
// Test between zero and first_subnormal. Round-to-even tie rounds down.
|
||||
TestHalfwayValue(
|
||||
"7."
|
||||
"006492321624085354618647916449580656401309709382578858785341419448955413"
|
||||
"42930300743319094181060791015625",
|
||||
-46, zero, first_subnormal, zero);
|
||||
|
||||
// first_subnormal and second_subnormal. Round-to-even tie rounds up.
|
||||
TestHalfwayValue(
|
||||
"2."
|
||||
"101947696487225606385594374934874196920392912814773657635602425834686624"
|
||||
"028790902229957282543182373046875",
|
||||
-45, first_subnormal, second_subnormal, second_subnormal);
|
||||
|
||||
// last_subnormal and first_normal. Round-to-even tie rounds up.
|
||||
TestHalfwayValue(
|
||||
"1."
|
||||
"175494280757364291727882991035766513322858992758990427682963118425003064"
|
||||
"9651730385585324256680905818939208984375",
|
||||
-38, last_subnormal, first_normal, first_normal);
|
||||
|
||||
// first_normal and second_normal. Round-to-even tie rounds down.
|
||||
TestHalfwayValue(
|
||||
"1."
|
||||
"175494420887210724209590083408724842314472120785184615334540294131831453"
|
||||
"9442813071445925743319094181060791015625",
|
||||
-38, first_normal, second_normal, first_normal);
|
||||
|
||||
// penultimate_normal and last_normal. Round-to-even rounds down.
|
||||
TestHalfwayValue("3.40282336497324057985868971510891282432", 38,
|
||||
penultimate_normal, last_normal, penultimate_normal);
|
||||
}
|
||||
|
||||
TEST(FromChars, Underflow) {
|
||||
// Check that underflow is handled correctly, according to the specification
|
||||
// in DR 3081.
|
||||
double d;
|
||||
float f;
|
||||
absl::from_chars_result result;
|
||||
|
||||
std::string negative_underflow = "-1e-1000";
|
||||
const char* begin = negative_underflow.data();
|
||||
const char* end = begin + negative_underflow.size();
|
||||
d = 100.0;
|
||||
result = absl::from_chars(begin, end, d);
|
||||
EXPECT_EQ(result.ptr, end);
|
||||
EXPECT_EQ(result.ec, std::errc::result_out_of_range);
|
||||
EXPECT_TRUE(std::signbit(d)); // negative
|
||||
EXPECT_GE(d, -std::numeric_limits<double>::min());
|
||||
f = 100.0;
|
||||
result = absl::from_chars(begin, end, f);
|
||||
EXPECT_EQ(result.ptr, end);
|
||||
EXPECT_EQ(result.ec, std::errc::result_out_of_range);
|
||||
EXPECT_TRUE(std::signbit(f)); // negative
|
||||
EXPECT_GE(f, -std::numeric_limits<float>::min());
|
||||
|
||||
std::string positive_underflow = "1e-1000";
|
||||
begin = positive_underflow.data();
|
||||
end = begin + positive_underflow.size();
|
||||
d = -100.0;
|
||||
result = absl::from_chars(begin, end, d);
|
||||
EXPECT_EQ(result.ptr, end);
|
||||
EXPECT_EQ(result.ec, std::errc::result_out_of_range);
|
||||
EXPECT_FALSE(std::signbit(d)); // positive
|
||||
EXPECT_LE(d, std::numeric_limits<double>::min());
|
||||
f = -100.0;
|
||||
result = absl::from_chars(begin, end, f);
|
||||
EXPECT_EQ(result.ptr, end);
|
||||
EXPECT_EQ(result.ec, std::errc::result_out_of_range);
|
||||
EXPECT_FALSE(std::signbit(f)); // positive
|
||||
EXPECT_LE(f, std::numeric_limits<float>::min());
|
||||
}
|
||||
|
||||
TEST(FromChars, Overflow) {
|
||||
// Check that overflow is handled correctly, according to the specification
|
||||
// in DR 3081.
|
||||
double d;
|
||||
float f;
|
||||
absl::from_chars_result result;
|
||||
|
||||
std::string negative_overflow = "-1e1000";
|
||||
const char* begin = negative_overflow.data();
|
||||
const char* end = begin + negative_overflow.size();
|
||||
d = 100.0;
|
||||
result = absl::from_chars(begin, end, d);
|
||||
EXPECT_EQ(result.ptr, end);
|
||||
EXPECT_EQ(result.ec, std::errc::result_out_of_range);
|
||||
EXPECT_TRUE(std::signbit(d)); // negative
|
||||
EXPECT_EQ(d, -std::numeric_limits<double>::max());
|
||||
f = 100.0;
|
||||
result = absl::from_chars(begin, end, f);
|
||||
EXPECT_EQ(result.ptr, end);
|
||||
EXPECT_EQ(result.ec, std::errc::result_out_of_range);
|
||||
EXPECT_TRUE(std::signbit(f)); // negative
|
||||
EXPECT_EQ(f, -std::numeric_limits<float>::max());
|
||||
|
||||
std::string positive_overflow = "1e1000";
|
||||
begin = positive_overflow.data();
|
||||
end = begin + positive_overflow.size();
|
||||
d = -100.0;
|
||||
result = absl::from_chars(begin, end, d);
|
||||
EXPECT_EQ(result.ptr, end);
|
||||
EXPECT_EQ(result.ec, std::errc::result_out_of_range);
|
||||
EXPECT_FALSE(std::signbit(d)); // positive
|
||||
EXPECT_EQ(d, std::numeric_limits<double>::max());
|
||||
f = -100.0;
|
||||
result = absl::from_chars(begin, end, f);
|
||||
EXPECT_EQ(result.ptr, end);
|
||||
EXPECT_EQ(result.ec, std::errc::result_out_of_range);
|
||||
EXPECT_FALSE(std::signbit(f)); // positive
|
||||
EXPECT_EQ(f, std::numeric_limits<float>::max());
|
||||
}
|
||||
|
||||
TEST(FromChars, ReturnValuePtr) {
|
||||
// Check that `ptr` points one past the number scanned, even if that number
|
||||
// is not representable.
|
||||
double d;
|
||||
absl::from_chars_result result;
|
||||
|
||||
std::string normal = "3.14@#$%@#$%";
|
||||
result = absl::from_chars(normal.data(), normal.data() + normal.size(), d);
|
||||
EXPECT_EQ(result.ec, std::errc());
|
||||
EXPECT_EQ(result.ptr - normal.data(), 4);
|
||||
|
||||
std::string overflow = "1e1000@#$%@#$%";
|
||||
result = absl::from_chars(overflow.data(),
|
||||
overflow.data() + overflow.size(), d);
|
||||
EXPECT_EQ(result.ec, std::errc::result_out_of_range);
|
||||
EXPECT_EQ(result.ptr - overflow.data(), 6);
|
||||
|
||||
std::string garbage = "#$%@#$%";
|
||||
result = absl::from_chars(garbage.data(),
|
||||
garbage.data() + garbage.size(), d);
|
||||
EXPECT_EQ(result.ec, std::errc::invalid_argument);
|
||||
EXPECT_EQ(result.ptr - garbage.data(), 0);
|
||||
}
|
||||
|
||||
// Check for a wide range of inputs that strtod() and absl::from_chars() exactly
|
||||
// agree on the conversion amount.
|
||||
//
|
||||
// This test assumes the platform's strtod() uses perfect round_to_nearest
|
||||
// rounding.
|
||||
TEST(FromChars, TestVersusStrtod) {
|
||||
for (int mantissa = 1000000; mantissa <= 9999999; mantissa += 501) {
|
||||
for (int exponent = -300; exponent < 300; ++exponent) {
|
||||
std::string candidate = absl::StrCat(mantissa, "e", exponent);
|
||||
double strtod_value = strtod(candidate.c_str(), nullptr);
|
||||
double absl_value = 0;
|
||||
absl::from_chars(candidate.data(), candidate.data() + candidate.size(),
|
||||
absl_value);
|
||||
ASSERT_EQ(strtod_value, absl_value) << candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a wide range of inputs that strtof() and absl::from_chars() exactly
|
||||
// agree on the conversion amount.
|
||||
//
|
||||
// This test assumes the platform's strtof() uses perfect round_to_nearest
|
||||
// rounding.
|
||||
TEST(FromChars, TestVersusStrtof) {
|
||||
for (int mantissa = 1000000; mantissa <= 9999999; mantissa += 501) {
|
||||
for (int exponent = -43; exponent < 32; ++exponent) {
|
||||
std::string candidate = absl::StrCat(mantissa, "e", exponent);
|
||||
float strtod_value = strtof(candidate.c_str(), nullptr);
|
||||
float absl_value = 0;
|
||||
absl::from_chars(candidate.data(), candidate.data() + candidate.size(),
|
||||
absl_value);
|
||||
ASSERT_EQ(strtod_value, absl_value) << candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests if two floating point values have identical bit layouts. (EXPECT_EQ
|
||||
// is not suitable for NaN testing, since NaNs are never equal.)
|
||||
template <typename Float>
|
||||
bool Identical(Float a, Float b) {
|
||||
return 0 == memcmp(&a, &b, sizeof(Float));
|
||||
}
|
||||
|
||||
// Check that NaNs are parsed correctly. The spec requires that
|
||||
// std::from_chars on "NaN(123abc)" return the same value as std::nan("123abc").
|
||||
// How such an n-char-sequence affects the generated NaN is unspecified, so we
|
||||
// just test for symmetry with std::nan and strtod here.
|
||||
//
|
||||
// (In Linux, this parses the value as a number and stuffs that number into the
|
||||
// free bits of a quiet NaN.)
|
||||
TEST(FromChars, NaNDoubles) {
|
||||
for (std::string n_char_sequence :
|
||||
{"", "1", "2", "3", "fff", "FFF", "200000", "400000", "4000000000000",
|
||||
"8000000000000", "abc123", "legal_but_unexpected",
|
||||
"99999999999999999999999", "_"}) {
|
||||
std::string input = absl::StrCat("nan(", n_char_sequence, ")");
|
||||
SCOPED_TRACE(input);
|
||||
double from_chars_double;
|
||||
absl::from_chars(input.data(), input.data() + input.size(),
|
||||
from_chars_double);
|
||||
double std_nan_double = std::nan(n_char_sequence.c_str());
|
||||
EXPECT_TRUE(Identical(from_chars_double, std_nan_double));
|
||||
|
||||
// Also check that we match strtod()'s behavior. This test assumes that the
|
||||
// platform has a compliant strtod().
|
||||
#if ABSL_STRTOD_HANDLES_NAN_CORRECTLY
|
||||
double strtod_double = strtod(input.c_str(), nullptr);
|
||||
EXPECT_TRUE(Identical(from_chars_double, strtod_double));
|
||||
#endif // ABSL_STRTOD_HANDLES_NAN_CORRECTLY
|
||||
|
||||
// Check that we can parse a negative NaN
|
||||
std::string negative_input = "-" + input;
|
||||
double negative_from_chars_double;
|
||||
absl::from_chars(negative_input.data(),
|
||||
negative_input.data() + negative_input.size(),
|
||||
negative_from_chars_double);
|
||||
EXPECT_TRUE(std::signbit(negative_from_chars_double));
|
||||
EXPECT_FALSE(Identical(negative_from_chars_double, from_chars_double));
|
||||
from_chars_double = std::copysign(from_chars_double, -1.0);
|
||||
EXPECT_TRUE(Identical(negative_from_chars_double, from_chars_double));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FromChars, NaNFloats) {
|
||||
for (std::string n_char_sequence :
|
||||
{"", "1", "2", "3", "fff", "FFF", "200000", "400000", "4000000000000",
|
||||
"8000000000000", "abc123", "legal_but_unexpected",
|
||||
"99999999999999999999999", "_"}) {
|
||||
std::string input = absl::StrCat("nan(", n_char_sequence, ")");
|
||||
SCOPED_TRACE(input);
|
||||
float from_chars_float;
|
||||
absl::from_chars(input.data(), input.data() + input.size(),
|
||||
from_chars_float);
|
||||
float std_nan_float = std::nanf(n_char_sequence.c_str());
|
||||
EXPECT_TRUE(Identical(from_chars_float, std_nan_float));
|
||||
|
||||
// Also check that we match strtof()'s behavior. This test assumes that the
|
||||
// platform has a compliant strtof().
|
||||
#if ABSL_STRTOD_HANDLES_NAN_CORRECTLY
|
||||
float strtof_float = strtof(input.c_str(), nullptr);
|
||||
EXPECT_TRUE(Identical(from_chars_float, strtof_float));
|
||||
#endif // ABSL_STRTOD_HANDLES_NAN_CORRECTLY
|
||||
|
||||
// Check that we can parse a negative NaN
|
||||
std::string negative_input = "-" + input;
|
||||
float negative_from_chars_float;
|
||||
absl::from_chars(negative_input.data(),
|
||||
negative_input.data() + negative_input.size(),
|
||||
negative_from_chars_float);
|
||||
EXPECT_TRUE(std::signbit(negative_from_chars_float));
|
||||
EXPECT_FALSE(Identical(negative_from_chars_float, from_chars_float));
|
||||
from_chars_float = std::copysign(from_chars_float, -1.0);
|
||||
EXPECT_TRUE(Identical(negative_from_chars_float, from_chars_float));
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an integer larger than step. The values grow exponentially.
|
||||
int NextStep(int step) {
|
||||
return step + (step >> 2) + 1;
|
||||
}
|
||||
|
||||
// Test a conversion on a family of input strings, checking that the calculation
|
||||
// is correct for in-bounds values, and that overflow and underflow are done
|
||||
// correctly for out-of-bounds values.
|
||||
//
|
||||
// input_generator maps from an integer index to a std::string to test.
|
||||
// expected_generator maps from an integer index to an expected Float value.
|
||||
// from_chars conversion of input_generator(i) should result in
|
||||
// expected_generator(i).
|
||||
//
|
||||
// lower_bound and upper_bound denote the smallest and largest values for which
|
||||
// the conversion is expected to succeed.
|
||||
template <typename Float>
|
||||
void TestOverflowAndUnderflow(
|
||||
const std::function<std::string(int)>& input_generator,
|
||||
const std::function<Float(int)>& expected_generator, int lower_bound,
|
||||
int upper_bound) {
|
||||
// test legal values near lower_bound
|
||||
int index, step;
|
||||
for (index = lower_bound, step = 1; index < upper_bound;
|
||||
index += step, step = NextStep(step)) {
|
||||
std::string input = input_generator(index);
|
||||
SCOPED_TRACE(input);
|
||||
Float expected = expected_generator(index);
|
||||
Float actual;
|
||||
auto result =
|
||||
absl::from_chars(input.data(), input.data() + input.size(), actual);
|
||||
EXPECT_EQ(result.ec, std::errc());
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
// test legal values near upper_bound
|
||||
for (index = upper_bound, step = 1; index > lower_bound;
|
||||
index -= step, step = NextStep(step)) {
|
||||
std::string input = input_generator(index);
|
||||
SCOPED_TRACE(input);
|
||||
Float expected = expected_generator(index);
|
||||
Float actual;
|
||||
auto result =
|
||||
absl::from_chars(input.data(), input.data() + input.size(), actual);
|
||||
EXPECT_EQ(result.ec, std::errc());
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
// Test underflow values below lower_bound
|
||||
for (index = lower_bound - 1, step = 1; index > -1000000;
|
||||
index -= step, step = NextStep(step)) {
|
||||
std::string input = input_generator(index);
|
||||
SCOPED_TRACE(input);
|
||||
Float actual;
|
||||
auto result =
|
||||
absl::from_chars(input.data(), input.data() + input.size(), actual);
|
||||
EXPECT_EQ(result.ec, std::errc::result_out_of_range);
|
||||
EXPECT_LT(actual, 1.0); // check for underflow
|
||||
}
|
||||
// Test overflow values above upper_bound
|
||||
for (index = upper_bound + 1, step = 1; index < 1000000;
|
||||
index += step, step = NextStep(step)) {
|
||||
std::string input = input_generator(index);
|
||||
SCOPED_TRACE(input);
|
||||
Float actual;
|
||||
auto result =
|
||||
absl::from_chars(input.data(), input.data() + input.size(), actual);
|
||||
EXPECT_EQ(result.ec, std::errc::result_out_of_range);
|
||||
EXPECT_GT(actual, 1.0); // check for overflow
|
||||
}
|
||||
}
|
||||
|
||||
// Check that overflow and underflow are caught correctly for hex doubles.
|
||||
//
|
||||
// The largest representable double is 0x1.fffffffffffffp+1023, and the
|
||||
// smallest representable subnormal is 0x0.0000000000001p-1022, which equals
|
||||
// 0x1p-1074. Therefore 1023 and -1074 are the limits of acceptable exponents
|
||||
// in this test.
|
||||
TEST(FromChars, HexdecimalDoubleLimits) {
|
||||
auto input_gen = [](int index) { return absl::StrCat("0x1.0p", index); };
|
||||
auto expected_gen = [](int index) { return std::ldexp(1.0, index); };
|
||||
TestOverflowAndUnderflow<double>(input_gen, expected_gen, -1074, 1023);
|
||||
}
|
||||
|
||||
// Check that overflow and underflow are caught correctly for hex floats.
|
||||
//
|
||||
// The largest representable float is 0x1.fffffep+127, and the smallest
|
||||
// representable subnormal is 0x0.000002p-126, which equals 0x1p-149.
|
||||
// Therefore 127 and -149 are the limits of acceptable exponents in this test.
|
||||
TEST(FromChars, HexdecimalFloatLimits) {
|
||||
auto input_gen = [](int index) { return absl::StrCat("0x1.0p", index); };
|
||||
auto expected_gen = [](int index) { return std::ldexp(1.0f, index); };
|
||||
TestOverflowAndUnderflow<float>(input_gen, expected_gen, -149, 127);
|
||||
}
|
||||
|
||||
// Check that overflow and underflow are caught correctly for decimal doubles.
|
||||
//
|
||||
// The largest representable double is about 1.8e308, and the smallest
|
||||
// representable subnormal is about 5e-324. '1e-324' therefore rounds away from
|
||||
// the smallest representable positive value. -323 and 308 are the limits of
|
||||
// acceptable exponents in this test.
|
||||
TEST(FromChars, DecimalDoubleLimits) {
|
||||
auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
|
||||
auto expected_gen = [](int index) { return std::pow(10.0, index); };
|
||||
TestOverflowAndUnderflow<double>(input_gen, expected_gen, -323, 308);
|
||||
}
|
||||
|
||||
// Check that overflow and underflow are caught correctly for decimal floats.
|
||||
//
|
||||
// The largest representable float is about 3.4e38, and the smallest
|
||||
// representable subnormal is about 1.45e-45. '1e-45' therefore rounds towards
|
||||
// the smallest representable positive value. -45 and 38 are the limits of
|
||||
// acceptable exponents in this test.
|
||||
TEST(FromChars, DecimalFloatLimits) {
|
||||
auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
|
||||
auto expected_gen = [](int index) { return std::pow(10.0, index); };
|
||||
TestOverflowAndUnderflow<float>(input_gen, expected_gen, -45, 38);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -1,357 +0,0 @@
|
||||
// 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/charconv_bigint.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
namespace absl {
|
||||
namespace strings_internal {
|
||||
|
||||
namespace {
|
||||
|
||||
// Table containing some large powers of 5, for fast computation.
|
||||
|
||||
// Constant step size for entries in the kLargePowersOfFive table. Each entry
|
||||
// is larger than the previous entry by a factor of 5**kLargePowerOfFiveStep
|
||||
// (or 5**27).
|
||||
//
|
||||
// In other words, the Nth entry in the table is 5**(27*N).
|
||||
//
|
||||
// 5**27 is the largest power of 5 that fits in 64 bits.
|
||||
constexpr int kLargePowerOfFiveStep = 27;
|
||||
|
||||
// The largest legal index into the kLargePowersOfFive table.
|
||||
//
|
||||
// In other words, the largest precomputed power of 5 is 5**(27*20).
|
||||
constexpr int kLargestPowerOfFiveIndex = 20;
|
||||
|
||||
// Table of powers of (5**27), up to (5**27)**20 == 5**540.
|
||||
//
|
||||
// Used to generate large powers of 5 while limiting the number of repeated
|
||||
// multiplications required.
|
||||
//
|
||||
// clang-format off
|
||||
const uint32_t kLargePowersOfFive[] = {
|
||||
// 5**27 (i=1), start=0, end=2
|
||||
0xfa10079dU, 0x6765c793U,
|
||||
// 5**54 (i=2), start=2, end=6
|
||||
0x97d9f649U, 0x6664242dU, 0x29939b14U, 0x29c30f10U,
|
||||
// 5**81 (i=3), start=6, end=12
|
||||
0xc4f809c5U, 0x7bf3f22aU, 0x67bdae34U, 0xad340517U, 0x369d1b5fU, 0x10de1593U,
|
||||
// 5**108 (i=4), start=12, end=20
|
||||
0x92b260d1U, 0x9efff7c7U, 0x81de0ec6U, 0xaeba5d56U, 0x410664a4U, 0x4f40737aU,
|
||||
0x20d3846fU, 0x06d00f73U,
|
||||
// 5**135 (i=5), start=20, end=30
|
||||
0xff1b172dU, 0x13a1d71cU, 0xefa07617U, 0x7f682d3dU, 0xff8c90c0U, 0x3f0131e7U,
|
||||
0x3fdcb9feU, 0x917b0177U, 0x16c407a7U, 0x02c06b9dU,
|
||||
// 5**162 (i=6), start=30, end=42
|
||||
0x960f7199U, 0x056667ecU, 0xe07aefd8U, 0x80f2b9ccU, 0x8273f5e3U, 0xeb9a214aU,
|
||||
0x40b38005U, 0x0e477ad4U, 0x277d08e6U, 0xfa28b11eU, 0xd3f7d784U, 0x011c835bU,
|
||||
// 5**189 (i=7), start=42, end=56
|
||||
0xf723d9d5U, 0x3282d3f3U, 0xe00857d1U, 0x69659d25U, 0x2cf117cfU, 0x24da6d07U,
|
||||
0x954d1417U, 0x3e5d8cedU, 0x7a8bb766U, 0xfd785ae6U, 0x645436d2U, 0x40c78b34U,
|
||||
0x94151217U, 0x0072e9f7U,
|
||||
// 5**216 (i=8), start=56, end=72
|
||||
0x2b416aa1U, 0x7893c5a7U, 0xe37dc6d4U, 0x2bad2beaU, 0xf0fc846cU, 0x7575ae4bU,
|
||||
0x62587b14U, 0x83b67a34U, 0x02110cdbU, 0xf7992f55U, 0x00deb022U, 0xa4a23becU,
|
||||
0x8af5c5cdU, 0xb85b654fU, 0x818df38bU, 0x002e69d2U,
|
||||
// 5**243 (i=9), start=72, end=90
|
||||
0x3518cbbdU, 0x20b0c15fU, 0x38756c2fU, 0xfb5dc3ddU, 0x22ad2d94U, 0xbf35a952U,
|
||||
0xa699192aU, 0x9a613326U, 0xad2a9cedU, 0xd7f48968U, 0xe87dfb54U, 0xc8f05db6U,
|
||||
0x5ef67531U, 0x31c1ab49U, 0xe202ac9fU, 0x9b2957b5U, 0xa143f6d3U, 0x0012bf07U,
|
||||
// 5**270 (i=10), start=90, end=110
|
||||
0x8b971de9U, 0x21aba2e1U, 0x63944362U, 0x57172336U, 0xd9544225U, 0xfb534166U,
|
||||
0x08c563eeU, 0x14640ee2U, 0x24e40d31U, 0x02b06537U, 0x03887f14U, 0x0285e533U,
|
||||
0xb744ef26U, 0x8be3a6c4U, 0x266979b4U, 0x6761ece2U, 0xd9cb39e4U, 0xe67de319U,
|
||||
0x0d39e796U, 0x00079250U,
|
||||
// 5**297 (i=11), start=110, end=132
|
||||
0x260eb6e5U, 0xf414a796U, 0xee1a7491U, 0xdb9368ebU, 0xf50c105bU, 0x59157750U,
|
||||
0x9ed2fb5cU, 0xf6e56d8bU, 0xeaee8d23U, 0x0f319f75U, 0x2aa134d6U, 0xac2908e9U,
|
||||
0xd4413298U, 0x02f02a55U, 0x989d5a7aU, 0x70dde184U, 0xba8040a7U, 0x03200981U,
|
||||
0xbe03b11cU, 0x3c1c2a18U, 0xd60427a1U, 0x00030ee0U,
|
||||
// 5**324 (i=12), start=132, end=156
|
||||
0xce566d71U, 0xf1c4aa25U, 0x4e93ca53U, 0xa72283d0U, 0x551a73eaU, 0x3d0538e2U,
|
||||
0x8da4303fU, 0x6a58de60U, 0x0e660221U, 0x49cf61a6U, 0x8d058fc1U, 0xb9d1a14cU,
|
||||
0x4bab157dU, 0xc85c6932U, 0x518c8b9eU, 0x9b92b8d0U, 0x0d8a0e21U, 0xbd855df9U,
|
||||
0xb3ea59a1U, 0x8da29289U, 0x4584d506U, 0x3752d80fU, 0xb72569c6U, 0x00013c33U,
|
||||
// 5**351 (i=13), start=156, end=182
|
||||
0x190f354dU, 0x83695cfeU, 0xe5a4d0c7U, 0xb60fb7e8U, 0xee5bbcc4U, 0xb922054cU,
|
||||
0xbb4f0d85U, 0x48394028U, 0x1d8957dbU, 0x0d7edb14U, 0x4ecc7587U, 0x505e9e02U,
|
||||
0x4c87f36bU, 0x99e66bd6U, 0x44b9ed35U, 0x753037d4U, 0xe5fe5f27U, 0x2742c203U,
|
||||
0x13b2ed2bU, 0xdc525d2cU, 0xe6fde59aU, 0x77ffb18fU, 0x13c5752cU, 0x08a84bccU,
|
||||
0x859a4940U, 0x00007fb6U,
|
||||
// 5**378 (i=14), start=182, end=210
|
||||
0x4f98cb39U, 0xa60edbbcU, 0x83b5872eU, 0xa501acffU, 0x9cc76f78U, 0xbadd4c73U,
|
||||
0x43e989faU, 0xca7acf80U, 0x2e0c824fU, 0xb19f4ffcU, 0x092fd81cU, 0xe4eb645bU,
|
||||
0xa1ff84c2U, 0x8a5a83baU, 0xa8a1fae9U, 0x1db43609U, 0xb0fed50bU, 0x0dd7d2bdU,
|
||||
0x7d7accd8U, 0x91fa640fU, 0x37dcc6c5U, 0x1c417fd5U, 0xe4d462adU, 0xe8a43399U,
|
||||
0x131bf9a5U, 0x8df54d29U, 0x36547dc1U, 0x00003395U,
|
||||
// 5**405 (i=15), start=210, end=240
|
||||
0x5bd330f5U, 0x77d21967U, 0x1ac481b7U, 0x6be2f7ceU, 0x7f4792a9U, 0xe84c2c52U,
|
||||
0x84592228U, 0x9dcaf829U, 0xdab44ce1U, 0x3d0c311bU, 0x532e297dU, 0x4704e8b4U,
|
||||
0x9cdc32beU, 0x41e64d9dU, 0x7717bea1U, 0xa824c00dU, 0x08f50b27U, 0x0f198d77U,
|
||||
0x49bbfdf0U, 0x025c6c69U, 0xd4e55cd3U, 0xf083602bU, 0xb9f0fecdU, 0xc0864aeaU,
|
||||
0x9cb98681U, 0xaaf620e9U, 0xacb6df30U, 0x4faafe66U, 0x8af13c3bU, 0x000014d5U,
|
||||
// 5**432 (i=16), start=240, end=272
|
||||
0x682bb941U, 0x89a9f297U, 0xcba75d7bU, 0x404217b1U, 0xb4e519e9U, 0xa1bc162bU,
|
||||
0xf7f5910aU, 0x98715af5U, 0x2ff53e57U, 0xe3ef118cU, 0x490c4543U, 0xbc9b1734U,
|
||||
0x2affbe4dU, 0x4cedcb4cU, 0xfb14e99eU, 0x35e34212U, 0xece39c24U, 0x07673ab3U,
|
||||
0xe73115ddU, 0xd15d38e7U, 0x093eed3bU, 0xf8e7eac5U, 0x78a8cc80U, 0x25227aacU,
|
||||
0x3f590551U, 0x413da1cbU, 0xdf643a55U, 0xab65ad44U, 0xd70b23d7U, 0xc672cd76U,
|
||||
0x3364ea62U, 0x0000086aU,
|
||||
// 5**459 (i=17), start=272, end=306
|
||||
0x22f163ddU, 0x23cf07acU, 0xbe2af6c2U, 0xf412f6f6U, 0xc3ff541eU, 0x6eeaf7deU,
|
||||
0xa47047e0U, 0x408cda92U, 0x0f0eeb08U, 0x56deba9dU, 0xcfc6b090U, 0x8bbbdf04U,
|
||||
0x3933cdb3U, 0x9e7bb67dU, 0x9f297035U, 0x38946244U, 0xee1d37bbU, 0xde898174U,
|
||||
0x63f3559dU, 0x705b72fbU, 0x138d27d9U, 0xf8603a78U, 0x735eec44U, 0xe30987d5U,
|
||||
0xc6d38070U, 0x9cfe548eU, 0x9ff01422U, 0x7c564aa8U, 0x91cc60baU, 0xcbc3565dU,
|
||||
0x7550a50bU, 0x6909aeadU, 0x13234c45U, 0x00000366U,
|
||||
// 5**486 (i=18), start=306, end=342
|
||||
0x17954989U, 0x3a7d7709U, 0x98042de5U, 0xa9011443U, 0x45e723c2U, 0x269ffd6fU,
|
||||
0x58852a46U, 0xaaa1042aU, 0x2eee8153U, 0xb2b6c39eU, 0xaf845b65U, 0xf6c365d7U,
|
||||
0xe4cffb2bU, 0xc840e90cU, 0xabea8abbU, 0x5c58f8d2U, 0x5c19fa3aU, 0x4670910aU,
|
||||
0x4449f21cU, 0xefa645b3U, 0xcc427decU, 0x083c3d73U, 0x467cb413U, 0x6fe10ae4U,
|
||||
0x3caffc72U, 0x9f8da55eU, 0x5e5c8ea7U, 0x490594bbU, 0xf0871b0bU, 0xdd89816cU,
|
||||
0x8e931df8U, 0xe85ce1c9U, 0xcca090a5U, 0x575fa16bU, 0x6b9f106cU, 0x0000015fU,
|
||||
// 5**513 (i=19), start=342, end=380
|
||||
0xee20d805U, 0x57bc3c07U, 0xcdea624eU, 0xd3f0f52dU, 0x9924b4f4U, 0xcf968640U,
|
||||
0x61d41962U, 0xe87fb464U, 0xeaaf51c7U, 0x564c8b60U, 0xccda4028U, 0x529428bbU,
|
||||
0x313a1fa8U, 0x96bd0f94U, 0x7a82ebaaU, 0xad99e7e9U, 0xf2668cd4U, 0xbe33a45eU,
|
||||
0xfd0db669U, 0x87ee369fU, 0xd3ec20edU, 0x9c4d7db7U, 0xdedcf0d8U, 0x7cd2ca64U,
|
||||
0xe25a6577U, 0x61003fd4U, 0xe56f54ccU, 0x10b7c748U, 0x40526e5eU, 0x7300ae87U,
|
||||
0x5c439261U, 0x2c0ff469U, 0xbf723f12U, 0xb2379b61U, 0xbf59b4f5U, 0xc91b1c3fU,
|
||||
0xf0046d27U, 0x0000008dU,
|
||||
// 5**540 (i=20), start=380, end=420
|
||||
0x525c9e11U, 0xf4e0eb41U, 0xebb2895dU, 0x5da512f9U, 0x7d9b29d4U, 0x452f4edcU,
|
||||
0x0b90bc37U, 0x341777cbU, 0x63d269afU, 0x1da77929U, 0x0a5c1826U, 0x77991898U,
|
||||
0x5aeddf86U, 0xf853a877U, 0x538c31ccU, 0xe84896daU, 0xb7a0010bU, 0x17ef4de5U,
|
||||
0xa52a2adeU, 0x029fd81cU, 0x987ce701U, 0x27fefd77U, 0xdb46c66fU, 0x5d301900U,
|
||||
0x496998c0U, 0xbb6598b9U, 0x5eebb607U, 0xe547354aU, 0xdf4a2f7eU, 0xf06c4955U,
|
||||
0x96242ffaU, 0x1775fb27U, 0xbecc58ceU, 0xebf2a53bU, 0x3eaad82aU, 0xf41137baU,
|
||||
0x573e6fbaU, 0xfb4866b8U, 0x54002148U, 0x00000039U,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// Returns a pointer to the big integer data for (5**27)**i. i must be
|
||||
// between 1 and 20, inclusive.
|
||||
const uint32_t* LargePowerOfFiveData(int i) {
|
||||
return kLargePowersOfFive + i * (i - 1);
|
||||
}
|
||||
|
||||
// Returns the size of the big integer data for (5**27)**i, in words. i must be
|
||||
// between 1 and 20, inclusive.
|
||||
int LargePowerOfFiveSize(int i) { return 2 * i; }
|
||||
} // namespace
|
||||
|
||||
const uint32_t kFiveToNth[14] = {
|
||||
1, 5, 25, 125, 625, 3125, 15625,
|
||||
78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125,
|
||||
};
|
||||
|
||||
const uint32_t kTenToNth[10] = {
|
||||
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
|
||||
};
|
||||
|
||||
template <int max_words>
|
||||
int BigUnsigned<max_words>::ReadFloatMantissa(const ParsedFloat& fp,
|
||||
int significant_digits) {
|
||||
SetToZero();
|
||||
assert(fp.type == FloatType::kNumber);
|
||||
|
||||
if (fp.subrange_begin == nullptr) {
|
||||
// We already exactly parsed the mantissa, so no more work is necessary.
|
||||
words_[0] = fp.mantissa & 0xffffffffu;
|
||||
words_[1] = fp.mantissa >> 32;
|
||||
if (words_[1]) {
|
||||
size_ = 2;
|
||||
} else if (words_[0]) {
|
||||
size_ = 1;
|
||||
}
|
||||
return fp.exponent;
|
||||
}
|
||||
int exponent_adjust =
|
||||
ReadDigits(fp.subrange_begin, fp.subrange_end, significant_digits);
|
||||
return fp.literal_exponent + exponent_adjust;
|
||||
}
|
||||
|
||||
template <int max_words>
|
||||
int BigUnsigned<max_words>::ReadDigits(const char* begin, const char* end,
|
||||
int significant_digits) {
|
||||
assert(significant_digits <= Digits10() + 1);
|
||||
SetToZero();
|
||||
|
||||
bool after_decimal_point = false;
|
||||
// Discard any leading zeroes before the decimal point
|
||||
while (begin < end && *begin == '0') {
|
||||
++begin;
|
||||
}
|
||||
int dropped_digits = 0;
|
||||
// Discard any trailing zeroes. These may or may not be after the decimal
|
||||
// point.
|
||||
while (begin < end && *std::prev(end) == '0') {
|
||||
--end;
|
||||
++dropped_digits;
|
||||
}
|
||||
if (begin < end && *std::prev(end) == '.') {
|
||||
// If the std::string ends in '.', either before or after dropping zeroes, then
|
||||
// drop the decimal point and look for more digits to drop.
|
||||
dropped_digits = 0;
|
||||
--end;
|
||||
while (begin < end && *std::prev(end) == '0') {
|
||||
--end;
|
||||
++dropped_digits;
|
||||
}
|
||||
} else if (dropped_digits) {
|
||||
// We dropped digits, and aren't sure if they're before or after the decimal
|
||||
// point. Figure that out now.
|
||||
const char* dp = std::find(begin, end, '.');
|
||||
if (dp != end) {
|
||||
// The dropped trailing digits were after the decimal point, so don't
|
||||
// count them.
|
||||
dropped_digits = 0;
|
||||
}
|
||||
}
|
||||
// Any non-fraction digits we dropped need to be accounted for in our exponent
|
||||
// adjustment.
|
||||
int exponent_adjust = dropped_digits;
|
||||
|
||||
uint32_t queued = 0;
|
||||
int digits_queued = 0;
|
||||
for (; begin != end && significant_digits > 0; ++begin) {
|
||||
if (*begin == '.') {
|
||||
after_decimal_point = true;
|
||||
continue;
|
||||
}
|
||||
if (after_decimal_point) {
|
||||
// For each fractional digit we emit in our parsed integer, adjust our
|
||||
// decimal exponent to compensate.
|
||||
--exponent_adjust;
|
||||
}
|
||||
int digit = (*begin - '0');
|
||||
--significant_digits;
|
||||
if (significant_digits == 0 && std::next(begin) != end &&
|
||||
(digit == 0 || digit == 5)) {
|
||||
// If this is the very last significant digit, but insignificant digits
|
||||
// remain, we know that the last of those remaining significant digits is
|
||||
// nonzero. (If it wasn't, we would have stripped it before we got here.)
|
||||
// So if this final digit is a 0 or 5, adjust it upward by 1.
|
||||
//
|
||||
// This adjustment is what allows incredibly large mantissas ending in
|
||||
// 500000...000000000001 to correctly round up, rather than to nearest.
|
||||
++digit;
|
||||
}
|
||||
queued = 10 * queued + digit;
|
||||
++digits_queued;
|
||||
if (digits_queued == kMaxSmallPowerOfTen) {
|
||||
MultiplyBy(kTenToNth[kMaxSmallPowerOfTen]);
|
||||
AddWithCarry(0, queued);
|
||||
queued = digits_queued = 0;
|
||||
}
|
||||
}
|
||||
// Encode any remaining digits.
|
||||
if (digits_queued) {
|
||||
MultiplyBy(kTenToNth[digits_queued]);
|
||||
AddWithCarry(0, queued);
|
||||
}
|
||||
|
||||
// If any insignificant digits remain, we will drop them. But if we have not
|
||||
// yet read the decimal point, then we have to adjust the exponent to account
|
||||
// for the dropped digits.
|
||||
if (begin < end && !after_decimal_point) {
|
||||
// This call to std::find will result in a pointer either to the decimal
|
||||
// point, or to the end of our buffer if there was none.
|
||||
//
|
||||
// Either way, [begin, decimal_point) will contain the set of dropped digits
|
||||
// that require an exponent adjustment.
|
||||
const char* decimal_point = std::find(begin, end, '.');
|
||||
exponent_adjust += (decimal_point - begin);
|
||||
}
|
||||
return exponent_adjust;
|
||||
}
|
||||
|
||||
template <int max_words>
|
||||
/* static */ BigUnsigned<max_words> BigUnsigned<max_words>::FiveToTheNth(
|
||||
int n) {
|
||||
BigUnsigned answer(1u);
|
||||
|
||||
// Seed from the table of large powers, if possible.
|
||||
bool first_pass = true;
|
||||
while (n >= kLargePowerOfFiveStep) {
|
||||
int big_power =
|
||||
std::min(n / kLargePowerOfFiveStep, kLargestPowerOfFiveIndex);
|
||||
if (first_pass) {
|
||||
// just copy, rather than multiplying by 1
|
||||
std::copy(
|
||||
LargePowerOfFiveData(big_power),
|
||||
LargePowerOfFiveData(big_power) + LargePowerOfFiveSize(big_power),
|
||||
answer.words_);
|
||||
answer.size_ = LargePowerOfFiveSize(big_power);
|
||||
first_pass = false;
|
||||
} else {
|
||||
answer.MultiplyBy(LargePowerOfFiveSize(big_power),
|
||||
LargePowerOfFiveData(big_power));
|
||||
}
|
||||
n -= kLargePowerOfFiveStep * big_power;
|
||||
}
|
||||
answer.MultiplyByFiveToTheNth(n);
|
||||
return answer;
|
||||
}
|
||||
|
||||
template <int max_words>
|
||||
void BigUnsigned<max_words>::MultiplyStep(int original_size,
|
||||
const uint32_t* other_words,
|
||||
int other_size, int step) {
|
||||
int this_i = std::min(original_size - 1, step);
|
||||
int other_i = step - this_i;
|
||||
|
||||
uint64_t this_word = 0;
|
||||
uint64_t carry = 0;
|
||||
for (; this_i >= 0 && other_i < other_size; --this_i, ++other_i) {
|
||||
uint64_t product = words_[this_i];
|
||||
product *= other_words[other_i];
|
||||
this_word += product;
|
||||
carry += (this_word >> 32);
|
||||
this_word &= 0xffffffff;
|
||||
}
|
||||
AddWithCarry(step + 1, carry);
|
||||
words_[step] = this_word & 0xffffffff;
|
||||
if (this_word > 0 && size_ <= step) {
|
||||
size_ = step + 1;
|
||||
}
|
||||
}
|
||||
|
||||
template <int max_words>
|
||||
std::string BigUnsigned<max_words>::ToString() const {
|
||||
BigUnsigned<max_words> copy = *this;
|
||||
std::string result;
|
||||
// Build result in reverse order
|
||||
while (copy.size() > 0) {
|
||||
int next_digit = copy.DivMod<10>();
|
||||
result.push_back('0' + next_digit);
|
||||
}
|
||||
if (result.empty()) {
|
||||
result.push_back('0');
|
||||
}
|
||||
std::reverse(result.begin(), result.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
template class BigUnsigned<4>;
|
||||
template class BigUnsigned<84>;
|
||||
|
||||
} // namespace strings_internal
|
||||
} // namespace absl
|
||||
@ -1,426 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifndef ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_
|
||||
#define ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/ascii.h"
|
||||
#include "absl/strings/internal/charconv_parse.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
namespace strings_internal {
|
||||
|
||||
// The largest power that 5 that can be raised to, and still fit in a uint32_t.
|
||||
constexpr int kMaxSmallPowerOfFive = 13;
|
||||
// The largest power that 10 that can be raised to, and still fit in a uint32_t.
|
||||
constexpr int kMaxSmallPowerOfTen = 9;
|
||||
|
||||
extern const uint32_t kFiveToNth[kMaxSmallPowerOfFive + 1];
|
||||
extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1];
|
||||
|
||||
// Large, fixed-width unsigned integer.
|
||||
//
|
||||
// Exact rounding for decimal-to-binary floating point conversion requires very
|
||||
// large integer math, but a design goal of absl::from_chars is to avoid
|
||||
// allocating memory. The integer precision needed for decimal-to-binary
|
||||
// conversions is large but bounded, so a huge fixed-width integer class
|
||||
// suffices.
|
||||
//
|
||||
// This is an intentionally limited big integer class. Only needed operations
|
||||
// are implemented. All storage lives in an array data member, and all
|
||||
// arithmetic is done in-place, to avoid requiring separate storage for operand
|
||||
// and result.
|
||||
//
|
||||
// This is an internal class. Some methods live in the .cc file, and are
|
||||
// instantiated only for the values of max_words we need.
|
||||
template <int max_words>
|
||||
class BigUnsigned {
|
||||
public:
|
||||
static_assert(max_words == 4 || max_words == 84,
|
||||
"unsupported max_words value");
|
||||
|
||||
BigUnsigned() : size_(0), words_{} {}
|
||||
explicit BigUnsigned(uint32_t v) : size_(v > 0 ? 1 : 0), words_{v} {}
|
||||
explicit BigUnsigned(uint64_t v)
|
||||
: size_(0),
|
||||
words_{static_cast<uint32_t>(v & 0xffffffff),
|
||||
static_cast<uint32_t>(v >> 32)} {
|
||||
if (words_[1]) {
|
||||
size_ = 2;
|
||||
} else if (words_[0]) {
|
||||
size_ = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Constructs a BigUnsigned from the given string_view containing a decimal
|
||||
// value. If the input std::string is not a decimal integer, constructs a 0
|
||||
// instead.
|
||||
explicit BigUnsigned(absl::string_view sv) : size_(0), words_{} {
|
||||
// Check for valid input, returning a 0 otherwise. This is reasonable
|
||||
// behavior only because this constructor is for unit tests.
|
||||
if (std::find_if_not(sv.begin(), sv.end(), ascii_isdigit) != sv.end() ||
|
||||
sv.empty()) {
|
||||
return;
|
||||
}
|
||||
int exponent_adjust =
|
||||
ReadDigits(sv.data(), sv.data() + sv.size(), Digits10() + 1);
|
||||
if (exponent_adjust > 0) {
|
||||
MultiplyByTenToTheNth(exponent_adjust);
|
||||
}
|
||||
}
|
||||
|
||||
// Loads the mantissa value of a previously-parsed float.
|
||||
//
|
||||
// Returns the associated decimal exponent. The value of the parsed float is
|
||||
// exactly *this * 10**exponent.
|
||||
int ReadFloatMantissa(const ParsedFloat& fp, int significant_digits);
|
||||
|
||||
// Returns the number of decimal digits of precision this type provides. All
|
||||
// numbers with this many decimal digits or fewer are representable by this
|
||||
// type.
|
||||
//
|
||||
// Analagous to std::numeric_limits<BigUnsigned>::digits10.
|
||||
static constexpr int Digits10() {
|
||||
// 9975007/1035508 is very slightly less than log10(2**32).
|
||||
return static_cast<uint64_t>(max_words) * 9975007 / 1035508;
|
||||
}
|
||||
|
||||
// Shifts left by the given number of bits.
|
||||
void ShiftLeft(int count) {
|
||||
if (count > 0) {
|
||||
const int word_shift = count / 32;
|
||||
if (word_shift >= max_words) {
|
||||
SetToZero();
|
||||
return;
|
||||
}
|
||||
size_ = std::min(size_ + word_shift, max_words);
|
||||
count %= 32;
|
||||
if (count == 0) {
|
||||
std::copy_backward(words_, words_ + size_ - word_shift, words_ + size_);
|
||||
} else {
|
||||
for (int i = std::min(size_, max_words - 1); i > word_shift; --i) {
|
||||
words_[i] = (words_[i - word_shift] << count) |
|
||||
(words_[i - word_shift - 1] >> (32 - count));
|
||||
}
|
||||
words_[word_shift] = words_[0] << count;
|
||||
// Grow size_ if necessary.
|
||||
if (size_ < max_words && words_[size_]) {
|
||||
++size_;
|
||||
}
|
||||
}
|
||||
std::fill(words_, words_ + word_shift, 0u);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Multiplies by v in-place.
|
||||
void MultiplyBy(uint32_t v) {
|
||||
if (size_ == 0 || v == 1) {
|
||||
return;
|
||||
}
|
||||
if (v == 0) {
|
||||
SetToZero();
|
||||
return;
|
||||
}
|
||||
const uint64_t factor = v;
|
||||
uint64_t window = 0;
|
||||
for (int i = 0; i < size_; ++i) {
|
||||
window += factor * words_[i];
|
||||
words_[i] = window & 0xffffffff;
|
||||
window >>= 32;
|
||||
}
|
||||
// If carry bits remain and there's space for them, grow size_.
|
||||
if (window && size_ < max_words) {
|
||||
words_[size_] = window & 0xffffffff;
|
||||
++size_;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplyBy(uint64_t v) {
|
||||
uint32_t words[2];
|
||||
words[0] = static_cast<uint32_t>(v);
|
||||
words[1] = static_cast<uint32_t>(v >> 32);
|
||||
if (words[1] == 0) {
|
||||
MultiplyBy(words[0]);
|
||||
} else {
|
||||
MultiplyBy(2, words);
|
||||
}
|
||||
}
|
||||
|
||||
// Multiplies in place by 5 to the power of n. n must be non-negative.
|
||||
void MultiplyByFiveToTheNth(int n) {
|
||||
while (n >= kMaxSmallPowerOfFive) {
|
||||
MultiplyBy(kFiveToNth[kMaxSmallPowerOfFive]);
|
||||
n -= kMaxSmallPowerOfFive;
|
||||
}
|
||||
if (n > 0) {
|
||||
MultiplyBy(kFiveToNth[n]);
|
||||
}
|
||||
}
|
||||
|
||||
// Multiplies in place by 10 to the power of n. n must be non-negative.
|
||||
void MultiplyByTenToTheNth(int n) {
|
||||
if (n > kMaxSmallPowerOfTen) {
|
||||
// For large n, raise to a power of 5, then shift left by the same amount.
|
||||
// (10**n == 5**n * 2**n.) This requires fewer multiplications overall.
|
||||
MultiplyByFiveToTheNth(n);
|
||||
ShiftLeft(n);
|
||||
} else if (n > 0) {
|
||||
// We can do this more quickly for very small N by using a single
|
||||
// multiplication.
|
||||
MultiplyBy(kTenToNth[n]);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the value of 5**n, for non-negative n. This implementation uses
|
||||
// a lookup table, and is faster then seeding a BigUnsigned with 1 and calling
|
||||
// MultiplyByFiveToTheNth().
|
||||
static BigUnsigned FiveToTheNth(int n);
|
||||
|
||||
// Multiplies by another BigUnsigned, in-place.
|
||||
template <int M>
|
||||
void MultiplyBy(const BigUnsigned<M>& other) {
|
||||
MultiplyBy(other.size(), other.words());
|
||||
}
|
||||
|
||||
void SetToZero() {
|
||||
std::fill(words_, words_ + size_, 0u);
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
// Returns the value of the nth word of this BigUnsigned. This is
|
||||
// range-checked, and returns 0 on out-of-bounds accesses.
|
||||
uint32_t GetWord(int index) const {
|
||||
if (index < 0 || index >= size_) {
|
||||
return 0;
|
||||
}
|
||||
return words_[index];
|
||||
}
|
||||
|
||||
// Returns this integer as a decimal std::string. This is not used in the decimal-
|
||||
// to-binary conversion; it is intended to aid in testing.
|
||||
std::string ToString() const;
|
||||
|
||||
int size() const { return size_; }
|
||||
const uint32_t* words() const { return words_; }
|
||||
|
||||
private:
|
||||
// Reads the number between [begin, end), possibly containing a decimal point,
|
||||
// into this BigUnsigned.
|
||||
//
|
||||
// Callers are required to ensure [begin, end) contains a valid number, with
|
||||
// one or more decimal digits and at most one decimal point. This routine
|
||||
// will behave unpredictably if these preconditions are not met.
|
||||
//
|
||||
// Only the first `significant_digits` digits are read. Digits beyond this
|
||||
// limit are "sticky": If the final significant digit is 0 or 5, and if any
|
||||
// dropped digit is nonzero, then that final significant digit is adjusted up
|
||||
// to 1 or 6. This adjustment allows for precise rounding.
|
||||
//
|
||||
// Returns `exponent_adjustment`, a power-of-ten exponent adjustment to
|
||||
// account for the decimal point and for dropped significant digits. After
|
||||
// this function returns,
|
||||
// actual_value_of_parsed_string ~= *this * 10**exponent_adjustment.
|
||||
int ReadDigits(const char* begin, const char* end, int significant_digits);
|
||||
|
||||
// Performs a step of big integer multiplication. This computes the full
|
||||
// (64-bit-wide) values that should be added at the given index (step), and
|
||||
// adds to that location in-place.
|
||||
//
|
||||
// Because our math all occurs in place, we must multiply starting from the
|
||||
// highest word working downward. (This is a bit more expensive due to the
|
||||
// extra carries involved.)
|
||||
//
|
||||
// This must be called in steps, for each word to be calculated, starting from
|
||||
// the high end and working down to 0. The first value of `step` should be
|
||||
// `std::min(original_size + other.size_ - 2, max_words - 1)`.
|
||||
// The reason for this expression is that multiplying the i'th word from one
|
||||
// multiplicand and the j'th word of another multiplicand creates a
|
||||
// two-word-wide value to be stored at the (i+j)'th element. The highest
|
||||
// word indices we will access are `original_size - 1` from this object, and
|
||||
// `other.size_ - 1` from our operand. Therefore,
|
||||
// `original_size + other.size_ - 2` is the first step we should calculate,
|
||||
// but limited on an upper bound by max_words.
|
||||
|
||||
// Working from high-to-low ensures that we do not overwrite the portions of
|
||||
// the initial value of *this which are still needed for later steps.
|
||||
//
|
||||
// Once called with step == 0, *this contains the result of the
|
||||
// multiplication.
|
||||
//
|
||||
// `original_size` is the size_ of *this before the first call to
|
||||
// MultiplyStep(). `other_words` and `other_size` are the contents of our
|
||||
// operand. `step` is the step to perform, as described above.
|
||||
void MultiplyStep(int original_size, const uint32_t* other_words,
|
||||
int other_size, int step);
|
||||
|
||||
void MultiplyBy(int other_size, const uint32_t* other_words) {
|
||||
const int original_size = size_;
|
||||
const int first_step =
|
||||
std::min(original_size + other_size - 2, max_words - 1);
|
||||
for (int step = first_step; step >= 0; --step) {
|
||||
MultiplyStep(original_size, other_words, other_size, step);
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a 32-bit value to the index'th word, with carry.
|
||||
void AddWithCarry(int index, uint32_t value) {
|
||||
if (value) {
|
||||
while (index < max_words && value > 0) {
|
||||
words_[index] += value;
|
||||
// carry if we overflowed in this word:
|
||||
if (value > words_[index]) {
|
||||
value = 1;
|
||||
++index;
|
||||
} else {
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
size_ = std::min(max_words, std::max(index + 1, size_));
|
||||
}
|
||||
}
|
||||
|
||||
void AddWithCarry(int index, uint64_t value) {
|
||||
if (value && index < max_words) {
|
||||
uint32_t high = value >> 32;
|
||||
uint32_t low = value & 0xffffffff;
|
||||
words_[index] += low;
|
||||
if (words_[index] < low) {
|
||||
++high;
|
||||
if (high == 0) {
|
||||
// Carry from the low word caused our high word to overflow.
|
||||
// Short circuit here to do the right thing.
|
||||
AddWithCarry(index + 2, static_cast<uint32_t>(1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (high > 0) {
|
||||
AddWithCarry(index + 1, high);
|
||||
} else {
|
||||
// Normally 32-bit AddWithCarry() sets size_, but since we don't call
|
||||
// it when `high` is 0, do it ourselves here.
|
||||
size_ = std::min(max_words, std::max(index + 1, size_));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divide this in place by a constant divisor. Returns the remainder of the
|
||||
// division.
|
||||
template <uint32_t divisor>
|
||||
uint32_t DivMod() {
|
||||
uint64_t accumulator = 0;
|
||||
for (int i = size_ - 1; i >= 0; --i) {
|
||||
accumulator <<= 32;
|
||||
accumulator += words_[i];
|
||||
// accumulator / divisor will never overflow an int32_t in this loop
|
||||
words_[i] = static_cast<uint32_t>(accumulator / divisor);
|
||||
accumulator = accumulator % divisor;
|
||||
}
|
||||
while (size_ > 0 && words_[size_ - 1] == 0) {
|
||||
--size_;
|
||||
}
|
||||
return static_cast<uint32_t>(accumulator);
|
||||
}
|
||||
|
||||
// The number of elements in words_ that may carry significant values.
|
||||
// All elements beyond this point are 0.
|
||||
//
|
||||
// When size_ is 0, this BigUnsigned stores the value 0.
|
||||
// When size_ is nonzero, is *not* guaranteed that words_[size_ - 1] is
|
||||
// nonzero. This can occur due to overflow truncation.
|
||||
// In particular, x.size_ != y.size_ does *not* imply x != y.
|
||||
int size_;
|
||||
uint32_t words_[max_words];
|
||||
};
|
||||
|
||||
// Compares two big integer instances.
|
||||
//
|
||||
// Returns -1 if lhs < rhs, 0 if lhs == rhs, and 1 if lhs > rhs.
|
||||
template <int N, int M>
|
||||
int Compare(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
|
||||
int limit = std::max(lhs.size(), rhs.size());
|
||||
for (int i = limit - 1; i >= 0; --i) {
|
||||
const uint32_t lhs_word = lhs.GetWord(i);
|
||||
const uint32_t rhs_word = rhs.GetWord(i);
|
||||
if (lhs_word < rhs_word) {
|
||||
return -1;
|
||||
} else if (lhs_word > rhs_word) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
bool operator==(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
|
||||
int limit = std::max(lhs.size(), rhs.size());
|
||||
for (int i = 0; i < limit; ++i) {
|
||||
if (lhs.GetWord(i) != rhs.GetWord(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
bool operator!=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
bool operator<(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
|
||||
return Compare(lhs, rhs) == -1;
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
bool operator>(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
|
||||
return rhs < lhs;
|
||||
}
|
||||
template <int N, int M>
|
||||
bool operator<=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
template <int N, int M>
|
||||
bool operator>=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
// Output operator for BigUnsigned, for testing purposes only.
|
||||
template <int N>
|
||||
std::ostream& operator<<(std::ostream& os, const BigUnsigned<N>& num) {
|
||||
return os << num.ToString();
|
||||
}
|
||||
|
||||
// Explicit instantiation declarations for the sizes of BigUnsigned that we
|
||||
// are using.
|
||||
//
|
||||
// For now, the choices of 4 and 84 are arbitrary; 4 is a small value that is
|
||||
// still bigger than an int128, and 84 is a large value we will want to use
|
||||
// in the from_chars implementation.
|
||||
//
|
||||
// Comments justifying the use of 84 belong in the from_chars implementation,
|
||||
// and will be added in a follow-up CL.
|
||||
extern template class BigUnsigned<4>;
|
||||
extern template class BigUnsigned<84>;
|
||||
|
||||
} // namespace strings_internal
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_
|
||||
@ -1,203 +0,0 @@
|
||||
// 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/charconv_bigint.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace absl {
|
||||
namespace strings_internal {
|
||||
|
||||
TEST(BigUnsigned, ShiftLeft) {
|
||||
{
|
||||
// Check that 3 * 2**100 is calculated correctly
|
||||
BigUnsigned<4> num(3u);
|
||||
num.ShiftLeft(100);
|
||||
EXPECT_EQ(num, BigUnsigned<4>("3802951800684688204490109616128"));
|
||||
}
|
||||
{
|
||||
// Test that overflow is truncated properly.
|
||||
// 15 is 4 bits long, and BigUnsigned<4> is a 128-bit bigint.
|
||||
// Shifting left by 125 bits should truncate off the high bit, so that
|
||||
// 15 << 125 == 7 << 125
|
||||
// after truncation.
|
||||
BigUnsigned<4> a(15u);
|
||||
BigUnsigned<4> b(7u);
|
||||
BigUnsigned<4> c(3u);
|
||||
a.ShiftLeft(125);
|
||||
b.ShiftLeft(125);
|
||||
c.ShiftLeft(125);
|
||||
EXPECT_EQ(a, b);
|
||||
EXPECT_NE(a, c);
|
||||
}
|
||||
{
|
||||
// Same test, larger bigint:
|
||||
BigUnsigned<84> a(15u);
|
||||
BigUnsigned<84> b(7u);
|
||||
BigUnsigned<84> c(3u);
|
||||
a.ShiftLeft(84 * 32 - 3);
|
||||
b.ShiftLeft(84 * 32 - 3);
|
||||
c.ShiftLeft(84 * 32 - 3);
|
||||
EXPECT_EQ(a, b);
|
||||
EXPECT_NE(a, c);
|
||||
}
|
||||
{
|
||||
// Check that incrementally shifting has the same result as doing it all at
|
||||
// once (attempting to capture corner cases.)
|
||||
const std::string seed = "1234567890123456789012345678901234567890";
|
||||
BigUnsigned<84> a(seed);
|
||||
for (int i = 1; i <= 84 * 32; ++i) {
|
||||
a.ShiftLeft(1);
|
||||
BigUnsigned<84> b(seed);
|
||||
b.ShiftLeft(i);
|
||||
EXPECT_EQ(a, b);
|
||||
}
|
||||
// And we should have fully rotated all bits off by now:
|
||||
EXPECT_EQ(a, BigUnsigned<84>(0u));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BigUnsigned, MultiplyByUint32) {
|
||||
const BigUnsigned<84> factorial_100(
|
||||
"933262154439441526816992388562667004907159682643816214685929638952175999"
|
||||
"932299156089414639761565182862536979208272237582511852109168640000000000"
|
||||
"00000000000000");
|
||||
BigUnsigned<84> a(1u);
|
||||
for (uint32_t i = 1; i <= 100; ++i) {
|
||||
a.MultiplyBy(i);
|
||||
}
|
||||
EXPECT_EQ(a, BigUnsigned<84>(factorial_100));
|
||||
}
|
||||
|
||||
TEST(BigUnsigned, MultiplyByBigUnsigned) {
|
||||
{
|
||||
// Put the terms of factorial_200 into two bigints, and multiply them
|
||||
// together.
|
||||
const BigUnsigned<84> factorial_200(
|
||||
"7886578673647905035523632139321850622951359776871732632947425332443594"
|
||||
"4996340334292030428401198462390417721213891963883025764279024263710506"
|
||||
"1926624952829931113462857270763317237396988943922445621451664240254033"
|
||||
"2918641312274282948532775242424075739032403212574055795686602260319041"
|
||||
"7032406235170085879617892222278962370389737472000000000000000000000000"
|
||||
"0000000000000000000000000");
|
||||
BigUnsigned<84> evens(1u);
|
||||
BigUnsigned<84> odds(1u);
|
||||
for (uint32_t i = 1; i < 200; i += 2) {
|
||||
odds.MultiplyBy(i);
|
||||
evens.MultiplyBy(i + 1);
|
||||
}
|
||||
evens.MultiplyBy(odds);
|
||||
EXPECT_EQ(evens, factorial_200);
|
||||
}
|
||||
{
|
||||
// Multiply various powers of 10 together.
|
||||
for (int a = 0 ; a < 700; a += 25) {
|
||||
SCOPED_TRACE(a);
|
||||
BigUnsigned<84> a_value("3" + std::string(a, '0'));
|
||||
for (int b = 0; b < (700 - a); b += 25) {
|
||||
SCOPED_TRACE(b);
|
||||
BigUnsigned<84> b_value("2" + std::string(b, '0'));
|
||||
BigUnsigned<84> expected_product("6" + std::string(a + b, '0'));
|
||||
b_value.MultiplyBy(a_value);
|
||||
EXPECT_EQ(b_value, expected_product);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BigUnsigned, MultiplyByOverflow) {
|
||||
{
|
||||
// Check that multiplcation overflow predictably truncates.
|
||||
|
||||
// A big int with all bits on.
|
||||
BigUnsigned<4> all_bits_on("340282366920938463463374607431768211455");
|
||||
// Modulo 2**128, this is equal to -1. Therefore the square of this,
|
||||
// modulo 2**128, should be 1.
|
||||
all_bits_on.MultiplyBy(all_bits_on);
|
||||
EXPECT_EQ(all_bits_on, BigUnsigned<4>(1u));
|
||||
}
|
||||
{
|
||||
// Try multiplying a large bigint by 2**50, and compare the result to
|
||||
// shifting.
|
||||
BigUnsigned<4> value_1("12345678901234567890123456789012345678");
|
||||
BigUnsigned<4> value_2("12345678901234567890123456789012345678");
|
||||
BigUnsigned<4> two_to_fiftieth(1u);
|
||||
two_to_fiftieth.ShiftLeft(50);
|
||||
|
||||
value_1.ShiftLeft(50);
|
||||
value_2.MultiplyBy(two_to_fiftieth);
|
||||
EXPECT_EQ(value_1, value_2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BigUnsigned, FiveToTheNth) {
|
||||
{
|
||||
// Sanity check that MultiplyByFiveToTheNth gives consistent answers, up to
|
||||
// and including overflow.
|
||||
for (int i = 0; i < 1160; ++i) {
|
||||
SCOPED_TRACE(i);
|
||||
BigUnsigned<84> value_1(123u);
|
||||
BigUnsigned<84> value_2(123u);
|
||||
value_1.MultiplyByFiveToTheNth(i);
|
||||
for (int j = 0; j < i; j++) {
|
||||
value_2.MultiplyBy(5u);
|
||||
}
|
||||
EXPECT_EQ(value_1, value_2);
|
||||
}
|
||||
}
|
||||
{
|
||||
// Check that the faster, table-lookup-based static method returns the same
|
||||
// result that multiplying in-place would return, up to and including
|
||||
// overflow.
|
||||
for (int i = 0; i < 1160; ++i) {
|
||||
SCOPED_TRACE(i);
|
||||
BigUnsigned<84> value_1(1u);
|
||||
value_1.MultiplyByFiveToTheNth(i);
|
||||
BigUnsigned<84> value_2 = BigUnsigned<84>::FiveToTheNth(i);
|
||||
EXPECT_EQ(value_1, value_2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BigUnsigned, TenToTheNth) {
|
||||
{
|
||||
// Sanity check MultiplyByTenToTheNth.
|
||||
for (int i = 0; i < 800; ++i) {
|
||||
SCOPED_TRACE(i);
|
||||
BigUnsigned<84> value_1(123u);
|
||||
BigUnsigned<84> value_2(123u);
|
||||
value_1.MultiplyByTenToTheNth(i);
|
||||
for (int j = 0; j < i; j++) {
|
||||
value_2.MultiplyBy(10u);
|
||||
}
|
||||
EXPECT_EQ(value_1, value_2);
|
||||
}
|
||||
}
|
||||
{
|
||||
// Alternate testing approach, taking advantage of the decimal parser.
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
SCOPED_TRACE(i);
|
||||
BigUnsigned<84> value_1(135u);
|
||||
value_1.MultiplyByTenToTheNth(i);
|
||||
BigUnsigned<84> value_2("135" + std::string(i, '0'));
|
||||
EXPECT_EQ(value_1, value_2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace strings_internal
|
||||
} // namespace absl
|
||||
@ -1,496 +0,0 @@
|
||||
// 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/charconv_parse.h"
|
||||
#include "absl/strings/charconv.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
#include "absl/strings/internal/memutil.h"
|
||||
|
||||
namespace absl {
|
||||
namespace {
|
||||
|
||||
// ParseFloat<10> will read the first 19 significant digits of the mantissa.
|
||||
// This number was chosen for multiple reasons.
|
||||
//
|
||||
// (a) First, for whatever integer type we choose to represent the mantissa, we
|
||||
// want to choose the largest possible number of decimal digits for that integer
|
||||
// type. We are using uint64_t, which can express any 19-digit unsigned
|
||||
// integer.
|
||||
//
|
||||
// (b) Second, we need to parse enough digits that the binary value of any
|
||||
// mantissa we capture has more bits of resolution than the mantissa
|
||||
// representation in the target float. Our algorithm requires at least 3 bits
|
||||
// of headway, but 19 decimal digits give a little more than that.
|
||||
//
|
||||
// The following static assertions verify the above comments:
|
||||
constexpr int kDecimalMantissaDigitsMax = 19;
|
||||
|
||||
static_assert(std::numeric_limits<uint64_t>::digits10 ==
|
||||
kDecimalMantissaDigitsMax,
|
||||
"(a) above");
|
||||
|
||||
// IEEE doubles, which we assume in Abseil, have 53 binary bits of mantissa.
|
||||
static_assert(std::numeric_limits<double>::is_iec559, "IEEE double assumed");
|
||||
static_assert(std::numeric_limits<double>::radix == 2, "IEEE double fact");
|
||||
static_assert(std::numeric_limits<double>::digits == 53, "IEEE double fact");
|
||||
|
||||
// The lowest valued 19-digit decimal mantissa we can read still contains
|
||||
// sufficient information to reconstruct a binary mantissa.
|
||||
static_assert(1000000000000000000u > (uint64_t(1) << (53 + 3)), "(b) above");
|
||||
|
||||
// ParseFloat<16> will read the first 15 significant digits of the mantissa.
|
||||
//
|
||||
// Because a base-16-to-base-2 conversion can be done exactly, we do not need
|
||||
// to maximize the number of scanned hex digits to improve our conversion. What
|
||||
// is required is to scan two more bits than the mantissa can represent, so that
|
||||
// we always round correctly.
|
||||
//
|
||||
// (One extra bit does not suffice to perform correct rounding, since a number
|
||||
// exactly halfway between two representable floats has unique rounding rules,
|
||||
// so we need to differentiate between a "halfway between" number and a "closer
|
||||
// to the larger value" number.)
|
||||
constexpr int kHexadecimalMantissaDigitsMax = 15;
|
||||
|
||||
// The minimum number of significant bits that will be read from
|
||||
// kHexadecimalMantissaDigitsMax hex digits. We must subtract by three, since
|
||||
// the most significant digit can be a "1", which only contributes a single
|
||||
// significant bit.
|
||||
constexpr int kGuaranteedHexadecimalMantissaBitPrecision =
|
||||
4 * kHexadecimalMantissaDigitsMax - 3;
|
||||
|
||||
static_assert(kGuaranteedHexadecimalMantissaBitPrecision >
|
||||
std::numeric_limits<double>::digits + 2,
|
||||
"kHexadecimalMantissaDigitsMax too small");
|
||||
|
||||
// We also impose a limit on the number of significant digits we will read from
|
||||
// an exponent, to avoid having to deal with integer overflow. We use 9 for
|
||||
// this purpose.
|
||||
//
|
||||
// If we read a 9 digit exponent, the end result of the conversion will
|
||||
// necessarily be infinity or zero, depending on the sign of the exponent.
|
||||
// Therefore we can just drop extra digits on the floor without any extra
|
||||
// logic.
|
||||
constexpr int kDecimalExponentDigitsMax = 9;
|
||||
static_assert(std::numeric_limits<int>::digits10 >= kDecimalExponentDigitsMax,
|
||||
"int type too small");
|
||||
|
||||
// To avoid incredibly large inputs causing integer overflow for our exponent,
|
||||
// we impose an arbitrary but very large limit on the number of significant
|
||||
// digits we will accept. The implementation refuses to match a std::string with
|
||||
// more consecutive significant mantissa digits than this.
|
||||
constexpr int kDecimalDigitLimit = 50000000;
|
||||
|
||||
// Corresponding limit for hexadecimal digit inputs. This is one fourth the
|
||||
// amount of kDecimalDigitLimit, since each dropped hexadecimal digit requires
|
||||
// a binary exponent adjustment of 4.
|
||||
constexpr int kHexadecimalDigitLimit = kDecimalDigitLimit / 4;
|
||||
|
||||
// The largest exponent we can read is 999999999 (per
|
||||
// kDecimalExponentDigitsMax), and the largest exponent adjustment we can get
|
||||
// from dropped mantissa digits is 2 * kDecimalDigitLimit, and the sum of these
|
||||
// comfortably fits in an integer.
|
||||
//
|
||||
// We count kDecimalDigitLimit twice because there are independent limits for
|
||||
// numbers before and after the decimal point. (In the case where there are no
|
||||
// significant digits before the decimal point, there are independent limits for
|
||||
// post-decimal-point leading zeroes and for significant digits.)
|
||||
static_assert(999999999 + 2 * kDecimalDigitLimit <
|
||||
std::numeric_limits<int>::max(),
|
||||
"int type too small");
|
||||
static_assert(999999999 + 2 * (4 * kHexadecimalDigitLimit) <
|
||||
std::numeric_limits<int>::max(),
|
||||
"int type too small");
|
||||
|
||||
// Returns true if the provided bitfield allows parsing an exponent value
|
||||
// (e.g., "1.5e100").
|
||||
bool AllowExponent(chars_format flags) {
|
||||
bool fixed = (flags & chars_format::fixed) == chars_format::fixed;
|
||||
bool scientific =
|
||||
(flags & chars_format::scientific) == chars_format::scientific;
|
||||
return scientific || !fixed;
|
||||
}
|
||||
|
||||
// Returns true if the provided bitfield requires an exponent value be present.
|
||||
bool RequireExponent(chars_format flags) {
|
||||
bool fixed = (flags & chars_format::fixed) == chars_format::fixed;
|
||||
bool scientific =
|
||||
(flags & chars_format::scientific) == chars_format::scientific;
|
||||
return scientific && !fixed;
|
||||
}
|
||||
|
||||
const int8_t kAsciiToInt[256] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||
|
||||
// Returns true if `ch` is a digit in the given base
|
||||
template <int base>
|
||||
bool IsDigit(char ch);
|
||||
|
||||
// Converts a valid `ch` to its digit value in the given base.
|
||||
template <int base>
|
||||
unsigned ToDigit(char ch);
|
||||
|
||||
// Returns true if `ch` is the exponent delimiter for the given base.
|
||||
template <int base>
|
||||
bool IsExponentCharacter(char ch);
|
||||
|
||||
// Returns the maximum number of significant digits we will read for a float
|
||||
// in the given base.
|
||||
template <int base>
|
||||
constexpr int MantissaDigitsMax();
|
||||
|
||||
// Returns the largest consecutive run of digits we will accept when parsing a
|
||||
// number in the given base.
|
||||
template <int base>
|
||||
constexpr int DigitLimit();
|
||||
|
||||
// Returns the amount the exponent must be adjusted by for each dropped digit.
|
||||
// (For decimal this is 1, since the digits are in base 10 and the exponent base
|
||||
// is also 10, but for hexadecimal this is 4, since the digits are base 16 but
|
||||
// the exponent base is 2.)
|
||||
template <int base>
|
||||
constexpr int DigitMagnitude();
|
||||
|
||||
template <>
|
||||
bool IsDigit<10>(char ch) {
|
||||
return ch >= '0' && ch <= '9';
|
||||
}
|
||||
template <>
|
||||
bool IsDigit<16>(char ch) {
|
||||
return kAsciiToInt[static_cast<unsigned char>(ch)] >= 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
unsigned ToDigit<10>(char ch) {
|
||||
return ch - '0';
|
||||
}
|
||||
template <>
|
||||
unsigned ToDigit<16>(char ch) {
|
||||
return kAsciiToInt[static_cast<unsigned char>(ch)];
|
||||
}
|
||||
|
||||
template <>
|
||||
bool IsExponentCharacter<10>(char ch) {
|
||||
return ch == 'e' || ch == 'E';
|
||||
}
|
||||
|
||||
template <>
|
||||
bool IsExponentCharacter<16>(char ch) {
|
||||
return ch == 'p' || ch == 'P';
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr int MantissaDigitsMax<10>() {
|
||||
return kDecimalMantissaDigitsMax;
|
||||
}
|
||||
template <>
|
||||
constexpr int MantissaDigitsMax<16>() {
|
||||
return kHexadecimalMantissaDigitsMax;
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr int DigitLimit<10>() {
|
||||
return kDecimalDigitLimit;
|
||||
}
|
||||
template <>
|
||||
constexpr int DigitLimit<16>() {
|
||||
return kHexadecimalDigitLimit;
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr int DigitMagnitude<10>() {
|
||||
return 1;
|
||||
}
|
||||
template <>
|
||||
constexpr int DigitMagnitude<16>() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
// Reads decimal digits from [begin, end) into *out. Returns the number of
|
||||
// digits consumed.
|
||||
//
|
||||
// After max_digits has been read, keeps consuming characters, but no longer
|
||||
// adjusts *out. If a nonzero digit is dropped this way, *dropped_nonzero_digit
|
||||
// is set; otherwise, it is left unmodified.
|
||||
//
|
||||
// If no digits are matched, returns 0 and leaves *out unchanged.
|
||||
//
|
||||
// ConsumeDigits does not protect against overflow on *out; max_digits must
|
||||
// be chosen with respect to type T to avoid the possibility of overflow.
|
||||
template <int base, typename T>
|
||||
std::size_t ConsumeDigits(const char* begin, const char* end, int max_digits,
|
||||
T* out, bool* dropped_nonzero_digit) {
|
||||
if (base == 10) {
|
||||
assert(max_digits <= std::numeric_limits<T>::digits10);
|
||||
} else if (base == 16) {
|
||||
assert(max_digits * 4 <= std::numeric_limits<T>::digits);
|
||||
}
|
||||
const char* const original_begin = begin;
|
||||
T accumulator = *out;
|
||||
const char* significant_digits_end =
|
||||
(end - begin > max_digits) ? begin + max_digits : end;
|
||||
while (begin < significant_digits_end && IsDigit<base>(*begin)) {
|
||||
// Do not guard against *out overflow; max_digits was chosen to avoid this.
|
||||
// Do assert against it, to detect problems in debug builds.
|
||||
auto digit = static_cast<T>(ToDigit<base>(*begin));
|
||||
assert(accumulator * base >= accumulator);
|
||||
accumulator *= base;
|
||||
assert(accumulator + digit >= accumulator);
|
||||
accumulator += digit;
|
||||
++begin;
|
||||
}
|
||||
bool dropped_nonzero = false;
|
||||
while (begin < end && IsDigit<base>(*begin)) {
|
||||
dropped_nonzero = dropped_nonzero || (*begin != '0');
|
||||
++begin;
|
||||
}
|
||||
if (dropped_nonzero && dropped_nonzero_digit != nullptr) {
|
||||
*dropped_nonzero_digit = true;
|
||||
}
|
||||
*out = accumulator;
|
||||
return begin - original_begin;
|
||||
}
|
||||
|
||||
// Returns true if `v` is one of the chars allowed inside parentheses following
|
||||
// a NaN.
|
||||
bool IsNanChar(char v) {
|
||||
return (v == '_') || (v >= '0' && v <= '9') || (v >= 'a' && v <= 'z') ||
|
||||
(v >= 'A' && v <= 'Z');
|
||||
}
|
||||
|
||||
// Checks the range [begin, end) for a strtod()-formatted infinity or NaN. If
|
||||
// one is found, sets `out` appropriately and returns true.
|
||||
bool ParseInfinityOrNan(const char* begin, const char* end,
|
||||
strings_internal::ParsedFloat* out) {
|
||||
if (end - begin < 3) {
|
||||
return false;
|
||||
}
|
||||
switch (*begin) {
|
||||
case 'i':
|
||||
case 'I': {
|
||||
// An infinity std::string consists of the characters "inf" or "infinity",
|
||||
// case insensitive.
|
||||
if (strings_internal::memcasecmp(begin + 1, "nf", 2) != 0) {
|
||||
return false;
|
||||
}
|
||||
out->type = strings_internal::FloatType::kInfinity;
|
||||
if (end - begin >= 8 &&
|
||||
strings_internal::memcasecmp(begin + 3, "inity", 5) == 0) {
|
||||
out->end = begin + 8;
|
||||
} else {
|
||||
out->end = begin + 3;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case 'n':
|
||||
case 'N': {
|
||||
// A NaN consists of the characters "nan", case insensitive, optionally
|
||||
// followed by a parenthesized sequence of zero or more alphanumeric
|
||||
// characters and/or underscores.
|
||||
if (strings_internal::memcasecmp(begin + 1, "an", 2) != 0) {
|
||||
return false;
|
||||
}
|
||||
out->type = strings_internal::FloatType::kNan;
|
||||
out->end = begin + 3;
|
||||
// NaN is allowed to be followed by a parenthesized std::string, consisting of
|
||||
// only the characters [a-zA-Z0-9_]. Match that if it's present.
|
||||
begin += 3;
|
||||
if (begin < end && *begin == '(') {
|
||||
const char* nan_begin = begin + 1;
|
||||
while (nan_begin < end && IsNanChar(*nan_begin)) {
|
||||
++nan_begin;
|
||||
}
|
||||
if (nan_begin < end && *nan_begin == ')') {
|
||||
// We found an extra NaN specifier range
|
||||
out->subrange_begin = begin + 1;
|
||||
out->subrange_end = nan_begin;
|
||||
out->end = nan_begin + 1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace strings_internal {
|
||||
|
||||
template <int base>
|
||||
strings_internal::ParsedFloat ParseFloat(const char* begin, const char* end,
|
||||
chars_format format_flags) {
|
||||
strings_internal::ParsedFloat result;
|
||||
|
||||
// Exit early if we're given an empty range.
|
||||
if (begin == end) return result;
|
||||
|
||||
// Handle the infinity and NaN cases.
|
||||
if (ParseInfinityOrNan(begin, end, &result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* const mantissa_begin = begin;
|
||||
while (begin < end && *begin == '0') {
|
||||
++begin; // skip leading zeros
|
||||
}
|
||||
uint64_t mantissa = 0;
|
||||
|
||||
int exponent_adjustment = 0;
|
||||
bool mantissa_is_inexact = false;
|
||||
std::size_t pre_decimal_digits = ConsumeDigits<base>(
|
||||
begin, end, MantissaDigitsMax<base>(), &mantissa, &mantissa_is_inexact);
|
||||
begin += pre_decimal_digits;
|
||||
int digits_left;
|
||||
if (pre_decimal_digits >= DigitLimit<base>()) {
|
||||
// refuse to parse pathological inputs
|
||||
return result;
|
||||
} else if (pre_decimal_digits > MantissaDigitsMax<base>()) {
|
||||
// We dropped some non-fraction digits on the floor. Adjust our exponent
|
||||
// to compensate.
|
||||
exponent_adjustment =
|
||||
static_cast<int>(pre_decimal_digits - MantissaDigitsMax<base>());
|
||||
digits_left = 0;
|
||||
} else {
|
||||
digits_left =
|
||||
static_cast<int>(MantissaDigitsMax<base>() - pre_decimal_digits);
|
||||
}
|
||||
if (begin < end && *begin == '.') {
|
||||
++begin;
|
||||
if (mantissa == 0) {
|
||||
// If we haven't seen any nonzero digits yet, keep skipping zeros. We
|
||||
// have to adjust the exponent to reflect the changed place value.
|
||||
const char* begin_zeros = begin;
|
||||
while (begin < end && *begin == '0') {
|
||||
++begin;
|
||||
}
|
||||
std::size_t zeros_skipped = begin - begin_zeros;
|
||||
if (zeros_skipped >= DigitLimit<base>()) {
|
||||
// refuse to parse pathological inputs
|
||||
return result;
|
||||
}
|
||||
exponent_adjustment -= static_cast<int>(zeros_skipped);
|
||||
}
|
||||
std::size_t post_decimal_digits = ConsumeDigits<base>(
|
||||
begin, end, digits_left, &mantissa, &mantissa_is_inexact);
|
||||
begin += post_decimal_digits;
|
||||
|
||||
// Since `mantissa` is an integer, each significant digit we read after
|
||||
// the decimal point requires an adjustment to the exponent. "1.23e0" will
|
||||
// be stored as `mantissa` == 123 and `exponent` == -2 (that is,
|
||||
// "123e-2").
|
||||
if (post_decimal_digits >= DigitLimit<base>()) {
|
||||
// refuse to parse pathological inputs
|
||||
return result;
|
||||
} else if (post_decimal_digits > digits_left) {
|
||||
exponent_adjustment -= digits_left;
|
||||
} else {
|
||||
exponent_adjustment -= post_decimal_digits;
|
||||
}
|
||||
}
|
||||
// If we've found no mantissa whatsoever, this isn't a number.
|
||||
if (mantissa_begin == begin) {
|
||||
return result;
|
||||
}
|
||||
// A bare "." doesn't count as a mantissa either.
|
||||
if (begin - mantissa_begin == 1 && *mantissa_begin == '.') {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (mantissa_is_inexact) {
|
||||
// We dropped significant digits on the floor. Handle this appropriately.
|
||||
if (base == 10) {
|
||||
// If we truncated significant decimal digits, store the full range of the
|
||||
// mantissa for future big integer math for exact rounding.
|
||||
result.subrange_begin = mantissa_begin;
|
||||
result.subrange_end = begin;
|
||||
} else if (base == 16) {
|
||||
// If we truncated hex digits, reflect this fact by setting the low
|
||||
// ("sticky") bit. This allows for correct rounding in all cases.
|
||||
mantissa |= 1;
|
||||
}
|
||||
}
|
||||
result.mantissa = mantissa;
|
||||
|
||||
const char* const exponent_begin = begin;
|
||||
result.literal_exponent = 0;
|
||||
bool found_exponent = false;
|
||||
if (AllowExponent(format_flags) && begin < end &&
|
||||
IsExponentCharacter<base>(*begin)) {
|
||||
bool negative_exponent = false;
|
||||
++begin;
|
||||
if (begin < end && *begin == '-') {
|
||||
negative_exponent = true;
|
||||
++begin;
|
||||
} else if (begin < end && *begin == '+') {
|
||||
++begin;
|
||||
}
|
||||
const char* const exponent_digits_begin = begin;
|
||||
// Exponent is always expressed in decimal, even for hexadecimal floats.
|
||||
begin += ConsumeDigits<10>(begin, end, kDecimalExponentDigitsMax,
|
||||
&result.literal_exponent, nullptr);
|
||||
if (begin == exponent_digits_begin) {
|
||||
// there were no digits where we expected an exponent. We failed to read
|
||||
// an exponent and should not consume the 'e' after all. Rewind 'begin'.
|
||||
found_exponent = false;
|
||||
begin = exponent_begin;
|
||||
} else {
|
||||
found_exponent = true;
|
||||
if (negative_exponent) {
|
||||
result.literal_exponent = -result.literal_exponent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_exponent && RequireExponent(format_flags)) {
|
||||
// Provided flags required an exponent, but none was found. This results
|
||||
// in a failure to scan.
|
||||
return result;
|
||||
}
|
||||
|
||||
// Success!
|
||||
result.type = strings_internal::FloatType::kNumber;
|
||||
if (result.mantissa > 0) {
|
||||
result.exponent = result.literal_exponent +
|
||||
(DigitMagnitude<base>() * exponent_adjustment);
|
||||
} else {
|
||||
result.exponent = 0;
|
||||
}
|
||||
result.end = begin;
|
||||
return result;
|
||||
}
|
||||
|
||||
template ParsedFloat ParseFloat<10>(const char* begin, const char* end,
|
||||
chars_format format_flags);
|
||||
template ParsedFloat ParseFloat<16>(const char* begin, const char* end,
|
||||
chars_format format_flags);
|
||||
|
||||
} // namespace strings_internal
|
||||
} // namespace absl
|
||||
@ -1,96 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifndef ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_
|
||||
#define ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "absl/strings/charconv.h"
|
||||
|
||||
namespace absl {
|
||||
namespace strings_internal {
|
||||
|
||||
// Enum indicating whether a parsed float is a number or special value.
|
||||
enum class FloatType { kNumber, kInfinity, kNan };
|
||||
|
||||
// The decomposed parts of a parsed `float` or `double`.
|
||||
struct ParsedFloat {
|
||||
// Representation of the parsed mantissa, with the decimal point adjusted to
|
||||
// make it an integer.
|
||||
//
|
||||
// During decimal scanning, this contains 19 significant digits worth of
|
||||
// mantissa value. If digits beyond this point are found, they
|
||||
// are truncated, and if any of these dropped digits are nonzero, then
|
||||
// `mantissa` is inexact, and the full mantissa is stored in [subrange_begin,
|
||||
// subrange_end).
|
||||
//
|
||||
// During hexadecimal scanning, this contains 15 significant hex digits worth
|
||||
// of mantissa value. Digits beyond this point are sticky -- they are
|
||||
// truncated, but if any dropped digits are nonzero, the low bit of mantissa
|
||||
// will be set. (This allows for precise rounding, and avoids the need
|
||||
// to store the full mantissa in [subrange_begin, subrange_end).)
|
||||
uint64_t mantissa = 0;
|
||||
|
||||
// Floating point expontent. This reflects any decimal point adjustments and
|
||||
// any truncated digits from the mantissa. The absolute value of the parsed
|
||||
// number is represented by mantissa * (base ** exponent), where base==10 for
|
||||
// decimal floats, and base==2 for hexadecimal floats.
|
||||
int exponent = 0;
|
||||
|
||||
// The literal exponent value scanned from the input, or 0 if none was
|
||||
// present. This does not reflect any adjustments applied to mantissa.
|
||||
int literal_exponent = 0;
|
||||
|
||||
// The type of number scanned.
|
||||
FloatType type = FloatType::kNumber;
|
||||
|
||||
// When non-null, [subrange_begin, subrange_end) marks a range of characters
|
||||
// that require further processing. The meaning is dependent on float type.
|
||||
// If type == kNumber and this is set, this is a "wide input": the input
|
||||
// mantissa contained more than 19 digits. The range contains the full
|
||||
// mantissa. It plus `literal_exponent` need to be examined to find the best
|
||||
// floating point match.
|
||||
// If type == kNan and this is set, the range marks the contents of a
|
||||
// matched parenthesized character region after the NaN.
|
||||
const char* subrange_begin = nullptr;
|
||||
const char* subrange_end = nullptr;
|
||||
|
||||
// One-past-the-end of the successfully parsed region, or nullptr if no
|
||||
// matching pattern was found.
|
||||
const char* end = nullptr;
|
||||
};
|
||||
|
||||
// Read the floating point number in the provided range, and populate
|
||||
// ParsedFloat accordingly.
|
||||
//
|
||||
// format_flags is a bitmask value specifying what patterns this API will match.
|
||||
// `scientific` and `fixed` are honored per std::from_chars rules
|
||||
// ([utility.from.chars], C++17): if exactly one of these bits is set, then an
|
||||
// exponent is required, or dislallowed, respectively.
|
||||
//
|
||||
// Template parameter `base` must be either 10 or 16. For base 16, a "0x" is
|
||||
// *not* consumed. The `hex` bit from format_flags is ignored by ParseFloat.
|
||||
template <int base>
|
||||
ParsedFloat ParseFloat(const char* begin, const char* end,
|
||||
absl::chars_format format_flags);
|
||||
|
||||
extern template ParsedFloat ParseFloat<10>(const char* begin, const char* end,
|
||||
absl::chars_format format_flags);
|
||||
extern template ParsedFloat ParseFloat<16>(const char* begin, const char* end,
|
||||
absl::chars_format format_flags);
|
||||
|
||||
} // namespace strings_internal
|
||||
} // namespace absl
|
||||
#endif // ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_
|
||||
@ -1,357 +0,0 @@
|
||||
// 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/charconv_parse.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
|
||||
using absl::chars_format;
|
||||
using absl::strings_internal::FloatType;
|
||||
using absl::strings_internal::ParsedFloat;
|
||||
using absl::strings_internal::ParseFloat;
|
||||
|
||||
namespace {
|
||||
|
||||
// Check that a given std::string input is parsed to the expected mantissa and
|
||||
// exponent.
|
||||
//
|
||||
// Input std::string `s` must contain a '$' character. It marks the end of the
|
||||
// characters that should be consumed by the match. It is stripped from the
|
||||
// input to ParseFloat.
|
||||
//
|
||||
// If input std::string `s` contains '[' and ']' characters, these mark the region
|
||||
// of characters that should be marked as the "subrange". For NaNs, this is
|
||||
// the location of the extended NaN std::string. For numbers, this is the location
|
||||
// of the full, over-large mantissa.
|
||||
template <int base>
|
||||
void ExpectParsedFloat(std::string s, absl::chars_format format_flags,
|
||||
FloatType expected_type, uint64_t expected_mantissa,
|
||||
int expected_exponent,
|
||||
int expected_literal_exponent = -999) {
|
||||
SCOPED_TRACE(s);
|
||||
|
||||
int begin_subrange = -1;
|
||||
int end_subrange = -1;
|
||||
// If s contains '[' and ']', then strip these characters and set the subrange
|
||||
// indices appropriately.
|
||||
std::string::size_type open_bracket_pos = s.find('[');
|
||||
if (open_bracket_pos != std::string::npos) {
|
||||
begin_subrange = static_cast<int>(open_bracket_pos);
|
||||
s.replace(open_bracket_pos, 1, "");
|
||||
std::string::size_type close_bracket_pos = s.find(']');
|
||||
ABSL_RAW_CHECK(close_bracket_pos != absl::string_view::npos,
|
||||
"Test input contains [ without matching ]");
|
||||
end_subrange = static_cast<int>(close_bracket_pos);
|
||||
s.replace(close_bracket_pos, 1, "");
|
||||
}
|
||||
const std::string::size_type expected_characters_matched = s.find('$');
|
||||
ABSL_RAW_CHECK(expected_characters_matched != std::string::npos,
|
||||
"Input std::string must contain $");
|
||||
s.replace(expected_characters_matched, 1, "");
|
||||
|
||||
ParsedFloat parsed =
|
||||
ParseFloat<base>(s.data(), s.data() + s.size(), format_flags);
|
||||
|
||||
EXPECT_NE(parsed.end, nullptr);
|
||||
if (parsed.end == nullptr) {
|
||||
return; // The following tests are not useful if we fully failed to parse
|
||||
}
|
||||
EXPECT_EQ(parsed.type, expected_type);
|
||||
if (begin_subrange == -1) {
|
||||
EXPECT_EQ(parsed.subrange_begin, nullptr);
|
||||
EXPECT_EQ(parsed.subrange_end, nullptr);
|
||||
} else {
|
||||
EXPECT_EQ(parsed.subrange_begin, s.data() + begin_subrange);
|
||||
EXPECT_EQ(parsed.subrange_end, s.data() + end_subrange);
|
||||
}
|
||||
if (parsed.type == FloatType::kNumber) {
|
||||
EXPECT_EQ(parsed.mantissa, expected_mantissa);
|
||||
EXPECT_EQ(parsed.exponent, expected_exponent);
|
||||
if (expected_literal_exponent != -999) {
|
||||
EXPECT_EQ(parsed.literal_exponent, expected_literal_exponent);
|
||||
}
|
||||
}
|
||||
auto characters_matched = static_cast<int>(parsed.end - s.data());
|
||||
EXPECT_EQ(characters_matched, expected_characters_matched);
|
||||
}
|
||||
|
||||
// Check that a given std::string input is parsed to the expected mantissa and
|
||||
// exponent.
|
||||
//
|
||||
// Input std::string `s` must contain a '$' character. It marks the end of the
|
||||
// characters that were consumed by the match.
|
||||
template <int base>
|
||||
void ExpectNumber(std::string s, absl::chars_format format_flags,
|
||||
uint64_t expected_mantissa, int expected_exponent,
|
||||
int expected_literal_exponent = -999) {
|
||||
ExpectParsedFloat<base>(std::move(s), format_flags, FloatType::kNumber,
|
||||
expected_mantissa, expected_exponent,
|
||||
expected_literal_exponent);
|
||||
}
|
||||
|
||||
// Check that a given std::string input is parsed to the given special value.
|
||||
//
|
||||
// This tests against both number bases, since infinities and NaNs have
|
||||
// identical representations in both modes.
|
||||
void ExpectSpecial(const std::string& s, absl::chars_format format_flags,
|
||||
FloatType type) {
|
||||
ExpectParsedFloat<10>(s, format_flags, type, 0, 0);
|
||||
ExpectParsedFloat<16>(s, format_flags, type, 0, 0);
|
||||
}
|
||||
|
||||
// Check that a given input std::string is not matched by Float.
|
||||
template <int base>
|
||||
void ExpectFailedParse(absl::string_view s, absl::chars_format format_flags) {
|
||||
ParsedFloat parsed =
|
||||
ParseFloat<base>(s.data(), s.data() + s.size(), format_flags);
|
||||
EXPECT_EQ(parsed.end, nullptr);
|
||||
}
|
||||
|
||||
TEST(ParseFloat, SimpleValue) {
|
||||
// Test that various forms of floating point numbers all parse correctly.
|
||||
ExpectNumber<10>("1.23456789e5$", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("1.23456789e+5$", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("1.23456789E5$", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("1.23456789e05$", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("123.456789e3$", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("0.000123456789e9$", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("123456.789$", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("123456789e-3$", chars_format::general, 123456789, -3);
|
||||
|
||||
ExpectNumber<16>("1.234abcdefp28$", chars_format::general, 0x1234abcdef, -8);
|
||||
ExpectNumber<16>("1.234abcdefp+28$", chars_format::general, 0x1234abcdef, -8);
|
||||
ExpectNumber<16>("1.234ABCDEFp28$", chars_format::general, 0x1234abcdef, -8);
|
||||
ExpectNumber<16>("1.234AbCdEfP0028$", chars_format::general, 0x1234abcdef,
|
||||
-8);
|
||||
ExpectNumber<16>("123.4abcdefp20$", chars_format::general, 0x1234abcdef, -8);
|
||||
ExpectNumber<16>("0.0001234abcdefp44$", chars_format::general, 0x1234abcdef,
|
||||
-8);
|
||||
ExpectNumber<16>("1234abcd.ef$", chars_format::general, 0x1234abcdef, -8);
|
||||
ExpectNumber<16>("1234abcdefp-8$", chars_format::general, 0x1234abcdef, -8);
|
||||
|
||||
// ExpectNumber does not attempt to drop trailing zeroes.
|
||||
ExpectNumber<10>("0001.2345678900e005$", chars_format::general, 12345678900,
|
||||
-5);
|
||||
ExpectNumber<16>("0001.234abcdef000p28$", chars_format::general,
|
||||
0x1234abcdef000, -20);
|
||||
|
||||
// Ensure non-matching characters after a number are ignored, even when they
|
||||
// look like potentially matching characters.
|
||||
ExpectNumber<10>("1.23456789e5$ ", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("1.23456789e5$e5e5", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("1.23456789e5$.25", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("1.23456789e5$-", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("1.23456789e5$PUPPERS!!!", chars_format::general, 123456789,
|
||||
-3);
|
||||
ExpectNumber<10>("123456.789$efghij", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("123456.789$e", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("123456.789$p5", chars_format::general, 123456789, -3);
|
||||
ExpectNumber<10>("123456.789$.10", chars_format::general, 123456789, -3);
|
||||
|
||||
ExpectNumber<16>("1.234abcdefp28$ ", chars_format::general, 0x1234abcdef,
|
||||
-8);
|
||||
ExpectNumber<16>("1.234abcdefp28$p28", chars_format::general, 0x1234abcdef,
|
||||
-8);
|
||||
ExpectNumber<16>("1.234abcdefp28$.125", chars_format::general, 0x1234abcdef,
|
||||
-8);
|
||||
ExpectNumber<16>("1.234abcdefp28$-", chars_format::general, 0x1234abcdef, -8);
|
||||
ExpectNumber<16>("1.234abcdefp28$KITTEHS!!!", chars_format::general,
|
||||
0x1234abcdef, -8);
|
||||
ExpectNumber<16>("1234abcd.ef$ghijk", chars_format::general, 0x1234abcdef,
|
||||
-8);
|
||||
ExpectNumber<16>("1234abcd.ef$p", chars_format::general, 0x1234abcdef, -8);
|
||||
ExpectNumber<16>("1234abcd.ef$.10", chars_format::general, 0x1234abcdef, -8);
|
||||
|
||||
// Ensure we can read a full resolution mantissa without overflow.
|
||||
ExpectNumber<10>("9999999999999999999$", chars_format::general,
|
||||
9999999999999999999u, 0);
|
||||
ExpectNumber<16>("fffffffffffffff$", chars_format::general,
|
||||
0xfffffffffffffffu, 0);
|
||||
|
||||
// Check that zero is consistently read.
|
||||
ExpectNumber<10>("0$", chars_format::general, 0, 0);
|
||||
ExpectNumber<16>("0$", chars_format::general, 0, 0);
|
||||
ExpectNumber<10>("000000000000000000000000000000000000000$",
|
||||
chars_format::general, 0, 0);
|
||||
ExpectNumber<16>("000000000000000000000000000000000000000$",
|
||||
chars_format::general, 0, 0);
|
||||
ExpectNumber<10>("0000000000000000000000.000000000000000000$",
|
||||
chars_format::general, 0, 0);
|
||||
ExpectNumber<16>("0000000000000000000000.000000000000000000$",
|
||||
chars_format::general, 0, 0);
|
||||
ExpectNumber<10>("0.00000000000000000000000000000000e123456$",
|
||||
chars_format::general, 0, 0);
|
||||
ExpectNumber<16>("0.00000000000000000000000000000000p123456$",
|
||||
chars_format::general, 0, 0);
|
||||
}
|
||||
|
||||
TEST(ParseFloat, LargeDecimalMantissa) {
|
||||
// After 19 significant decimal digits in the mantissa, ParsedFloat will
|
||||
// truncate additional digits. We need to test that:
|
||||
// 1) the truncation to 19 digits happens
|
||||
// 2) the returned exponent reflects the dropped significant digits
|
||||
// 3) a correct literal_exponent is set
|
||||
//
|
||||
// If and only if a significant digit is found after 19 digits, then the
|
||||
// entirety of the mantissa in case the exact value is needed to make a
|
||||
// rounding decision. The [ and ] characters below denote where such a
|
||||
// subregion was marked by by ParseFloat. They are not part of the input.
|
||||
|
||||
// Mark a capture group only if a dropped digit is significant (nonzero).
|
||||
ExpectNumber<10>("100000000000000000000000000$", chars_format::general,
|
||||
1000000000000000000,
|
||||
/* adjusted exponent */ 8);
|
||||
|
||||
ExpectNumber<10>("123456789123456789100000000$", chars_format::general,
|
||||
1234567891234567891,
|
||||
/* adjusted exponent */ 8);
|
||||
|
||||
ExpectNumber<10>("[123456789123456789123456789]$", chars_format::general,
|
||||
1234567891234567891,
|
||||
/* adjusted exponent */ 8,
|
||||
/* literal exponent */ 0);
|
||||
|
||||
ExpectNumber<10>("[123456789123456789100000009]$", chars_format::general,
|
||||
1234567891234567891,
|
||||
/* adjusted exponent */ 8,
|
||||
/* literal exponent */ 0);
|
||||
|
||||
ExpectNumber<10>("[123456789123456789120000000]$", chars_format::general,
|
||||
1234567891234567891,
|
||||
/* adjusted exponent */ 8,
|
||||
/* literal exponent */ 0);
|
||||
|
||||
// Leading zeroes should not count towards the 19 significant digit limit
|
||||
ExpectNumber<10>("[00000000123456789123456789123456789]$",
|
||||
chars_format::general, 1234567891234567891,
|
||||
/* adjusted exponent */ 8,
|
||||
/* literal exponent */ 0);
|
||||
|
||||
ExpectNumber<10>("00000000123456789123456789100000000$",
|
||||
chars_format::general, 1234567891234567891,
|
||||
/* adjusted exponent */ 8);
|
||||
|
||||
// Truncated digits after the decimal point should not cause a further
|
||||
// exponent adjustment.
|
||||
ExpectNumber<10>("1.234567891234567891e123$", chars_format::general,
|
||||
1234567891234567891, 105);
|
||||
ExpectNumber<10>("[1.23456789123456789123456789]e123$", chars_format::general,
|
||||
1234567891234567891,
|
||||
/* adjusted exponent */ 105,
|
||||
/* literal exponent */ 123);
|
||||
|
||||
// Ensure we truncate, and not round. (The from_chars algorithm we use
|
||||
// depends on our guess missing low, if it misses, so we need the rounding
|
||||
// error to be downward.)
|
||||
ExpectNumber<10>("[1999999999999999999999]$", chars_format::general,
|
||||
1999999999999999999,
|
||||
/* adjusted exponent */ 3,
|
||||
/* literal exponent */ 0);
|
||||
}
|
||||
|
||||
TEST(ParseFloat, LargeHexadecimalMantissa) {
|
||||
// After 15 significant hex digits in the mantissa, ParsedFloat will treat
|
||||
// additional digits as sticky, We need to test that:
|
||||
// 1) The truncation to 15 digits happens
|
||||
// 2) The returned exponent reflects the dropped significant digits
|
||||
// 3) If a nonzero digit is dropped, the low bit of mantissa is set.
|
||||
|
||||
ExpectNumber<16>("123456789abcdef123456789abcdef$", chars_format::general,
|
||||
0x123456789abcdef, 60);
|
||||
|
||||
// Leading zeroes should not count towards the 15 significant digit limit
|
||||
ExpectNumber<16>("000000123456789abcdef123456789abcdef$",
|
||||
chars_format::general, 0x123456789abcdef, 60);
|
||||
|
||||
// Truncated digits after the radix point should not cause a further
|
||||
// exponent adjustment.
|
||||
ExpectNumber<16>("1.23456789abcdefp100$", chars_format::general,
|
||||
0x123456789abcdef, 44);
|
||||
ExpectNumber<16>("1.23456789abcdef123456789abcdefp100$",
|
||||
chars_format::general, 0x123456789abcdef, 44);
|
||||
|
||||
// test sticky digit behavior. The low bit should be set iff any dropped
|
||||
// digit is nonzero.
|
||||
ExpectNumber<16>("123456789abcdee123456789abcdee$", chars_format::general,
|
||||
0x123456789abcdef, 60);
|
||||
ExpectNumber<16>("123456789abcdee000000000000001$", chars_format::general,
|
||||
0x123456789abcdef, 60);
|
||||
ExpectNumber<16>("123456789abcdee000000000000000$", chars_format::general,
|
||||
0x123456789abcdee, 60);
|
||||
}
|
||||
|
||||
TEST(ParseFloat, ScientificVsFixed) {
|
||||
// In fixed mode, an exponent is never matched (but the remainder of the
|
||||
// number will be matched.)
|
||||
ExpectNumber<10>("1.23456789$e5", chars_format::fixed, 123456789, -8);
|
||||
ExpectNumber<10>("123456.789$", chars_format::fixed, 123456789, -3);
|
||||
ExpectNumber<16>("1.234abcdef$p28", chars_format::fixed, 0x1234abcdef, -36);
|
||||
ExpectNumber<16>("1234abcd.ef$", chars_format::fixed, 0x1234abcdef, -8);
|
||||
|
||||
// In scientific mode, numbers don't match *unless* they have an exponent.
|
||||
ExpectNumber<10>("1.23456789e5$", chars_format::scientific, 123456789, -3);
|
||||
ExpectFailedParse<10>("-123456.789$", chars_format::scientific);
|
||||
ExpectNumber<16>("1.234abcdefp28$", chars_format::scientific, 0x1234abcdef,
|
||||
-8);
|
||||
ExpectFailedParse<16>("1234abcd.ef$", chars_format::scientific);
|
||||
}
|
||||
|
||||
TEST(ParseFloat, Infinity) {
|
||||
ExpectFailedParse<10>("in", chars_format::general);
|
||||
ExpectFailedParse<16>("in", chars_format::general);
|
||||
ExpectFailedParse<10>("inx", chars_format::general);
|
||||
ExpectFailedParse<16>("inx", chars_format::general);
|
||||
ExpectSpecial("inf$", chars_format::general, FloatType::kInfinity);
|
||||
ExpectSpecial("Inf$", chars_format::general, FloatType::kInfinity);
|
||||
ExpectSpecial("INF$", chars_format::general, FloatType::kInfinity);
|
||||
ExpectSpecial("inf$inite", chars_format::general, FloatType::kInfinity);
|
||||
ExpectSpecial("iNfInItY$", chars_format::general, FloatType::kInfinity);
|
||||
ExpectSpecial("infinity$!!!", chars_format::general, FloatType::kInfinity);
|
||||
}
|
||||
|
||||
TEST(ParseFloat, NaN) {
|
||||
ExpectFailedParse<10>("na", chars_format::general);
|
||||
ExpectFailedParse<16>("na", chars_format::general);
|
||||
ExpectFailedParse<10>("nah", chars_format::general);
|
||||
ExpectFailedParse<16>("nah", chars_format::general);
|
||||
ExpectSpecial("nan$", chars_format::general, FloatType::kNan);
|
||||
ExpectSpecial("NaN$", chars_format::general, FloatType::kNan);
|
||||
ExpectSpecial("nAn$", chars_format::general, FloatType::kNan);
|
||||
ExpectSpecial("NAN$", chars_format::general, FloatType::kNan);
|
||||
ExpectSpecial("NaN$aNaNaNaNaBatman!", chars_format::general, FloatType::kNan);
|
||||
|
||||
// A parenthesized sequence of the characters [a-zA-Z0-9_] is allowed to
|
||||
// appear after an NaN. Check that this is allowed, and that the correct
|
||||
// characters are grouped.
|
||||
//
|
||||
// (The characters [ and ] in the pattern below delimit the expected matched
|
||||
// subgroup; they are not part of the input passed to ParseFloat.)
|
||||
ExpectSpecial("nan([0xabcdef])$", chars_format::general, FloatType::kNan);
|
||||
ExpectSpecial("nan([0xabcdef])$...", chars_format::general, FloatType::kNan);
|
||||
ExpectSpecial("nan([0xabcdef])$)...", chars_format::general, FloatType::kNan);
|
||||
ExpectSpecial("nan([])$", chars_format::general, FloatType::kNan);
|
||||
ExpectSpecial("nan([aAzZ09_])$", chars_format::general, FloatType::kNan);
|
||||
// If the subgroup contains illegal characters, don't match it at all.
|
||||
ExpectSpecial("nan$(bad-char)", chars_format::general, FloatType::kNan);
|
||||
// Also cope with a missing close paren.
|
||||
ExpectSpecial("nan$(0xabcdef", chars_format::general, FloatType::kNan);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
78
third_party/abseil-cpp/absl/strings/numbers.cc
vendored
78
third_party/abseil-cpp/absl/strings/numbers.cc
vendored
@ -32,7 +32,6 @@
|
||||
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/strings/ascii.h"
|
||||
#include "absl/strings/charconv.h"
|
||||
#include "absl/strings/internal/bits.h"
|
||||
#include "absl/strings/internal/memutil.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
@ -41,54 +40,51 @@ namespace absl {
|
||||
|
||||
bool SimpleAtof(absl::string_view str, float* value) {
|
||||
*value = 0.0;
|
||||
str = StripAsciiWhitespace(str);
|
||||
if (!str.empty() && str[0] == '+') {
|
||||
str.remove_prefix(1);
|
||||
if (str.empty()) return false;
|
||||
char buf[32];
|
||||
std::unique_ptr<char[]> bigbuf;
|
||||
char* ptr = buf;
|
||||
if (str.size() > sizeof(buf) - 1) {
|
||||
bigbuf.reset(new char[str.size() + 1]);
|
||||
ptr = bigbuf.get();
|
||||
}
|
||||
auto result = absl::from_chars(str.data(), str.data() + str.size(), *value);
|
||||
if (result.ec == std::errc::invalid_argument) {
|
||||
return false;
|
||||
memcpy(ptr, str.data(), str.size());
|
||||
ptr[str.size()] = '\0';
|
||||
|
||||
char* endptr;
|
||||
*value = strtof(ptr, &endptr);
|
||||
if (endptr != ptr) {
|
||||
while (absl::ascii_isspace(*endptr)) ++endptr;
|
||||
}
|
||||
if (result.ptr != str.data() + str.size()) {
|
||||
// not all non-whitespace characters consumed
|
||||
return false;
|
||||
}
|
||||
// from_chars() with DR 3801's current wording will return max() on
|
||||
// overflow. SimpleAtof returns infinity instead.
|
||||
if (result.ec == std::errc::result_out_of_range) {
|
||||
if (*value > 1.0) {
|
||||
*value = std::numeric_limits<float>::infinity();
|
||||
} else if (*value < -1.0) {
|
||||
*value = -std::numeric_limits<float>::infinity();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
// Ignore range errors from strtod/strtof.
|
||||
// The values it returns on underflow and
|
||||
// overflow are the right fallback in a
|
||||
// robust setting.
|
||||
return *ptr != '\0' && *endptr == '\0';
|
||||
}
|
||||
|
||||
bool SimpleAtod(absl::string_view str, double* value) {
|
||||
*value = 0.0;
|
||||
str = StripAsciiWhitespace(str);
|
||||
if (!str.empty() && str[0] == '+') {
|
||||
str.remove_prefix(1);
|
||||
if (str.empty()) return false;
|
||||
char buf[32];
|
||||
std::unique_ptr<char[]> bigbuf;
|
||||
char* ptr = buf;
|
||||
if (str.size() > sizeof(buf) - 1) {
|
||||
bigbuf.reset(new char[str.size() + 1]);
|
||||
ptr = bigbuf.get();
|
||||
}
|
||||
auto result = absl::from_chars(str.data(), str.data() + str.size(), *value);
|
||||
if (result.ec == std::errc::invalid_argument) {
|
||||
return false;
|
||||
memcpy(ptr, str.data(), str.size());
|
||||
ptr[str.size()] = '\0';
|
||||
|
||||
char* endptr;
|
||||
*value = strtod(ptr, &endptr);
|
||||
if (endptr != ptr) {
|
||||
while (absl::ascii_isspace(*endptr)) ++endptr;
|
||||
}
|
||||
if (result.ptr != str.data() + str.size()) {
|
||||
// not all non-whitespace characters consumed
|
||||
return false;
|
||||
}
|
||||
// from_chars() with DR 3801's current wording will return max() on
|
||||
// overflow. SimpleAtod returns infinity instead.
|
||||
if (result.ec == std::errc::result_out_of_range) {
|
||||
if (*value > 1.0) {
|
||||
*value = std::numeric_limits<double>::infinity();
|
||||
} else if (*value < -1.0) {
|
||||
*value = -std::numeric_limits<double>::infinity();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
// Ignore range errors from strtod. The values it
|
||||
// returns on underflow and overflow are the right
|
||||
// fallback in a robust setting.
|
||||
return *ptr != '\0' && *endptr == '\0';
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@ -149,6 +149,12 @@ cc_test(
|
||||
size = "large",
|
||||
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 = [
|
||||
":synchronization",
|
||||
":thread_pool",
|
||||
|
||||
4
third_party/abseil-cpp/absl/time/BUILD.bazel
vendored
4
third_party/abseil-cpp/absl/time/BUILD.bazel
vendored
@ -44,7 +44,6 @@ cc_library(
|
||||
"//absl/base",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/numeric:int128",
|
||||
"//absl/strings",
|
||||
"//absl/time/internal/cctz:civil_time",
|
||||
"//absl/time/internal/cctz:time_zone",
|
||||
],
|
||||
@ -81,6 +80,9 @@ cc_test(
|
||||
"time_zone_test.cc",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
tags = [
|
||||
"no_test_loonix",
|
||||
],
|
||||
deps = [
|
||||
":test_util",
|
||||
":time",
|
||||
|
||||
1
third_party/abseil-cpp/absl/time/BUILD.gn
vendored
1
third_party/abseil-cpp/absl/time/BUILD.gn
vendored
@ -37,7 +37,6 @@ source_set("time") {
|
||||
"../base",
|
||||
"../base:core_headers",
|
||||
"../numeric:int128",
|
||||
"../strings",
|
||||
"../time/internal/cctz:civil_time",
|
||||
"../time/internal/cctz:time_zone",
|
||||
]
|
||||
|
||||
@ -53,7 +53,7 @@ list(APPEND TIME_SRC
|
||||
${TIME_PUBLIC_HEADERS}
|
||||
${TIME_INTERNAL_HEADERS}
|
||||
)
|
||||
set(TIME_PUBLIC_LIBRARIES absl::base absl::stacktrace absl::int128 absl::strings)
|
||||
set(TIME_PUBLIC_LIBRARIES absl::base absl::stacktrace absl::int128)
|
||||
|
||||
absl_library(
|
||||
TARGET
|
||||
|
||||
3
third_party/abseil-cpp/absl/time/duration.cc
vendored
3
third_party/abseil-cpp/absl/time/duration.cc
vendored
@ -896,7 +896,8 @@ bool ParseDuration(const std::string& dur_string, Duration* d) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseFlag(const std::string& text, Duration* dst, std::string* ) {
|
||||
// TODO(absl-team): Remove once dependencies are removed.
|
||||
bool ParseFlag(const std::string& text, Duration* dst, std::string* /* err */) {
|
||||
return ParseDuration(text, dst);
|
||||
}
|
||||
|
||||
|
||||
1
third_party/abseil-cpp/absl/time/format.cc
vendored
1
third_party/abseil-cpp/absl/time/format.cc
vendored
@ -129,6 +129,7 @@ bool ParseTime(const std::string& format, const std::string& input, absl::TimeZo
|
||||
return b;
|
||||
}
|
||||
|
||||
// TODO(absl-team): Remove once dependencies are removed.
|
||||
// Functions required to support absl::Time flags.
|
||||
bool ParseFlag(const std::string& text, absl::Time* t, std::string* error) {
|
||||
return absl::ParseTime(RFC3339_full, text, absl::UTCTimeZone(), t, error);
|
||||
|
||||
6
third_party/abseil-cpp/absl/time/time.h
vendored
6
third_party/abseil-cpp/absl/time/time.h
vendored
@ -64,7 +64,6 @@
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/port.h" // Needed for string vs std::string
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
|
||||
|
||||
namespace absl {
|
||||
@ -492,6 +491,9 @@ inline std::ostream& operator<<(std::ostream& os, Duration d) {
|
||||
// `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`.
|
||||
bool ParseDuration(const std::string& dur_string, Duration* d);
|
||||
|
||||
// Flag Support
|
||||
// TODO(absl-team): Remove once dependencies are removed.
|
||||
|
||||
// ParseFlag()
|
||||
//
|
||||
bool ParseFlag(const std::string& text, Duration* dst, std::string* error);
|
||||
@ -991,6 +993,8 @@ bool ParseTime(const std::string& format, const std::string& input, Time* time,
|
||||
bool ParseTime(const std::string& format, const std::string& input, TimeZone tz,
|
||||
Time* time, std::string* err);
|
||||
|
||||
// TODO(absl-team): Remove once dependencies are removed.
|
||||
|
||||
// ParseFlag()
|
||||
// UnparseFlag()
|
||||
//
|
||||
|
||||
13
third_party/abseil-cpp/absl/types/BUILD.bazel
vendored
13
third_party/abseil-cpp/absl/types/BUILD.bazel
vendored
@ -247,19 +247,6 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "variant_benchmark",
|
||||
srcs = [
|
||||
"variant_benchmark.cc",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
deps = [
|
||||
":variant",
|
||||
"//absl/utility",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "variant_exception_safety_test",
|
||||
size = "small",
|
||||
|
||||
302
third_party/abseil-cpp/absl/types/internal/variant.h
vendored
302
third_party/abseil-cpp/absl/types/internal/variant.h
vendored
@ -19,19 +19,15 @@
|
||||
#ifndef ABSL_TYPES_variant_internal_H_
|
||||
#define ABSL_TYPES_variant_internal_H_
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/identity.h"
|
||||
#include "absl/base/internal/inline_variable.h"
|
||||
#include "absl/base/internal/invoke.h"
|
||||
#include "absl/base/macros.h"
|
||||
#include "absl/base/optimization.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/types/bad_variant_access.h"
|
||||
@ -123,8 +119,6 @@ using GiveQualsToT = typename GiveQualsTo<T, U>::type;
|
||||
template <std::size_t I>
|
||||
using SizeT = std::integral_constant<std::size_t, I>;
|
||||
|
||||
using NPos = SizeT<variant_npos>;
|
||||
|
||||
template <class Variant, class T, class = void>
|
||||
struct IndexOfConstructedType {};
|
||||
|
||||
@ -254,270 +248,19 @@ struct MakeVisitationMatrix<ReturnType, FunctionObject,
|
||||
ReturnType, FunctionObject, index_sequence<TailEndIndices...>,
|
||||
absl::make_index_sequence<HeadEndIndex>, BoundIndices...> {};
|
||||
|
||||
struct UnreachableSwitchCase {
|
||||
template <class Op>
|
||||
[[noreturn]] static VisitIndicesResultT<Op, std::size_t> Run(
|
||||
Op&& /*ignored*/) {
|
||||
#if ABSL_HAVE_BUILTIN(__builtin_unreachable) || \
|
||||
(defined(__GNUC__) && !defined(__clang__))
|
||||
__builtin_unreachable();
|
||||
#elif defined(_MSC_VER)
|
||||
__assume(false);
|
||||
#else
|
||||
// Try to use assert of false being identified as an unreachable intrinsic.
|
||||
// NOTE: We use assert directly to increase chances of exploiting an assume
|
||||
// intrinsic.
|
||||
assert(false); // NOLINT
|
||||
|
||||
// Hack to silence potential no return warning -- cause an infinite loop.
|
||||
return Run(absl::forward<Op>(op));
|
||||
#endif // Checks for __builtin_unreachable
|
||||
}
|
||||
};
|
||||
|
||||
template <class Op, std::size_t I>
|
||||
struct ReachableSwitchCase {
|
||||
static VisitIndicesResultT<Op, std::size_t> Run(Op&& op) {
|
||||
return absl::base_internal::Invoke(absl::forward<Op>(op), SizeT<I>());
|
||||
}
|
||||
};
|
||||
|
||||
// The number 33 is just a guess at a reasonable maximum to our switch. It is
|
||||
// not based on any analysis. The reason it is a power of 2 plus 1 instead of a
|
||||
// power of 2 is because the number was picked to correspond to a power of 2
|
||||
// amount of "normal" alternatives, plus one for the possibility of the user
|
||||
// providing "monostate" in addition to the more natural alternatives.
|
||||
ABSL_INTERNAL_INLINE_CONSTEXPR(std::size_t, MaxUnrolledVisitCases, 33);
|
||||
|
||||
// Note: The default-definition is for unreachable cases.
|
||||
template <bool IsReachable>
|
||||
struct PickCaseImpl {
|
||||
template <class Op, std::size_t I>
|
||||
using Apply = UnreachableSwitchCase;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct PickCaseImpl</*IsReachable =*/true> {
|
||||
template <class Op, std::size_t I>
|
||||
using Apply = ReachableSwitchCase<Op, I>;
|
||||
};
|
||||
|
||||
// Note: This form of dance with template aliases is to make sure that we
|
||||
// instantiate a number of templates proportional to the number of variant
|
||||
// alternatives rather than a number of templates proportional to our
|
||||
// maximum unrolled amount of visitation cases (aliases are effectively
|
||||
// "free" whereas other template instantiations are costly).
|
||||
template <class Op, std::size_t I, std::size_t EndIndex>
|
||||
using PickCase = typename PickCaseImpl<(I < EndIndex)>::template Apply<Op, I>;
|
||||
template <std::size_t... EndIndices, class Op, class... SizeT>
|
||||
VisitIndicesResultT<Op, SizeT...> visit_indices(Op&& op, SizeT... indices) {
|
||||
return AccessSimpleArray(
|
||||
MakeVisitationMatrix<VisitIndicesResultT<Op, SizeT...>, Op,
|
||||
index_sequence<(EndIndices + 1)...>>::Run(),
|
||||
(indices + 1)...)(absl::forward<Op>(op));
|
||||
}
|
||||
|
||||
template <class ReturnType>
|
||||
[[noreturn]] ReturnType TypedThrowBadVariantAccess() {
|
||||
absl::variant_internal::ThrowBadVariantAccess();
|
||||
}
|
||||
|
||||
// Given N variant sizes, determine the number of cases there would need to be
|
||||
// in a single switch-statement that would cover every possibility in the
|
||||
// corresponding N-ary visit operation.
|
||||
template <std::size_t... NumAlternatives>
|
||||
struct NumCasesOfSwitch;
|
||||
|
||||
template <std::size_t HeadNumAlternatives, std::size_t... TailNumAlternatives>
|
||||
struct NumCasesOfSwitch<HeadNumAlternatives, TailNumAlternatives...> {
|
||||
static constexpr std::size_t value =
|
||||
(HeadNumAlternatives + 1) *
|
||||
NumCasesOfSwitch<TailNumAlternatives...>::value;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct NumCasesOfSwitch<> {
|
||||
static constexpr std::size_t value = 1;
|
||||
};
|
||||
|
||||
// A switch statement optimizes better than the table of function pointers.
|
||||
template <std::size_t EndIndex>
|
||||
struct VisitIndicesSwitch {
|
||||
static_assert(EndIndex <= MaxUnrolledVisitCases,
|
||||
"Maximum unrolled switch size exceeded.");
|
||||
|
||||
template <class Op>
|
||||
static VisitIndicesResultT<Op, std::size_t> Run(Op&& op, std::size_t i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return PickCase<Op, 0, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 1:
|
||||
return PickCase<Op, 1, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 2:
|
||||
return PickCase<Op, 2, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 3:
|
||||
return PickCase<Op, 3, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 4:
|
||||
return PickCase<Op, 4, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 5:
|
||||
return PickCase<Op, 5, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 6:
|
||||
return PickCase<Op, 6, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 7:
|
||||
return PickCase<Op, 7, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 8:
|
||||
return PickCase<Op, 8, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 9:
|
||||
return PickCase<Op, 9, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 10:
|
||||
return PickCase<Op, 10, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 11:
|
||||
return PickCase<Op, 11, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 12:
|
||||
return PickCase<Op, 12, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 13:
|
||||
return PickCase<Op, 13, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 14:
|
||||
return PickCase<Op, 14, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 15:
|
||||
return PickCase<Op, 15, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 16:
|
||||
return PickCase<Op, 16, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 17:
|
||||
return PickCase<Op, 17, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 18:
|
||||
return PickCase<Op, 18, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 19:
|
||||
return PickCase<Op, 19, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 20:
|
||||
return PickCase<Op, 20, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 21:
|
||||
return PickCase<Op, 21, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 22:
|
||||
return PickCase<Op, 22, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 23:
|
||||
return PickCase<Op, 23, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 24:
|
||||
return PickCase<Op, 24, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 25:
|
||||
return PickCase<Op, 25, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 26:
|
||||
return PickCase<Op, 26, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 27:
|
||||
return PickCase<Op, 27, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 28:
|
||||
return PickCase<Op, 28, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 29:
|
||||
return PickCase<Op, 29, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 30:
|
||||
return PickCase<Op, 30, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 31:
|
||||
return PickCase<Op, 31, EndIndex>::Run(absl::forward<Op>(op));
|
||||
case 32:
|
||||
return PickCase<Op, 32, EndIndex>::Run(absl::forward<Op>(op));
|
||||
default:
|
||||
ABSL_ASSERT(i == variant_npos);
|
||||
return absl::base_internal::Invoke(absl::forward<Op>(op), NPos());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t... EndIndices>
|
||||
struct VisitIndicesFallback {
|
||||
template <class Op, class... SizeT>
|
||||
static VisitIndicesResultT<Op, SizeT...> Run(Op&& op, SizeT... indices) {
|
||||
return AccessSimpleArray(
|
||||
MakeVisitationMatrix<VisitIndicesResultT<Op, SizeT...>, Op,
|
||||
index_sequence<(EndIndices + 1)...>>::Run(),
|
||||
(indices + 1)...)(absl::forward<Op>(op));
|
||||
}
|
||||
};
|
||||
|
||||
// Take an N-dimensional series of indices and convert them into a single index
|
||||
// without loss of information. The purpose of this is to be able to convert an
|
||||
// N-ary visit operation into a single switch statement.
|
||||
template <std::size_t...>
|
||||
struct FlattenIndices;
|
||||
|
||||
template <std::size_t HeadSize, std::size_t... TailSize>
|
||||
struct FlattenIndices<HeadSize, TailSize...> {
|
||||
template<class... SizeType>
|
||||
static constexpr std::size_t Run(std::size_t head, SizeType... tail) {
|
||||
return head + HeadSize * FlattenIndices<TailSize...>::Run(tail...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct FlattenIndices<> {
|
||||
static constexpr std::size_t Run() { return 0; }
|
||||
};
|
||||
|
||||
// Take a single "flattened" index (flattened by FlattenIndices) and determine
|
||||
// the value of the index of one of the logically represented dimensions.
|
||||
template <std::size_t I, std::size_t IndexToGet, std::size_t HeadSize,
|
||||
std::size_t... TailSize>
|
||||
struct UnflattenIndex {
|
||||
static constexpr std::size_t value =
|
||||
UnflattenIndex<I / HeadSize, IndexToGet - 1, TailSize...>::value;
|
||||
};
|
||||
|
||||
template <std::size_t I, std::size_t HeadSize, std::size_t... TailSize>
|
||||
struct UnflattenIndex<I, 0, HeadSize, TailSize...> {
|
||||
static constexpr std::size_t value = (I % HeadSize);
|
||||
};
|
||||
|
||||
// The backend for converting an N-ary visit operation into a unary visit.
|
||||
template <class IndexSequence, std::size_t... EndIndices>
|
||||
struct VisitIndicesVariadicImpl;
|
||||
|
||||
template <std::size_t... N, std::size_t... EndIndices>
|
||||
struct VisitIndicesVariadicImpl<absl::index_sequence<N...>, EndIndices...> {
|
||||
// A type that can take an N-ary function object and converts it to a unary
|
||||
// function object that takes a single, flattened index, and "unflattens" it
|
||||
// into its individual dimensions when forwarding to the wrapped object.
|
||||
template <class Op>
|
||||
struct FlattenedOp {
|
||||
template <std::size_t I>
|
||||
VisitIndicesResultT<Op, decltype(EndIndices)...> operator()(
|
||||
SizeT<I> /*index*/) && {
|
||||
return base_internal::Invoke(
|
||||
absl::forward<Op>(op),
|
||||
SizeT<UnflattenIndex<I, N, (EndIndices + 1)...>::value -
|
||||
std::size_t{1}>()...);
|
||||
}
|
||||
|
||||
Op&& op;
|
||||
};
|
||||
|
||||
template <class Op, class... SizeType>
|
||||
static VisitIndicesResultT<Op, decltype(EndIndices)...> Run(
|
||||
Op&& op, SizeType... i) {
|
||||
return VisitIndicesSwitch<NumCasesOfSwitch<EndIndices...>::value>::Run(
|
||||
FlattenedOp<Op>{absl::forward<Op>(op)},
|
||||
FlattenIndices<(EndIndices + std::size_t{1})...>::Run(
|
||||
(i + std::size_t{1})...));
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t... EndIndices>
|
||||
struct VisitIndicesVariadic
|
||||
: VisitIndicesVariadicImpl<absl::make_index_sequence<sizeof...(EndIndices)>,
|
||||
EndIndices...> {};
|
||||
|
||||
// This implementation will flatten N-ary visit operations into a single switch
|
||||
// statement when the number of cases would be less than our maximum specified
|
||||
// switch-statement size.
|
||||
// TODO(calabrese)
|
||||
// Based on benchmarks, determine whether the function table approach actually
|
||||
// does optimize better than a chain of switch statements and possibly update
|
||||
// the implementation accordingly. Also consider increasing the maximum switch
|
||||
// size.
|
||||
template <std::size_t... EndIndices>
|
||||
struct VisitIndices
|
||||
: absl::conditional_t<(NumCasesOfSwitch<EndIndices...>::value <=
|
||||
MaxUnrolledVisitCases),
|
||||
VisitIndicesVariadic<EndIndices...>,
|
||||
VisitIndicesFallback<EndIndices...>> {};
|
||||
|
||||
template <std::size_t EndIndex>
|
||||
struct VisitIndices<EndIndex>
|
||||
: absl::conditional_t<(EndIndex <= MaxUnrolledVisitCases),
|
||||
VisitIndicesSwitch<EndIndex>,
|
||||
VisitIndicesFallback<EndIndex>> {};
|
||||
|
||||
// Suppress bogus warning on MSVC: MSVC complains that the `reinterpret_cast`
|
||||
// below is returning the address of a temporary or local object.
|
||||
#ifdef _MSC_VER
|
||||
@ -527,10 +270,8 @@ struct VisitIndices<EndIndex>
|
||||
|
||||
// TODO(calabrese) std::launder
|
||||
// TODO(calabrese) constexpr
|
||||
// NOTE: DO NOT REMOVE the `inline` keyword as it is necessary to work around a
|
||||
// MSVC bug. See https://github.com/abseil/abseil-cpp/issues/129 for details.
|
||||
template <class Self, std::size_t I>
|
||||
inline VariantAccessResult<I, Self> AccessUnion(Self&& self, SizeT<I> /*i*/) {
|
||||
VariantAccessResult<I, Self> AccessUnion(Self&& self, SizeT<I> /*i*/) {
|
||||
return reinterpret_cast<VariantAccessResult<I, Self>>(self);
|
||||
}
|
||||
|
||||
@ -572,7 +313,7 @@ struct VariantCoreAccess {
|
||||
|
||||
template <class Variant>
|
||||
static void InitFrom(Variant& self, Variant&& other) { // NOLINT
|
||||
VisitIndices<absl::variant_size<Variant>::value>::Run(
|
||||
variant_internal::visit_indices<absl::variant_size<Variant>::value>(
|
||||
InitFromVisitor<Variant, Variant&&>{&self,
|
||||
std::forward<Variant>(other)},
|
||||
other.index());
|
||||
@ -1308,7 +1049,9 @@ class VariantStateBaseDestructorNontrivial : protected VariantStateBase<T...> {
|
||||
VariantStateBaseDestructorNontrivial* self;
|
||||
};
|
||||
|
||||
void destroy() { VisitIndices<sizeof...(T)>::Run(Destroyer{this}, index_); }
|
||||
void destroy() {
|
||||
variant_internal::visit_indices<sizeof...(T)>(Destroyer{this}, index_);
|
||||
}
|
||||
|
||||
~VariantStateBaseDestructorNontrivial() { destroy(); }
|
||||
|
||||
@ -1344,7 +1087,8 @@ class VariantMoveBaseNontrivial : protected VariantStateBaseDestructor<T...> {
|
||||
VariantMoveBaseNontrivial(VariantMoveBaseNontrivial&& other) noexcept(
|
||||
absl::conjunction<std::is_nothrow_move_constructible<T>...>::value)
|
||||
: Base(NoopConstructorTag()) {
|
||||
VisitIndices<sizeof...(T)>::Run(Construct{this, &other}, other.index_);
|
||||
variant_internal::visit_indices<sizeof...(T)>(Construct{this, &other},
|
||||
other.index_);
|
||||
index_ = other.index_;
|
||||
}
|
||||
|
||||
@ -1387,7 +1131,8 @@ class VariantCopyBaseNontrivial : protected VariantMoveBase<T...> {
|
||||
|
||||
VariantCopyBaseNontrivial(VariantCopyBaseNontrivial const& other)
|
||||
: Base(NoopConstructorTag()) {
|
||||
VisitIndices<sizeof...(T)>::Run(Construct{this, &other}, other.index_);
|
||||
variant_internal::visit_indices<sizeof...(T)>(Construct{this, &other},
|
||||
other.index_);
|
||||
index_ = other.index_;
|
||||
}
|
||||
|
||||
@ -1421,7 +1166,7 @@ class VariantMoveAssignBaseNontrivial : protected VariantCopyBase<T...> {
|
||||
operator=(VariantMoveAssignBaseNontrivial&& other) noexcept(
|
||||
absl::conjunction<std::is_nothrow_move_constructible<T>...,
|
||||
std::is_nothrow_move_assignable<T>...>::value) {
|
||||
VisitIndices<sizeof...(T)>::Run(
|
||||
variant_internal::visit_indices<sizeof...(T)>(
|
||||
VariantCoreAccess::MakeMoveAssignVisitor(this, &other), other.index_);
|
||||
return *this;
|
||||
}
|
||||
@ -1450,7 +1195,7 @@ class VariantCopyAssignBaseNontrivial : protected VariantMoveAssignBase<T...> {
|
||||
|
||||
VariantCopyAssignBaseNontrivial& operator=(
|
||||
const VariantCopyAssignBaseNontrivial& other) {
|
||||
VisitIndices<sizeof...(T)>::Run(
|
||||
variant_internal::visit_indices<sizeof...(T)>(
|
||||
VariantCoreAccess::MakeCopyAssignVisitor(this, other), other.index_);
|
||||
return *this;
|
||||
}
|
||||
@ -1591,7 +1336,7 @@ struct Swap {
|
||||
template <std::size_t Wi>
|
||||
void operator()(SizeT<Wi> /*w_i*/) {
|
||||
if (v->index() == Wi) {
|
||||
VisitIndices<sizeof...(Types)>::Run(SwapSameIndex<Types...>{v, w}, Wi);
|
||||
visit_indices<sizeof...(Types)>(SwapSameIndex<Types...>{v, w}, Wi);
|
||||
} else {
|
||||
generic_swap();
|
||||
}
|
||||
@ -1625,10 +1370,11 @@ struct VariantHashBase<Variant,
|
||||
if (var.valueless_by_exception()) {
|
||||
return 239799884;
|
||||
}
|
||||
size_t result = VisitIndices<variant_size<Variant>::value>::Run(
|
||||
PerformVisitation<VariantHashVisitor, const Variant&>{
|
||||
std::forward_as_tuple(var), VariantHashVisitor{}},
|
||||
var.index());
|
||||
size_t result =
|
||||
variant_internal::visit_indices<variant_size<Variant>::value>(
|
||||
PerformVisitation<VariantHashVisitor, const Variant&>{
|
||||
std::forward_as_tuple(var), VariantHashVisitor{}},
|
||||
var.index());
|
||||
// Combine the index and the hash result in order to distinguish
|
||||
// std::variant<int, int> holding the same value as different alternative.
|
||||
return result ^ var.index();
|
||||
|
||||
2
third_party/abseil-cpp/absl/types/optional.h
vendored
2
third_party/abseil-cpp/absl/types/optional.h
vendored
@ -48,7 +48,7 @@ using std::optional;
|
||||
using std::make_optional;
|
||||
using std::nullopt_t;
|
||||
using std::nullopt;
|
||||
} // namespace absl
|
||||
}
|
||||
|
||||
#else // ABSL_HAVE_STD_OPTIONAL
|
||||
|
||||
|
||||
28
third_party/abseil-cpp/absl/types/variant.h
vendored
28
third_party/abseil-cpp/absl/types/variant.h
vendored
@ -416,12 +416,12 @@ constexpr absl::add_pointer_t<const T> get_if(
|
||||
template <typename Visitor, typename... Variants>
|
||||
variant_internal::VisitResult<Visitor, Variants...> visit(Visitor&& vis,
|
||||
Variants&&... vars) {
|
||||
return variant_internal::
|
||||
VisitIndices<variant_size<absl::decay_t<Variants> >::value...>::Run(
|
||||
variant_internal::PerformVisitation<Visitor, Variants...>{
|
||||
std::forward_as_tuple(absl::forward<Variants>(vars)...),
|
||||
absl::forward<Visitor>(vis)},
|
||||
vars.index()...);
|
||||
return variant_internal::visit_indices<
|
||||
variant_size<absl::decay_t<Variants>>::value...>(
|
||||
variant_internal::PerformVisitation<Visitor, Variants...>{
|
||||
std::forward_as_tuple(absl::forward<Variants>(vars)...),
|
||||
absl::forward<Visitor>(vis)},
|
||||
vars.index()...);
|
||||
}
|
||||
|
||||
// monostate
|
||||
@ -573,7 +573,7 @@ class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
|
||||
variant& operator=(T&& t) noexcept(
|
||||
std::is_nothrow_assignable<Tj&, T>::value&&
|
||||
std::is_nothrow_constructible<Tj, T>::value) {
|
||||
variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
|
||||
variant_internal::visit_indices<sizeof...(Tn) + 1>(
|
||||
variant_internal::VariantCoreAccess::MakeConversionAssignVisitor(
|
||||
this, absl::forward<T>(t)),
|
||||
index());
|
||||
@ -682,7 +682,7 @@ class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
|
||||
// true and `is_nothrow_swappable()` is same as `std::is_trivial()`.
|
||||
void swap(variant& rhs) noexcept(
|
||||
absl::conjunction<std::is_trivial<T0>, std::is_trivial<Tn>...>::value) {
|
||||
return variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
|
||||
return variant_internal::visit_indices<sizeof...(Tn) + 1>(
|
||||
variant_internal::Swap<T0, Tn...>{this, &rhs}, rhs.index());
|
||||
}
|
||||
};
|
||||
@ -722,7 +722,7 @@ template <typename... Types>
|
||||
constexpr variant_internal::RequireAllHaveEqualT<Types...> operator==(
|
||||
const variant<Types...>& a, const variant<Types...>& b) {
|
||||
return (a.index() == b.index()) &&
|
||||
variant_internal::VisitIndices<sizeof...(Types)>::Run(
|
||||
variant_internal::visit_indices<sizeof...(Types)>(
|
||||
variant_internal::EqualsOp<Types...>{&a, &b}, a.index());
|
||||
}
|
||||
|
||||
@ -731,7 +731,7 @@ template <typename... Types>
|
||||
constexpr variant_internal::RequireAllHaveNotEqualT<Types...> operator!=(
|
||||
const variant<Types...>& a, const variant<Types...>& b) {
|
||||
return (a.index() != b.index()) ||
|
||||
variant_internal::VisitIndices<sizeof...(Types)>::Run(
|
||||
variant_internal::visit_indices<sizeof...(Types)>(
|
||||
variant_internal::NotEqualsOp<Types...>{&a, &b}, a.index());
|
||||
}
|
||||
|
||||
@ -741,7 +741,7 @@ constexpr variant_internal::RequireAllHaveLessThanT<Types...> operator<(
|
||||
const variant<Types...>& a, const variant<Types...>& b) {
|
||||
return (a.index() != b.index())
|
||||
? (a.index() + 1) < (b.index() + 1)
|
||||
: variant_internal::VisitIndices<sizeof...(Types)>::Run(
|
||||
: variant_internal::visit_indices<sizeof...(Types)>(
|
||||
variant_internal::LessThanOp<Types...>{&a, &b}, a.index());
|
||||
}
|
||||
|
||||
@ -751,7 +751,7 @@ constexpr variant_internal::RequireAllHaveGreaterThanT<Types...> operator>(
|
||||
const variant<Types...>& a, const variant<Types...>& b) {
|
||||
return (a.index() != b.index())
|
||||
? (a.index() + 1) > (b.index() + 1)
|
||||
: variant_internal::VisitIndices<sizeof...(Types)>::Run(
|
||||
: variant_internal::visit_indices<sizeof...(Types)>(
|
||||
variant_internal::GreaterThanOp<Types...>{&a, &b},
|
||||
a.index());
|
||||
}
|
||||
@ -762,7 +762,7 @@ constexpr variant_internal::RequireAllHaveLessThanOrEqualT<Types...> operator<=(
|
||||
const variant<Types...>& a, const variant<Types...>& b) {
|
||||
return (a.index() != b.index())
|
||||
? (a.index() + 1) < (b.index() + 1)
|
||||
: variant_internal::VisitIndices<sizeof...(Types)>::Run(
|
||||
: variant_internal::visit_indices<sizeof...(Types)>(
|
||||
variant_internal::LessThanOrEqualsOp<Types...>{&a, &b},
|
||||
a.index());
|
||||
}
|
||||
@ -773,7 +773,7 @@ constexpr variant_internal::RequireAllHaveGreaterThanOrEqualT<Types...>
|
||||
operator>=(const variant<Types...>& a, const variant<Types...>& b) {
|
||||
return (a.index() != b.index())
|
||||
? (a.index() + 1) > (b.index() + 1)
|
||||
: variant_internal::VisitIndices<sizeof...(Types)>::Run(
|
||||
: variant_internal::visit_indices<sizeof...(Types)>(
|
||||
variant_internal::GreaterThanOrEqualsOp<Types...>{&a, &b},
|
||||
a.index());
|
||||
}
|
||||
|
||||
@ -1,220 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// Unit tests for the variant template. The 'is' and 'IsEmpty' methods
|
||||
// of variant are not explicitly tested because they are used repeatedly
|
||||
// in building other tests. All other public variant methods should have
|
||||
// explicit tests.
|
||||
|
||||
#include "absl/types/variant.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "absl/utility/utility.h"
|
||||
|
||||
namespace absl {
|
||||
namespace {
|
||||
|
||||
template <std::size_t I>
|
||||
struct VariantAlternative {
|
||||
char member;
|
||||
};
|
||||
|
||||
template <class Indices>
|
||||
struct VariantOfAlternativesImpl;
|
||||
|
||||
template <std::size_t... Indices>
|
||||
struct VariantOfAlternativesImpl<absl::index_sequence<Indices...>> {
|
||||
using type = absl::variant<VariantAlternative<Indices>...>;
|
||||
};
|
||||
|
||||
template <std::size_t NumAlternatives>
|
||||
using VariantOfAlternatives = typename VariantOfAlternativesImpl<
|
||||
absl::make_index_sequence<NumAlternatives>>::type;
|
||||
|
||||
struct Empty {};
|
||||
|
||||
template <class... T>
|
||||
void Ignore(T...) noexcept {}
|
||||
|
||||
template <class T>
|
||||
Empty DoNotOptimizeAndReturnEmpty(T&& arg) noexcept {
|
||||
benchmark::DoNotOptimize(arg);
|
||||
return {};
|
||||
}
|
||||
|
||||
struct VisitorApplier {
|
||||
struct Visitor {
|
||||
template <class... T>
|
||||
void operator()(T&&... args) const noexcept {
|
||||
Ignore(DoNotOptimizeAndReturnEmpty(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <class... Vars>
|
||||
void operator()(const Vars&... vars) const noexcept {
|
||||
absl::visit(Visitor(), vars...);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t NumIndices, std::size_t CurrIndex = NumIndices - 1>
|
||||
struct MakeWithIndex {
|
||||
using Variant = VariantOfAlternatives<NumIndices>;
|
||||
|
||||
static Variant Run(std::size_t index) {
|
||||
return index == CurrIndex
|
||||
? Variant(absl::in_place_index_t<CurrIndex>())
|
||||
: MakeWithIndex<NumIndices, CurrIndex - 1>::Run(index);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t NumIndices>
|
||||
struct MakeWithIndex<NumIndices, 0> {
|
||||
using Variant = VariantOfAlternatives<NumIndices>;
|
||||
|
||||
static Variant Run(std::size_t /*index*/) { return Variant(); }
|
||||
};
|
||||
|
||||
template <std::size_t NumIndices, class Dimensions>
|
||||
struct MakeVariantTuple;
|
||||
|
||||
template <class T, std::size_t /*I*/>
|
||||
using always_t = T;
|
||||
|
||||
template <std::size_t NumIndices>
|
||||
VariantOfAlternatives<NumIndices> MakeVariant(std::size_t dimension,
|
||||
std::size_t index) {
|
||||
return dimension == 0
|
||||
? MakeWithIndex<NumIndices>::Run(index % NumIndices)
|
||||
: MakeVariant<NumIndices>(dimension - 1, index / NumIndices);
|
||||
}
|
||||
|
||||
template <std::size_t NumIndices, std::size_t... Dimensions>
|
||||
struct MakeVariantTuple<NumIndices, absl::index_sequence<Dimensions...>> {
|
||||
using VariantTuple =
|
||||
std::tuple<always_t<VariantOfAlternatives<NumIndices>, Dimensions>...>;
|
||||
|
||||
static VariantTuple Run(int index) {
|
||||
return std::make_tuple(MakeVariant<NumIndices>(Dimensions, index)...);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr std::size_t integral_pow(std::size_t base, std::size_t power) {
|
||||
return power == 0 ? 1 : base * integral_pow(base, power - 1);
|
||||
}
|
||||
|
||||
template <std::size_t End, std::size_t I = 0>
|
||||
struct VisitTestBody {
|
||||
template <class Vars, class State>
|
||||
static bool Run(Vars& vars, State& state) {
|
||||
if (state.KeepRunning()) {
|
||||
absl::apply(VisitorApplier(), vars[I]);
|
||||
return VisitTestBody<End, I + 1>::Run(vars, state);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t End>
|
||||
struct VisitTestBody<End, End> {
|
||||
template <class Vars, class State>
|
||||
static bool Run(Vars& /*vars*/, State& /*state*/) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Visit operations where branch prediction is likely to give a boost.
|
||||
template <std::size_t NumIndices, std::size_t NumDimensions = 1>
|
||||
void BM_RedundantVisit(benchmark::State& state) {
|
||||
auto vars =
|
||||
MakeVariantTuple<NumIndices, absl::make_index_sequence<NumDimensions>>::
|
||||
Run(static_cast<std::size_t>(state.range(0)));
|
||||
|
||||
for (auto _ : state) { // NOLINT
|
||||
benchmark::DoNotOptimize(vars);
|
||||
absl::apply(VisitorApplier(), vars);
|
||||
}
|
||||
}
|
||||
|
||||
// Visit operations where branch prediction is unlikely to give a boost.
|
||||
template <std::size_t NumIndices, std::size_t NumDimensions = 1>
|
||||
void BM_Visit(benchmark::State& state) {
|
||||
constexpr std::size_t num_possibilities =
|
||||
integral_pow(NumIndices, NumDimensions);
|
||||
|
||||
using VariantTupleMaker =
|
||||
MakeVariantTuple<NumIndices, absl::make_index_sequence<NumDimensions>>;
|
||||
using Tuple = typename VariantTupleMaker::VariantTuple;
|
||||
|
||||
Tuple vars[num_possibilities];
|
||||
for (std::size_t i = 0; i < num_possibilities; ++i)
|
||||
vars[i] = VariantTupleMaker::Run(i);
|
||||
|
||||
while (VisitTestBody<num_possibilities>::Run(vars, state)) {
|
||||
}
|
||||
}
|
||||
|
||||
// Visitation
|
||||
// Each visit is on a different variant with a different active alternative)
|
||||
|
||||
// Unary visit
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 4);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 5);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 6);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 7);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 8);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 16);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 32);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 64);
|
||||
|
||||
// Binary visit
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 2);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 2);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 2);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 4, 2);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 5, 2);
|
||||
|
||||
// Ternary visit
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 3);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 3);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 3);
|
||||
|
||||
// Quaternary visit
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 4);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 4);
|
||||
|
||||
// Redundant Visitation
|
||||
// Each visit consistently has the same alternative active
|
||||
|
||||
// Unary visit
|
||||
BENCHMARK_TEMPLATE(BM_RedundantVisit, 1)->Arg(0);
|
||||
BENCHMARK_TEMPLATE(BM_RedundantVisit, 2)->DenseRange(0, 1);
|
||||
BENCHMARK_TEMPLATE(BM_RedundantVisit, 8)->DenseRange(0, 7);
|
||||
|
||||
// Binary visit
|
||||
BENCHMARK_TEMPLATE(BM_RedundantVisit, 1, 2)->Arg(0);
|
||||
BENCHMARK_TEMPLATE(BM_RedundantVisit, 2, 2)
|
||||
->DenseRange(0, integral_pow(2, 2) - 1);
|
||||
BENCHMARK_TEMPLATE(BM_RedundantVisit, 4, 2)
|
||||
->DenseRange(0, integral_pow(4, 2) - 1);
|
||||
|
||||
} // namespace
|
||||
} // namespace absl
|
||||
@ -21,6 +21,7 @@ chrome.bluetoothPrivate = {};
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#type-PairingEventType
|
||||
*/
|
||||
chrome.bluetoothPrivate.PairingEventType = {
|
||||
REQUEST_PINCODE: 'requestPincode',
|
||||
@ -35,6 +36,7 @@ chrome.bluetoothPrivate.PairingEventType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#type-ConnectResultType
|
||||
*/
|
||||
chrome.bluetoothPrivate.ConnectResultType = {
|
||||
ALREADY_CONNECTED: 'alreadyConnected',
|
||||
@ -51,6 +53,7 @@ chrome.bluetoothPrivate.ConnectResultType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#type-PairingResponse
|
||||
*/
|
||||
chrome.bluetoothPrivate.PairingResponse = {
|
||||
CONFIRM: 'confirm',
|
||||
@ -60,6 +63,7 @@ chrome.bluetoothPrivate.PairingResponse = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#type-TransportType
|
||||
*/
|
||||
chrome.bluetoothPrivate.TransportType = {
|
||||
LE: 'le',
|
||||
@ -75,6 +79,7 @@ chrome.bluetoothPrivate.TransportType = {
|
||||
* passkey: (number|undefined),
|
||||
* enteredKey: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#type-PairingEvent
|
||||
*/
|
||||
chrome.bluetoothPrivate.PairingEvent;
|
||||
|
||||
@ -84,6 +89,7 @@ chrome.bluetoothPrivate.PairingEvent;
|
||||
* powered: (boolean|undefined),
|
||||
* discoverable: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#type-NewAdapterState
|
||||
*/
|
||||
chrome.bluetoothPrivate.NewAdapterState;
|
||||
|
||||
@ -94,6 +100,7 @@ chrome.bluetoothPrivate.NewAdapterState;
|
||||
* pincode: (string|undefined),
|
||||
* passkey: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#type-SetPairingResponseOptions
|
||||
*/
|
||||
chrome.bluetoothPrivate.SetPairingResponseOptions;
|
||||
|
||||
@ -104,6 +111,7 @@ chrome.bluetoothPrivate.SetPairingResponseOptions;
|
||||
* rssi: (number|undefined),
|
||||
* pathloss: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#type-DiscoveryFilter
|
||||
*/
|
||||
chrome.bluetoothPrivate.DiscoveryFilter;
|
||||
|
||||
@ -111,12 +119,14 @@ chrome.bluetoothPrivate.DiscoveryFilter;
|
||||
* Changes the state of the Bluetooth adapter.
|
||||
* @param {!chrome.bluetoothPrivate.NewAdapterState} adapterState
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#method-setAdapterState
|
||||
*/
|
||||
chrome.bluetoothPrivate.setAdapterState = function(adapterState, callback) {};
|
||||
|
||||
/**
|
||||
* @param {!chrome.bluetoothPrivate.SetPairingResponseOptions} options
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#method-setPairingResponse
|
||||
*/
|
||||
chrome.bluetoothPrivate.setPairingResponse = function(options, callback) {};
|
||||
|
||||
@ -124,6 +134,7 @@ chrome.bluetoothPrivate.setPairingResponse = function(options, callback) {};
|
||||
* Tears down all connections to the given device.
|
||||
* @param {string} deviceAddress
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#method-disconnectAll
|
||||
*/
|
||||
chrome.bluetoothPrivate.disconnectAll = function(deviceAddress, callback) {};
|
||||
|
||||
@ -131,6 +142,7 @@ chrome.bluetoothPrivate.disconnectAll = function(deviceAddress, callback) {};
|
||||
* Forgets the given device.
|
||||
* @param {string} deviceAddress
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#method-forgetDevice
|
||||
*/
|
||||
chrome.bluetoothPrivate.forgetDevice = function(deviceAddress, callback) {};
|
||||
|
||||
@ -138,6 +150,7 @@ chrome.bluetoothPrivate.forgetDevice = function(deviceAddress, callback) {};
|
||||
* Set or clear discovery filter.
|
||||
* @param {!chrome.bluetoothPrivate.DiscoveryFilter} discoveryFilter
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#method-setDiscoveryFilter
|
||||
*/
|
||||
chrome.bluetoothPrivate.setDiscoveryFilter = function(discoveryFilter, callback) {};
|
||||
|
||||
@ -147,6 +160,7 @@ chrome.bluetoothPrivate.setDiscoveryFilter = function(discoveryFilter, callback)
|
||||
* succeed and invoke |callback| with ConnectResultType.
|
||||
* @param {string} deviceAddress
|
||||
* @param {function(!chrome.bluetoothPrivate.ConnectResultType):void=} callback
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#method-connect
|
||||
*/
|
||||
chrome.bluetoothPrivate.connect = function(deviceAddress, callback) {};
|
||||
|
||||
@ -154,11 +168,13 @@ chrome.bluetoothPrivate.connect = function(deviceAddress, callback) {};
|
||||
* Pairs the given device.
|
||||
* @param {string} deviceAddress
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#method-pair
|
||||
*/
|
||||
chrome.bluetoothPrivate.pair = function(deviceAddress, callback) {};
|
||||
|
||||
/**
|
||||
* Fired when a pairing event occurs.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/bluetoothPrivate#event-onPairing
|
||||
*/
|
||||
chrome.bluetoothPrivate.onPairing;
|
||||
|
||||
@ -18,6 +18,7 @@ chrome.developerPrivate = {};
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ItemType
|
||||
*/
|
||||
chrome.developerPrivate.ItemType = {
|
||||
HOSTED_APP: 'hosted_app',
|
||||
@ -35,6 +36,7 @@ chrome.developerPrivate.ItemType = {
|
||||
* incognito: boolean,
|
||||
* generatedBackgroundPage: boolean
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ItemInspectView
|
||||
*/
|
||||
chrome.developerPrivate.ItemInspectView;
|
||||
|
||||
@ -45,6 +47,7 @@ chrome.developerPrivate.ItemInspectView;
|
||||
* render_view_id: (string|number),
|
||||
* incognito: boolean
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-InspectOptions
|
||||
*/
|
||||
chrome.developerPrivate.InspectOptions;
|
||||
|
||||
@ -52,11 +55,13 @@ chrome.developerPrivate.InspectOptions;
|
||||
* @typedef {{
|
||||
* message: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-InstallWarning
|
||||
*/
|
||||
chrome.developerPrivate.InstallWarning;
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionType
|
||||
*/
|
||||
chrome.developerPrivate.ExtensionType = {
|
||||
HOSTED_APP: 'HOSTED_APP',
|
||||
@ -69,6 +74,7 @@ chrome.developerPrivate.ExtensionType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-Location
|
||||
*/
|
||||
chrome.developerPrivate.Location = {
|
||||
FROM_STORE: 'FROM_STORE',
|
||||
@ -79,6 +85,7 @@ chrome.developerPrivate.Location = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ViewType
|
||||
*/
|
||||
chrome.developerPrivate.ViewType = {
|
||||
APP_WINDOW: 'APP_WINDOW',
|
||||
@ -93,6 +100,7 @@ chrome.developerPrivate.ViewType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ErrorType
|
||||
*/
|
||||
chrome.developerPrivate.ErrorType = {
|
||||
MANIFEST: 'MANIFEST',
|
||||
@ -101,6 +109,7 @@ chrome.developerPrivate.ErrorType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ErrorLevel
|
||||
*/
|
||||
chrome.developerPrivate.ErrorLevel = {
|
||||
LOG: 'LOG',
|
||||
@ -110,6 +119,7 @@ chrome.developerPrivate.ErrorLevel = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionState
|
||||
*/
|
||||
chrome.developerPrivate.ExtensionState = {
|
||||
ENABLED: 'ENABLED',
|
||||
@ -120,6 +130,7 @@ chrome.developerPrivate.ExtensionState = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-CommandScope
|
||||
*/
|
||||
chrome.developerPrivate.CommandScope = {
|
||||
GLOBAL: 'GLOBAL',
|
||||
@ -131,6 +142,7 @@ chrome.developerPrivate.CommandScope = {
|
||||
* isEnabled: boolean,
|
||||
* isActive: boolean
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-AccessModifier
|
||||
*/
|
||||
chrome.developerPrivate.AccessModifier;
|
||||
|
||||
@ -141,6 +153,7 @@ chrome.developerPrivate.AccessModifier;
|
||||
* url: string,
|
||||
* functionName: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-StackFrame
|
||||
*/
|
||||
chrome.developerPrivate.StackFrame;
|
||||
|
||||
@ -155,6 +168,7 @@ chrome.developerPrivate.StackFrame;
|
||||
* manifestKey: string,
|
||||
* manifestSpecific: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ManifestError
|
||||
*/
|
||||
chrome.developerPrivate.ManifestError;
|
||||
|
||||
@ -174,6 +188,7 @@ chrome.developerPrivate.ManifestError;
|
||||
* canInspect: boolean,
|
||||
* stackTrace: !Array<!chrome.developerPrivate.StackFrame>
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-RuntimeError
|
||||
*/
|
||||
chrome.developerPrivate.RuntimeError;
|
||||
|
||||
@ -183,6 +198,7 @@ chrome.developerPrivate.RuntimeError;
|
||||
* corruptInstall: boolean,
|
||||
* updateRequired: boolean
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-DisableReasons
|
||||
*/
|
||||
chrome.developerPrivate.DisableReasons;
|
||||
|
||||
@ -191,6 +207,7 @@ chrome.developerPrivate.DisableReasons;
|
||||
* openInTab: boolean,
|
||||
* url: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-OptionsPage
|
||||
*/
|
||||
chrome.developerPrivate.OptionsPage;
|
||||
|
||||
@ -199,6 +216,7 @@ chrome.developerPrivate.OptionsPage;
|
||||
* url: string,
|
||||
* specified: boolean
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-HomePage
|
||||
*/
|
||||
chrome.developerPrivate.HomePage;
|
||||
|
||||
@ -211,11 +229,13 @@ chrome.developerPrivate.HomePage;
|
||||
* isIframe: boolean,
|
||||
* type: !chrome.developerPrivate.ViewType
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionView
|
||||
*/
|
||||
chrome.developerPrivate.ExtensionView;
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ControllerType
|
||||
*/
|
||||
chrome.developerPrivate.ControllerType = {
|
||||
POLICY: 'POLICY',
|
||||
@ -228,6 +248,7 @@ chrome.developerPrivate.ControllerType = {
|
||||
* type: !chrome.developerPrivate.ControllerType,
|
||||
* text: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ControlledInfo
|
||||
*/
|
||||
chrome.developerPrivate.ControlledInfo;
|
||||
|
||||
@ -240,6 +261,7 @@ chrome.developerPrivate.ControlledInfo;
|
||||
* scope: !chrome.developerPrivate.CommandScope,
|
||||
* isExtensionAction: boolean
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-Command
|
||||
*/
|
||||
chrome.developerPrivate.Command;
|
||||
|
||||
@ -248,6 +270,7 @@ chrome.developerPrivate.Command;
|
||||
* id: string,
|
||||
* name: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-DependentExtension
|
||||
*/
|
||||
chrome.developerPrivate.DependentExtension;
|
||||
|
||||
@ -256,6 +279,7 @@ chrome.developerPrivate.DependentExtension;
|
||||
* message: string,
|
||||
* submessages: !Array<string>
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-Permission
|
||||
*/
|
||||
chrome.developerPrivate.Permission;
|
||||
|
||||
@ -297,6 +321,7 @@ chrome.developerPrivate.Permission;
|
||||
* views: !Array<!chrome.developerPrivate.ExtensionView>,
|
||||
* webStoreUrl: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionInfo
|
||||
*/
|
||||
chrome.developerPrivate.ExtensionInfo;
|
||||
|
||||
@ -309,6 +334,7 @@ chrome.developerPrivate.ExtensionInfo;
|
||||
* isIncognitoAvailable: boolean,
|
||||
* isSupervised: boolean
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ProfileInfo
|
||||
*/
|
||||
chrome.developerPrivate.ProfileInfo;
|
||||
|
||||
@ -342,6 +368,7 @@ chrome.developerPrivate.ProfileInfo;
|
||||
* offline_enabled: boolean,
|
||||
* views: !Array<!chrome.developerPrivate.ItemInspectView>
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ItemInfo
|
||||
*/
|
||||
chrome.developerPrivate.ItemInfo;
|
||||
|
||||
@ -350,6 +377,7 @@ chrome.developerPrivate.ItemInfo;
|
||||
* includeDisabled: (boolean|undefined),
|
||||
* includeTerminated: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-GetExtensionsInfoOptions
|
||||
*/
|
||||
chrome.developerPrivate.GetExtensionsInfoOptions;
|
||||
|
||||
@ -361,6 +389,7 @@ chrome.developerPrivate.GetExtensionsInfoOptions;
|
||||
* errorCollection: (boolean|undefined),
|
||||
* runOnAllUrls: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionConfigurationUpdate
|
||||
*/
|
||||
chrome.developerPrivate.ExtensionConfigurationUpdate;
|
||||
|
||||
@ -368,6 +397,7 @@ chrome.developerPrivate.ExtensionConfigurationUpdate;
|
||||
* @typedef {{
|
||||
* inDeveloperMode: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ProfileConfigurationUpdate
|
||||
*/
|
||||
chrome.developerPrivate.ProfileConfigurationUpdate;
|
||||
|
||||
@ -378,6 +408,7 @@ chrome.developerPrivate.ProfileConfigurationUpdate;
|
||||
* scope: (!chrome.developerPrivate.CommandScope|undefined),
|
||||
* keybinding: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionCommandUpdate
|
||||
*/
|
||||
chrome.developerPrivate.ExtensionCommandUpdate;
|
||||
|
||||
@ -386,6 +417,7 @@ chrome.developerPrivate.ExtensionCommandUpdate;
|
||||
* failQuietly: (boolean|undefined),
|
||||
* populateErrorForUnpacked: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ReloadOptions
|
||||
*/
|
||||
chrome.developerPrivate.ReloadOptions;
|
||||
|
||||
@ -396,11 +428,13 @@ chrome.developerPrivate.ReloadOptions;
|
||||
* retryGuid: (string|undefined),
|
||||
* useDraggedPath: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-LoadUnpackedOptions
|
||||
*/
|
||||
chrome.developerPrivate.LoadUnpackedOptions;
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-PackStatus
|
||||
*/
|
||||
chrome.developerPrivate.PackStatus = {
|
||||
SUCCESS: 'SUCCESS',
|
||||
@ -410,6 +444,7 @@ chrome.developerPrivate.PackStatus = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-FileType
|
||||
*/
|
||||
chrome.developerPrivate.FileType = {
|
||||
LOAD: 'LOAD',
|
||||
@ -418,6 +453,7 @@ chrome.developerPrivate.FileType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-SelectType
|
||||
*/
|
||||
chrome.developerPrivate.SelectType = {
|
||||
FILE: 'FILE',
|
||||
@ -426,6 +462,7 @@ chrome.developerPrivate.SelectType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-EventType
|
||||
*/
|
||||
chrome.developerPrivate.EventType = {
|
||||
INSTALLED: 'INSTALLED',
|
||||
@ -450,6 +487,7 @@ chrome.developerPrivate.EventType = {
|
||||
* override_flags: number,
|
||||
* status: !chrome.developerPrivate.PackStatus
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-PackDirectoryResponse
|
||||
*/
|
||||
chrome.developerPrivate.PackDirectoryResponse;
|
||||
|
||||
@ -457,6 +495,7 @@ chrome.developerPrivate.PackDirectoryResponse;
|
||||
* @typedef {{
|
||||
* name: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ProjectInfo
|
||||
*/
|
||||
chrome.developerPrivate.ProjectInfo;
|
||||
|
||||
@ -466,6 +505,7 @@ chrome.developerPrivate.ProjectInfo;
|
||||
* item_id: string,
|
||||
* extensionInfo: (!chrome.developerPrivate.ExtensionInfo|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-EventData
|
||||
*/
|
||||
chrome.developerPrivate.EventData;
|
||||
|
||||
@ -475,6 +515,7 @@ chrome.developerPrivate.EventData;
|
||||
* highlight: string,
|
||||
* afterHighlight: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-ErrorFileSource
|
||||
*/
|
||||
chrome.developerPrivate.ErrorFileSource;
|
||||
|
||||
@ -485,6 +526,7 @@ chrome.developerPrivate.ErrorFileSource;
|
||||
* source: (!chrome.developerPrivate.ErrorFileSource|undefined),
|
||||
* retryGuid: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-LoadError
|
||||
*/
|
||||
chrome.developerPrivate.LoadError;
|
||||
|
||||
@ -497,6 +539,7 @@ chrome.developerPrivate.LoadError;
|
||||
* manifestSpecific: (string|undefined),
|
||||
* lineNumber: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-RequestFileSourceProperties
|
||||
*/
|
||||
chrome.developerPrivate.RequestFileSourceProperties;
|
||||
|
||||
@ -508,6 +551,7 @@ chrome.developerPrivate.RequestFileSourceProperties;
|
||||
* title: string,
|
||||
* message: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-RequestFileSourceResponse
|
||||
*/
|
||||
chrome.developerPrivate.RequestFileSourceResponse;
|
||||
|
||||
@ -521,6 +565,7 @@ chrome.developerPrivate.RequestFileSourceResponse;
|
||||
* lineNumber: (number|undefined),
|
||||
* columnNumber: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-OpenDevToolsProperties
|
||||
*/
|
||||
chrome.developerPrivate.OpenDevToolsProperties;
|
||||
|
||||
@ -530,12 +575,14 @@ chrome.developerPrivate.OpenDevToolsProperties;
|
||||
* errorIds: (!Array<number>|undefined),
|
||||
* type: (!chrome.developerPrivate.ErrorType|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#type-DeleteExtensionErrorsProperties
|
||||
*/
|
||||
chrome.developerPrivate.DeleteExtensionErrorsProperties;
|
||||
|
||||
/**
|
||||
* Runs auto update for extensions and apps immediately.
|
||||
* @param {function():void=} callback Called after update check completes.
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-autoUpdate
|
||||
*/
|
||||
chrome.developerPrivate.autoUpdate = function(callback) {};
|
||||
|
||||
@ -545,6 +592,7 @@ chrome.developerPrivate.autoUpdate = function(callback) {};
|
||||
* to restrict the items returned.
|
||||
* @param {function(!Array<!chrome.developerPrivate.ExtensionInfo>):void=}
|
||||
* callback Called with extensions info.
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-getExtensionsInfo
|
||||
*/
|
||||
chrome.developerPrivate.getExtensionsInfo = function(options, callback) {};
|
||||
|
||||
@ -553,6 +601,7 @@ chrome.developerPrivate.getExtensionsInfo = function(options, callback) {};
|
||||
* @param {string} id The id of the extension.
|
||||
* @param {function(!chrome.developerPrivate.ExtensionInfo):void=} callback
|
||||
* Called with the result.
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-getExtensionInfo
|
||||
*/
|
||||
chrome.developerPrivate.getExtensionInfo = function(id, callback) {};
|
||||
|
||||
@ -560,6 +609,7 @@ chrome.developerPrivate.getExtensionInfo = function(id, callback) {};
|
||||
* Returns the size of a particular extension on disk (already formatted).
|
||||
* @param {string} id The id of the extension.
|
||||
* @param {function(string):void} callback Called with the result.
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-getExtensionSize
|
||||
*/
|
||||
chrome.developerPrivate.getExtensionSize = function(id, callback) {};
|
||||
|
||||
@ -570,12 +620,14 @@ chrome.developerPrivate.getExtensionSize = function(id, callback) {};
|
||||
* @param {function(!Array<!chrome.developerPrivate.ItemInfo>):void} callback
|
||||
* Called with items info.
|
||||
* @deprecated Use getExtensionsInfo
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-getItemsInfo
|
||||
*/
|
||||
chrome.developerPrivate.getItemsInfo = function(includeDisabled, includeTerminated, callback) {};
|
||||
|
||||
/**
|
||||
* Returns the current profile's configuration.
|
||||
* @param {function(!chrome.developerPrivate.ProfileInfo):void} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-getProfileConfiguration
|
||||
*/
|
||||
chrome.developerPrivate.getProfileConfiguration = function(callback) {};
|
||||
|
||||
@ -585,6 +637,7 @@ chrome.developerPrivate.getProfileConfiguration = function(callback) {};
|
||||
* parameters for updating the profile's configuration. Any properties
|
||||
* omitted from |update| will not be changed.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-updateProfileConfiguration
|
||||
*/
|
||||
chrome.developerPrivate.updateProfileConfiguration = function(update, callback) {};
|
||||
|
||||
@ -592,6 +645,7 @@ chrome.developerPrivate.updateProfileConfiguration = function(update, callback)
|
||||
* Opens a permissions dialog.
|
||||
* @param {string} extensionId The id of the extension to show permissions for.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-showPermissionsDialog
|
||||
*/
|
||||
chrome.developerPrivate.showPermissionsDialog = function(extensionId, callback) {};
|
||||
|
||||
@ -602,6 +656,7 @@ chrome.developerPrivate.showPermissionsDialog = function(extensionId, callback)
|
||||
* configuration parameters.
|
||||
* @param {function((!chrome.developerPrivate.LoadError|undefined)):void=}
|
||||
* callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-reload
|
||||
*/
|
||||
chrome.developerPrivate.reload = function(extensionId, options, callback) {};
|
||||
|
||||
@ -611,6 +666,7 @@ chrome.developerPrivate.reload = function(extensionId, options, callback) {};
|
||||
* parameters for updating the extension's configuration. Any properties
|
||||
* omitted from |update| will not be changed.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-updateExtensionConfiguration
|
||||
*/
|
||||
chrome.developerPrivate.updateExtensionConfiguration = function(update, callback) {};
|
||||
|
||||
@ -620,18 +676,21 @@ chrome.developerPrivate.updateExtensionConfiguration = function(update, callback
|
||||
* configuration parameters.
|
||||
* @param {function((!chrome.developerPrivate.LoadError|undefined)):void=}
|
||||
* callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-loadUnpacked
|
||||
*/
|
||||
chrome.developerPrivate.loadUnpacked = function(options, callback) {};
|
||||
|
||||
/**
|
||||
* Installs the file that was dragged and dropped onto the associated page.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-installDroppedFile
|
||||
*/
|
||||
chrome.developerPrivate.installDroppedFile = function(callback) {};
|
||||
|
||||
/**
|
||||
* Notifies the browser that a user began a drag in order to install an
|
||||
* extension.
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-notifyDragInstallInProgress
|
||||
*/
|
||||
chrome.developerPrivate.notifyDragInstallInProgress = function() {};
|
||||
|
||||
@ -639,6 +698,7 @@ chrome.developerPrivate.notifyDragInstallInProgress = function() {};
|
||||
* Loads an extension / app.
|
||||
* @param {Object} directory The directory to load the extension from.
|
||||
* @param {function(string):void} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-loadDirectory
|
||||
*/
|
||||
chrome.developerPrivate.loadDirectory = function(directory, callback) {};
|
||||
|
||||
@ -650,6 +710,7 @@ chrome.developerPrivate.loadDirectory = function(directory, callback) {};
|
||||
* example, pem type is for private key and load type is for an unpacked
|
||||
* item.
|
||||
* @param {function(string):void} callback called with selected item's path.
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-choosePath
|
||||
*/
|
||||
chrome.developerPrivate.choosePath = function(selectType, fileType, callback) {};
|
||||
|
||||
@ -660,12 +721,14 @@ chrome.developerPrivate.choosePath = function(selectType, fileType, callback) {}
|
||||
* @param {number=} flags Special flags to apply to the loading process, if any.
|
||||
* @param {function(!chrome.developerPrivate.PackDirectoryResponse):void=}
|
||||
* callback called with the success result string.
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-packDirectory
|
||||
*/
|
||||
chrome.developerPrivate.packDirectory = function(path, privateKeyPath, flags, callback) {};
|
||||
|
||||
/**
|
||||
* Returns true if the profile is managed.
|
||||
* @param {function(boolean):void} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-isProfileManaged
|
||||
*/
|
||||
chrome.developerPrivate.isProfileManaged = function(callback) {};
|
||||
|
||||
@ -675,6 +738,7 @@ chrome.developerPrivate.isProfileManaged = function(callback) {};
|
||||
* @param {!chrome.developerPrivate.RequestFileSourceProperties} properties
|
||||
* @param {function(!chrome.developerPrivate.RequestFileSourceResponse):void}
|
||||
* callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-requestFileSource
|
||||
*/
|
||||
chrome.developerPrivate.requestFileSource = function(properties, callback) {};
|
||||
|
||||
@ -682,6 +746,7 @@ chrome.developerPrivate.requestFileSource = function(properties, callback) {};
|
||||
* Open the developer tools to focus on a particular error.
|
||||
* @param {!chrome.developerPrivate.OpenDevToolsProperties} properties
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-openDevTools
|
||||
*/
|
||||
chrome.developerPrivate.openDevTools = function(properties, callback) {};
|
||||
|
||||
@ -690,6 +755,7 @@ chrome.developerPrivate.openDevTools = function(properties, callback) {};
|
||||
* @param {!chrome.developerPrivate.DeleteExtensionErrorsProperties} properties
|
||||
* The properties specifying the errors to remove.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-deleteExtensionErrors
|
||||
*/
|
||||
chrome.developerPrivate.deleteExtensionErrors = function(properties, callback) {};
|
||||
|
||||
@ -697,6 +763,7 @@ chrome.developerPrivate.deleteExtensionErrors = function(properties, callback) {
|
||||
* Repairs the extension specified.
|
||||
* @param {string} extensionId The id of the extension to repair.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-repairExtension
|
||||
*/
|
||||
chrome.developerPrivate.repairExtension = function(extensionId, callback) {};
|
||||
|
||||
@ -705,6 +772,7 @@ chrome.developerPrivate.repairExtension = function(extensionId, callback) {};
|
||||
* @param {string} extensionId The id of the extension to show the options page
|
||||
* for.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-showOptions
|
||||
*/
|
||||
chrome.developerPrivate.showOptions = function(extensionId, callback) {};
|
||||
|
||||
@ -712,6 +780,7 @@ chrome.developerPrivate.showOptions = function(extensionId, callback) {};
|
||||
* Shows the path of the extension specified.
|
||||
* @param {string} extensionId The id of the extension to show the path for.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-showPath
|
||||
*/
|
||||
chrome.developerPrivate.showPath = function(extensionId, callback) {};
|
||||
|
||||
@ -720,6 +789,7 @@ chrome.developerPrivate.showPath = function(extensionId, callback) {};
|
||||
* @param {boolean} isSuspended Whether or not shortcut handling should be
|
||||
* suspended.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-setShortcutHandlingSuspended
|
||||
*/
|
||||
chrome.developerPrivate.setShortcutHandlingSuspended = function(isSuspended, callback) {};
|
||||
|
||||
@ -728,6 +798,7 @@ chrome.developerPrivate.setShortcutHandlingSuspended = function(isSuspended, cal
|
||||
* @param {!chrome.developerPrivate.ExtensionCommandUpdate} update The
|
||||
* parameters for updating the extension command.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-updateExtensionCommand
|
||||
*/
|
||||
chrome.developerPrivate.updateExtensionCommand = function(update, callback) {};
|
||||
|
||||
@ -737,6 +808,7 @@ chrome.developerPrivate.updateExtensionCommand = function(update, callback) {};
|
||||
* @param {string} extensionId The id of the extension to modify.
|
||||
* @param {string} host The host to add.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-addHostPermission
|
||||
*/
|
||||
chrome.developerPrivate.addHostPermission = function(extensionId, host, callback) {};
|
||||
|
||||
@ -746,6 +818,7 @@ chrome.developerPrivate.addHostPermission = function(extensionId, host, callback
|
||||
* @param {string} extensionId The id of the extension to modify.
|
||||
* @param {string} host The host to remove.
|
||||
* @param {function():void=} callback
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-removeHostPermission
|
||||
*/
|
||||
chrome.developerPrivate.removeHostPermission = function(extensionId, host, callback) {};
|
||||
|
||||
@ -754,6 +827,7 @@ chrome.developerPrivate.removeHostPermission = function(extensionId, host, callb
|
||||
* @param {boolean} enabled
|
||||
* @param {function():void=} callback
|
||||
* @deprecated Use management.setEnabled
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-enable
|
||||
*/
|
||||
chrome.developerPrivate.enable = function(id, enabled, callback) {};
|
||||
|
||||
@ -762,6 +836,7 @@ chrome.developerPrivate.enable = function(id, enabled, callback) {};
|
||||
* @param {boolean} allow
|
||||
* @param {function():void=} callback
|
||||
* @deprecated Use updateExtensionConfiguration
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-allowIncognito
|
||||
*/
|
||||
chrome.developerPrivate.allowIncognito = function(extensionId, allow, callback) {};
|
||||
|
||||
@ -770,6 +845,7 @@ chrome.developerPrivate.allowIncognito = function(extensionId, allow, callback)
|
||||
* @param {boolean} allow
|
||||
* @param {function():void=} callback
|
||||
* @deprecated Use updateExtensionConfiguration
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-allowFileAccess
|
||||
*/
|
||||
chrome.developerPrivate.allowFileAccess = function(extensionId, allow, callback) {};
|
||||
|
||||
@ -777,17 +853,20 @@ chrome.developerPrivate.allowFileAccess = function(extensionId, allow, callback)
|
||||
* @param {!chrome.developerPrivate.InspectOptions} options
|
||||
* @param {function():void=} callback
|
||||
* @deprecated Use openDevTools
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#method-inspect
|
||||
*/
|
||||
chrome.developerPrivate.inspect = function(options, callback) {};
|
||||
|
||||
/**
|
||||
* Fired when a item state is changed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#event-onItemStateChanged
|
||||
*/
|
||||
chrome.developerPrivate.onItemStateChanged;
|
||||
|
||||
/**
|
||||
* Fired when the profile's state has changed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/developerPrivate#event-onProfileStateChanged
|
||||
*/
|
||||
chrome.developerPrivate.onProfileStateChanged;
|
||||
|
||||
@ -22,6 +22,7 @@ chrome.inputMethodPrivate = {};
|
||||
* isPhysicalKeyboardAutocorrectEnabled: boolean,
|
||||
* isImeMenuActivated: boolean
|
||||
* }):void} callback Callback which is called with the config object.
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#method-getInputMethodConfig
|
||||
*/
|
||||
chrome.inputMethodPrivate.getInputMethodConfig = function(callback) {};
|
||||
|
||||
@ -32,6 +33,7 @@ chrome.inputMethodPrivate.getInputMethodConfig = function(callback) {};
|
||||
* name: string,
|
||||
* indicator: string
|
||||
* }>):void} callback Callback which is called with the input method objects.
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#method-getInputMethods
|
||||
*/
|
||||
chrome.inputMethodPrivate.getInputMethods = function(callback) {};
|
||||
|
||||
@ -39,6 +41,7 @@ chrome.inputMethodPrivate.getInputMethods = function(callback) {};
|
||||
* Gets the current input method.
|
||||
* @param {function(string):void} callback Callback which is called with the
|
||||
* current input method.
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#method-getCurrentInputMethod
|
||||
*/
|
||||
chrome.inputMethodPrivate.getCurrentInputMethod = function(callback) {};
|
||||
|
||||
@ -48,6 +51,7 @@ chrome.inputMethodPrivate.getCurrentInputMethod = function(callback) {};
|
||||
* method.
|
||||
* @param {function():void=} callback Callback which is called once the current
|
||||
* input method is set. If unsuccessful $(ref:runtime.lastError) is set.
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#method-setCurrentInputMethod
|
||||
*/
|
||||
chrome.inputMethodPrivate.setCurrentInputMethod = function(inputMethodId, callback) {};
|
||||
|
||||
@ -55,6 +59,7 @@ chrome.inputMethodPrivate.setCurrentInputMethod = function(inputMethodId, callba
|
||||
* Fetches a list of all the words currently in the dictionary.
|
||||
* @param {function(!Array<string>):void} callback Callback which is called once
|
||||
* the list of dictionary words are ready.
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#method-fetchAllDictionaryWords
|
||||
*/
|
||||
chrome.inputMethodPrivate.fetchAllDictionaryWords = function(callback) {};
|
||||
|
||||
@ -63,6 +68,7 @@ chrome.inputMethodPrivate.fetchAllDictionaryWords = function(callback) {};
|
||||
* @param {string} word A new word to add to the dictionary.
|
||||
* @param {function():void=} callback Callback which is called once the word is
|
||||
* added. If unsuccessful $(ref:runtime.lastError) is set.
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#method-addWordToDictionary
|
||||
*/
|
||||
chrome.inputMethodPrivate.addWordToDictionary = function(word, callback) {};
|
||||
|
||||
@ -70,6 +76,7 @@ chrome.inputMethodPrivate.addWordToDictionary = function(word, callback) {};
|
||||
* Gets whether the encrypt sync is enabled.
|
||||
* @param {function(boolean):void=} callback Callback which is called to provide
|
||||
* the result.
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#method-getEncryptSyncEnabled
|
||||
*/
|
||||
chrome.inputMethodPrivate.getEncryptSyncEnabled = function(callback) {};
|
||||
|
||||
@ -78,35 +85,41 @@ chrome.inputMethodPrivate.getEncryptSyncEnabled = function(callback) {};
|
||||
* @param {string} xkb_name The XKB layout name.
|
||||
* @param {function():void=} callback Callback which is called when the layout
|
||||
* is set.
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#method-setXkbLayout
|
||||
*/
|
||||
chrome.inputMethodPrivate.setXkbLayout = function(xkb_name, callback) {};
|
||||
|
||||
/**
|
||||
* Fired when the input method is changed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#event-onChanged
|
||||
*/
|
||||
chrome.inputMethodPrivate.onChanged;
|
||||
|
||||
/**
|
||||
* Fired when the composition bounds or cursor bounds are changed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#event-onCompositionBoundsChanged
|
||||
*/
|
||||
chrome.inputMethodPrivate.onCompositionBoundsChanged;
|
||||
|
||||
/**
|
||||
* Fired when the custom spelling dictionary is loaded.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#event-onDictionaryLoaded
|
||||
*/
|
||||
chrome.inputMethodPrivate.onDictionaryLoaded;
|
||||
|
||||
/**
|
||||
* Fired when words are added or removed from the custom spelling dictionary.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#event-onDictionaryChanged
|
||||
*/
|
||||
chrome.inputMethodPrivate.onDictionaryChanged;
|
||||
|
||||
/**
|
||||
* Fired when the IME menu is activated or deactivated.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/inputMethodPrivate#event-onImeMenuActivationChanged
|
||||
*/
|
||||
chrome.inputMethodPrivate.onImeMenuActivationChanged;
|
||||
|
||||
@ -18,6 +18,7 @@ chrome.languageSettingsPrivate = {};
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#type-MoveType
|
||||
*/
|
||||
chrome.languageSettingsPrivate.MoveType = {
|
||||
TOP: 'TOP',
|
||||
@ -36,6 +37,7 @@ chrome.languageSettingsPrivate.MoveType = {
|
||||
* supportsTranslate: (boolean|undefined),
|
||||
* isAllowedUILocale: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#type-Language
|
||||
*/
|
||||
chrome.languageSettingsPrivate.Language;
|
||||
|
||||
@ -46,6 +48,7 @@ chrome.languageSettingsPrivate.Language;
|
||||
* isDownloading: (boolean|undefined),
|
||||
* downloadFailed: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#type-SpellcheckDictionaryStatus
|
||||
*/
|
||||
chrome.languageSettingsPrivate.SpellcheckDictionaryStatus;
|
||||
|
||||
@ -57,6 +60,7 @@ chrome.languageSettingsPrivate.SpellcheckDictionaryStatus;
|
||||
* enabled: (boolean|undefined),
|
||||
* hasOptionsPage: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#type-InputMethod
|
||||
*/
|
||||
chrome.languageSettingsPrivate.InputMethod;
|
||||
|
||||
@ -65,6 +69,7 @@ chrome.languageSettingsPrivate.InputMethod;
|
||||
* componentExtensionImes: !Array<!chrome.languageSettingsPrivate.InputMethod>,
|
||||
* thirdPartyExtensionImes: !Array<!chrome.languageSettingsPrivate.InputMethod>
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#type-InputMethodLists
|
||||
*/
|
||||
chrome.languageSettingsPrivate.InputMethodLists;
|
||||
|
||||
@ -72,6 +77,7 @@ chrome.languageSettingsPrivate.InputMethodLists;
|
||||
* Gets languages available for translate, spell checking, input and locale.
|
||||
* @param {function(!Array<!chrome.languageSettingsPrivate.Language>):void}
|
||||
* callback
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-getLanguageList
|
||||
*/
|
||||
chrome.languageSettingsPrivate.getLanguageList = function(callback) {};
|
||||
|
||||
@ -79,12 +85,14 @@ chrome.languageSettingsPrivate.getLanguageList = function(callback) {};
|
||||
* Enables a language, adding it to the Accept-Language list (used to decide
|
||||
* which languages to translate, generate the Accept-Language header, etc.).
|
||||
* @param {string} languageCode
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-enableLanguage
|
||||
*/
|
||||
chrome.languageSettingsPrivate.enableLanguage = function(languageCode) {};
|
||||
|
||||
/**
|
||||
* Disables a language, removing it from the Accept-Language list.
|
||||
* @param {string} languageCode
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-disableLanguage
|
||||
*/
|
||||
chrome.languageSettingsPrivate.disableLanguage = function(languageCode) {};
|
||||
|
||||
@ -92,6 +100,7 @@ chrome.languageSettingsPrivate.disableLanguage = function(languageCode) {};
|
||||
* Enables or disables translation for a given language.
|
||||
* @param {string} languageCode
|
||||
* @param {boolean} enable
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-setEnableTranslationForLanguage
|
||||
*/
|
||||
chrome.languageSettingsPrivate.setEnableTranslationForLanguage = function(languageCode, enable) {};
|
||||
|
||||
@ -99,6 +108,7 @@ chrome.languageSettingsPrivate.setEnableTranslationForLanguage = function(langua
|
||||
* Moves a language inside the language list.
|
||||
* @param {string} languageCode
|
||||
* @param {!chrome.languageSettingsPrivate.MoveType} moveType
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-moveLanguage
|
||||
*/
|
||||
chrome.languageSettingsPrivate.moveLanguage = function(languageCode, moveType) {};
|
||||
|
||||
@ -106,30 +116,35 @@ chrome.languageSettingsPrivate.moveLanguage = function(languageCode, moveType) {
|
||||
* Gets the current status of the chosen spell check dictionaries.
|
||||
* @param {function(!Array<!chrome.languageSettingsPrivate.SpellcheckDictionaryStatus>):void}
|
||||
* callback
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-getSpellcheckDictionaryStatuses
|
||||
*/
|
||||
chrome.languageSettingsPrivate.getSpellcheckDictionaryStatuses = function(callback) {};
|
||||
|
||||
/**
|
||||
* Gets the custom spell check words, in sorted order.
|
||||
* @param {function(!Array<string>):void} callback
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-getSpellcheckWords
|
||||
*/
|
||||
chrome.languageSettingsPrivate.getSpellcheckWords = function(callback) {};
|
||||
|
||||
/**
|
||||
* Adds a word to the custom dictionary.
|
||||
* @param {string} word
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-addSpellcheckWord
|
||||
*/
|
||||
chrome.languageSettingsPrivate.addSpellcheckWord = function(word) {};
|
||||
|
||||
/**
|
||||
* Removes a word from the custom dictionary.
|
||||
* @param {string} word
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-removeSpellcheckWord
|
||||
*/
|
||||
chrome.languageSettingsPrivate.removeSpellcheckWord = function(word) {};
|
||||
|
||||
/**
|
||||
* Gets the translate target language (in most cases, the display locale).
|
||||
* @param {function(string):void} callback
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-getTranslateTargetLanguage
|
||||
*/
|
||||
chrome.languageSettingsPrivate.getTranslateTargetLanguage = function(callback) {};
|
||||
|
||||
@ -137,6 +152,7 @@ chrome.languageSettingsPrivate.getTranslateTargetLanguage = function(callback) {
|
||||
* Gets all supported input methods, including third-party IMEs. Chrome OS only.
|
||||
* @param {function(!chrome.languageSettingsPrivate.InputMethodLists):void}
|
||||
* callback
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-getInputMethodLists
|
||||
*/
|
||||
chrome.languageSettingsPrivate.getInputMethodLists = function(callback) {};
|
||||
|
||||
@ -144,6 +160,7 @@ chrome.languageSettingsPrivate.getInputMethodLists = function(callback) {};
|
||||
* Adds the input method to the current user's list of enabled input methods,
|
||||
* enabling the input method for the current user. Chrome OS only.
|
||||
* @param {string} inputMethodId
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-addInputMethod
|
||||
*/
|
||||
chrome.languageSettingsPrivate.addInputMethod = function(inputMethodId) {};
|
||||
|
||||
@ -151,12 +168,14 @@ chrome.languageSettingsPrivate.addInputMethod = function(inputMethodId) {};
|
||||
* Removes the input method from the current user's list of enabled input
|
||||
* methods, disabling the input method for the current user. Chrome OS only.
|
||||
* @param {string} inputMethodId
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-removeInputMethod
|
||||
*/
|
||||
chrome.languageSettingsPrivate.removeInputMethod = function(inputMethodId) {};
|
||||
|
||||
/**
|
||||
* Tries to download the dictionary after a failed download.
|
||||
* @param {string} languageCode
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-retryDownloadDictionary
|
||||
*/
|
||||
chrome.languageSettingsPrivate.retryDownloadDictionary = function(languageCode) {};
|
||||
|
||||
@ -164,6 +183,7 @@ chrome.languageSettingsPrivate.retryDownloadDictionary = function(languageCode)
|
||||
* Called when the pref for the dictionaries used for spell checking changes or
|
||||
* the status of one of the spell check dictionaries changes.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#event-onSpellcheckDictionariesChanged
|
||||
*/
|
||||
chrome.languageSettingsPrivate.onSpellcheckDictionariesChanged;
|
||||
|
||||
@ -171,17 +191,20 @@ chrome.languageSettingsPrivate.onSpellcheckDictionariesChanged;
|
||||
* Called when words are added to and/or removed from the custom spell check
|
||||
* dictionary.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#event-onCustomDictionaryChanged
|
||||
*/
|
||||
chrome.languageSettingsPrivate.onCustomDictionaryChanged;
|
||||
|
||||
/**
|
||||
* Called when an input method is added.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#event-onInputMethodAdded
|
||||
*/
|
||||
chrome.languageSettingsPrivate.onInputMethodAdded;
|
||||
|
||||
/**
|
||||
* Called when an input method is removed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/languageSettingsPrivate#event-onInputMethodRemoved
|
||||
*/
|
||||
chrome.languageSettingsPrivate.onInputMethodRemoved;
|
||||
chrome.languageSettingsPrivate.onInputMethodRemoved;
|
||||
@ -18,6 +18,7 @@ chrome.metricsPrivate = {};
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#type-MetricTypeType
|
||||
*/
|
||||
chrome.metricsPrivate.MetricTypeType = {
|
||||
HISTOGRAM_LOG: 'histogram-log',
|
||||
@ -33,12 +34,14 @@ chrome.metricsPrivate.MetricTypeType = {
|
||||
* max: number,
|
||||
* buckets: number
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#type-MetricType
|
||||
*/
|
||||
chrome.metricsPrivate.MetricType;
|
||||
|
||||
/**
|
||||
* Returns true if the user opted in to sending crash reports.
|
||||
* @param {function(boolean):void} callback
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-getIsCrashReportingEnabled
|
||||
*/
|
||||
chrome.metricsPrivate.getIsCrashReportingEnabled = function(callback) {};
|
||||
|
||||
@ -47,6 +50,7 @@ chrome.metricsPrivate.getIsCrashReportingEnabled = function(callback) {};
|
||||
* trial does not exist or is not enabled.
|
||||
* @param {string} name
|
||||
* @param {function(string):void} callback
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-getFieldTrial
|
||||
*/
|
||||
chrome.metricsPrivate.getFieldTrial = function(name, callback) {};
|
||||
|
||||
@ -55,12 +59,14 @@ chrome.metricsPrivate.getFieldTrial = function(name, callback) {};
|
||||
* otherwise.
|
||||
* @param {string} name
|
||||
* @param {function((Object|undefined)):void} callback
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-getVariationParams
|
||||
*/
|
||||
chrome.metricsPrivate.getVariationParams = function(name, callback) {};
|
||||
|
||||
/**
|
||||
* Records an action performed by the user.
|
||||
* @param {string} name
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordUserAction
|
||||
*/
|
||||
chrome.metricsPrivate.recordUserAction = function(name) {};
|
||||
|
||||
@ -68,6 +74,7 @@ chrome.metricsPrivate.recordUserAction = function(name) {};
|
||||
* Records a percentage value from 1 to 100.
|
||||
* @param {string} metricName
|
||||
* @param {number} value
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordPercentage
|
||||
*/
|
||||
chrome.metricsPrivate.recordPercentage = function(metricName, value) {};
|
||||
|
||||
@ -75,6 +82,7 @@ chrome.metricsPrivate.recordPercentage = function(metricName, value) {};
|
||||
* Records a value than can range from 1 to 1,000,000.
|
||||
* @param {string} metricName
|
||||
* @param {number} value
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordCount
|
||||
*/
|
||||
chrome.metricsPrivate.recordCount = function(metricName, value) {};
|
||||
|
||||
@ -82,6 +90,7 @@ chrome.metricsPrivate.recordCount = function(metricName, value) {};
|
||||
* Records a value than can range from 1 to 100.
|
||||
* @param {string} metricName
|
||||
* @param {number} value
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordSmallCount
|
||||
*/
|
||||
chrome.metricsPrivate.recordSmallCount = function(metricName, value) {};
|
||||
|
||||
@ -89,6 +98,7 @@ chrome.metricsPrivate.recordSmallCount = function(metricName, value) {};
|
||||
* Records a value than can range from 1 to 10,000.
|
||||
* @param {string} metricName
|
||||
* @param {number} value
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordMediumCount
|
||||
*/
|
||||
chrome.metricsPrivate.recordMediumCount = function(metricName, value) {};
|
||||
|
||||
@ -97,6 +107,7 @@ chrome.metricsPrivate.recordMediumCount = function(metricName, value) {};
|
||||
* specified in milliseconds.
|
||||
* @param {string} metricName
|
||||
* @param {number} value
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordTime
|
||||
*/
|
||||
chrome.metricsPrivate.recordTime = function(metricName, value) {};
|
||||
|
||||
@ -105,6 +116,7 @@ chrome.metricsPrivate.recordTime = function(metricName, value) {};
|
||||
* specified in milliseconds.
|
||||
* @param {string} metricName
|
||||
* @param {number} value
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordMediumTime
|
||||
*/
|
||||
chrome.metricsPrivate.recordMediumTime = function(metricName, value) {};
|
||||
|
||||
@ -113,6 +125,7 @@ chrome.metricsPrivate.recordMediumTime = function(metricName, value) {};
|
||||
* specified in milliseconds.
|
||||
* @param {string} metricName
|
||||
* @param {number} value
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordLongTime
|
||||
*/
|
||||
chrome.metricsPrivate.recordLongTime = function(metricName, value) {};
|
||||
|
||||
@ -121,6 +134,7 @@ chrome.metricsPrivate.recordLongTime = function(metricName, value) {};
|
||||
* histogram defined by the |metricName|.
|
||||
* @param {string} metricName
|
||||
* @param {string} value
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordSparseHashable
|
||||
*/
|
||||
chrome.metricsPrivate.recordSparseHashable = function(metricName, value) {};
|
||||
|
||||
@ -129,6 +143,7 @@ chrome.metricsPrivate.recordSparseHashable = function(metricName, value) {};
|
||||
* by the |metricName|.
|
||||
* @param {string} metricName
|
||||
* @param {number} value
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordSparseValue
|
||||
*/
|
||||
chrome.metricsPrivate.recordSparseValue = function(metricName, value) {};
|
||||
|
||||
@ -136,6 +151,7 @@ chrome.metricsPrivate.recordSparseValue = function(metricName, value) {};
|
||||
* Adds a value to the given metric.
|
||||
* @param {!chrome.metricsPrivate.MetricType} metric
|
||||
* @param {number} value
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordValue
|
||||
*/
|
||||
chrome.metricsPrivate.recordValue = function(metric, value) {};
|
||||
|
||||
@ -144,6 +160,7 @@ chrome.metricsPrivate.recordValue = function(metric, value) {};
|
||||
* base::UmaHistogramBoolean().
|
||||
* @param {string} metricName
|
||||
* @param {boolean} value
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordBoolean
|
||||
*/
|
||||
chrome.metricsPrivate.recordBoolean = function(metricName, value) {};
|
||||
|
||||
@ -154,5 +171,6 @@ chrome.metricsPrivate.recordBoolean = function(metricName, value) {};
|
||||
* @param {string} metricName
|
||||
* @param {number} value
|
||||
* @param {number} enumSize
|
||||
* @see https://developer.chrome.com/extensions/metricsPrivate#method-recordEnumerationValue
|
||||
*/
|
||||
chrome.metricsPrivate.recordEnumerationValue = function(metricName, value, enumSize) {};
|
||||
|
||||
@ -18,6 +18,7 @@ chrome.networkingPrivate = {};
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ActivationStateType
|
||||
*/
|
||||
chrome.networkingPrivate.ActivationStateType = {
|
||||
ACTIVATED: 'Activated',
|
||||
@ -28,6 +29,7 @@ chrome.networkingPrivate.ActivationStateType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-CaptivePortalStatus
|
||||
*/
|
||||
chrome.networkingPrivate.CaptivePortalStatus = {
|
||||
UNKNOWN: 'Unknown',
|
||||
@ -39,6 +41,7 @@ chrome.networkingPrivate.CaptivePortalStatus = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ConnectionStateType
|
||||
*/
|
||||
chrome.networkingPrivate.ConnectionStateType = {
|
||||
CONNECTED: 'Connected',
|
||||
@ -48,6 +51,7 @@ chrome.networkingPrivate.ConnectionStateType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-DeviceStateType
|
||||
*/
|
||||
chrome.networkingPrivate.DeviceStateType = {
|
||||
UNINITIALIZED: 'Uninitialized',
|
||||
@ -59,6 +63,7 @@ chrome.networkingPrivate.DeviceStateType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-IPConfigType
|
||||
*/
|
||||
chrome.networkingPrivate.IPConfigType = {
|
||||
DHCP: 'DHCP',
|
||||
@ -67,6 +72,7 @@ chrome.networkingPrivate.IPConfigType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-NetworkType
|
||||
*/
|
||||
chrome.networkingPrivate.NetworkType = {
|
||||
ALL: 'All',
|
||||
@ -81,6 +87,7 @@ chrome.networkingPrivate.NetworkType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ProxySettingsType
|
||||
*/
|
||||
chrome.networkingPrivate.ProxySettingsType = {
|
||||
DIRECT: 'Direct',
|
||||
@ -100,6 +107,7 @@ chrome.networkingPrivate.ProxySettingsType = {
|
||||
* UserEditable: (boolean|undefined),
|
||||
* DeviceEditable: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedBoolean
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedBoolean;
|
||||
|
||||
@ -114,6 +122,7 @@ chrome.networkingPrivate.ManagedBoolean;
|
||||
* UserEditable: (boolean|undefined),
|
||||
* DeviceEditable: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedLong
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedLong;
|
||||
|
||||
@ -128,6 +137,7 @@ chrome.networkingPrivate.ManagedLong;
|
||||
* UserEditable: (boolean|undefined),
|
||||
* DeviceEditable: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedDOMString
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedDOMString;
|
||||
|
||||
@ -142,6 +152,7 @@ chrome.networkingPrivate.ManagedDOMString;
|
||||
* UserEditable: (boolean|undefined),
|
||||
* DeviceEditable: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedDOMStringList
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedDOMStringList;
|
||||
|
||||
@ -156,6 +167,7 @@ chrome.networkingPrivate.ManagedDOMStringList;
|
||||
* UserEditable: (boolean|undefined),
|
||||
* DeviceEditable: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedIPConfigType
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedIPConfigType;
|
||||
|
||||
@ -170,6 +182,7 @@ chrome.networkingPrivate.ManagedIPConfigType;
|
||||
* UserEditable: (boolean|undefined),
|
||||
* DeviceEditable: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedProxySettingsType
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedProxySettingsType;
|
||||
|
||||
@ -183,6 +196,7 @@ chrome.networkingPrivate.ManagedProxySettingsType;
|
||||
* Password: (string|undefined),
|
||||
* Username: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-APNProperties
|
||||
*/
|
||||
chrome.networkingPrivate.APNProperties;
|
||||
|
||||
@ -196,6 +210,7 @@ chrome.networkingPrivate.APNProperties;
|
||||
* Password: (!chrome.networkingPrivate.ManagedDOMString|undefined),
|
||||
* Username: (!chrome.networkingPrivate.ManagedDOMString|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedAPNProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedAPNProperties;
|
||||
|
||||
@ -210,6 +225,7 @@ chrome.networkingPrivate.ManagedAPNProperties;
|
||||
* UserEditable: (boolean|undefined),
|
||||
* DeviceEditable: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedAPNList
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedAPNList;
|
||||
|
||||
@ -219,6 +235,7 @@ chrome.networkingPrivate.ManagedAPNList;
|
||||
* Code: string,
|
||||
* Country: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-CellularProviderProperties
|
||||
*/
|
||||
chrome.networkingPrivate.CellularProviderProperties;
|
||||
|
||||
@ -228,6 +245,7 @@ chrome.networkingPrivate.CellularProviderProperties;
|
||||
* currentPin: string,
|
||||
* newPin: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-CellularSimState
|
||||
*/
|
||||
chrome.networkingPrivate.CellularSimState;
|
||||
|
||||
@ -238,6 +256,7 @@ chrome.networkingPrivate.CellularSimState;
|
||||
* Organization: (string|undefined),
|
||||
* OrganizationalUnit: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-IssuerSubjectPattern
|
||||
*/
|
||||
chrome.networkingPrivate.IssuerSubjectPattern;
|
||||
|
||||
@ -248,6 +267,7 @@ chrome.networkingPrivate.IssuerSubjectPattern;
|
||||
* Organization: (!chrome.networkingPrivate.ManagedDOMString|undefined),
|
||||
* OrganizationalUnit: (!chrome.networkingPrivate.ManagedDOMString|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedIssuerSubjectPattern
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedIssuerSubjectPattern;
|
||||
|
||||
@ -258,6 +278,7 @@ chrome.networkingPrivate.ManagedIssuerSubjectPattern;
|
||||
* IssuerCARef: (!Array<string>|undefined),
|
||||
* Subject: (!chrome.networkingPrivate.IssuerSubjectPattern|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-CertificatePattern
|
||||
*/
|
||||
chrome.networkingPrivate.CertificatePattern;
|
||||
|
||||
@ -268,6 +289,7 @@ chrome.networkingPrivate.CertificatePattern;
|
||||
* IssuerCARef: (!chrome.networkingPrivate.ManagedDOMStringList|undefined),
|
||||
* Subject: (!chrome.networkingPrivate.ManagedIssuerSubjectPattern|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedCertificatePattern
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedCertificatePattern;
|
||||
|
||||
@ -290,6 +312,7 @@ chrome.networkingPrivate.ManagedCertificatePattern;
|
||||
* UseProactiveKeyCaching: (boolean|undefined),
|
||||
* UseSystemCAs: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-EAPProperties
|
||||
*/
|
||||
chrome.networkingPrivate.EAPProperties;
|
||||
|
||||
@ -312,6 +335,7 @@ chrome.networkingPrivate.EAPProperties;
|
||||
* UseProactiveKeyCaching: (!chrome.networkingPrivate.ManagedBoolean|undefined),
|
||||
* UseSystemCAs: (!chrome.networkingPrivate.ManagedBoolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedEAPProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedEAPProperties;
|
||||
|
||||
@ -323,6 +347,7 @@ chrome.networkingPrivate.ManagedEAPProperties;
|
||||
* ShortName: (string|undefined),
|
||||
* LongName: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-FoundNetworkProperties
|
||||
*/
|
||||
chrome.networkingPrivate.FoundNetworkProperties;
|
||||
|
||||
@ -335,6 +360,7 @@ chrome.networkingPrivate.FoundNetworkProperties;
|
||||
* Type: (string|undefined),
|
||||
* WebProxyAutoDiscoveryUrl: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-IPConfigProperties
|
||||
*/
|
||||
chrome.networkingPrivate.IPConfigProperties;
|
||||
|
||||
@ -347,6 +373,7 @@ chrome.networkingPrivate.IPConfigProperties;
|
||||
* Type: (!chrome.networkingPrivate.ManagedDOMString|undefined),
|
||||
* WebProxyAutoDiscoveryUrl: (!chrome.networkingPrivate.ManagedDOMString|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedIPConfigProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedIPConfigProperties;
|
||||
|
||||
@ -356,6 +383,7 @@ chrome.networkingPrivate.ManagedIPConfigProperties;
|
||||
* SaveCredentials: (boolean|undefined),
|
||||
* Username: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-XAUTHProperties
|
||||
*/
|
||||
chrome.networkingPrivate.XAUTHProperties;
|
||||
|
||||
@ -365,6 +393,7 @@ chrome.networkingPrivate.XAUTHProperties;
|
||||
* SaveCredentials: (!chrome.networkingPrivate.ManagedBoolean|undefined),
|
||||
* Username: (!chrome.networkingPrivate.ManagedDOMString|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedXAUTHProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedXAUTHProperties;
|
||||
|
||||
@ -384,6 +413,7 @@ chrome.networkingPrivate.ManagedXAUTHProperties;
|
||||
* ServerCARefs: (!Array<string>|undefined),
|
||||
* XAUTH: (!chrome.networkingPrivate.XAUTHProperties|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-IPSecProperties
|
||||
*/
|
||||
chrome.networkingPrivate.IPSecProperties;
|
||||
|
||||
@ -403,6 +433,7 @@ chrome.networkingPrivate.IPSecProperties;
|
||||
* ServerCARefs: (!chrome.networkingPrivate.ManagedDOMStringList|undefined),
|
||||
* XAUTH: (!chrome.networkingPrivate.ManagedXAUTHProperties|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedIPSecProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedIPSecProperties;
|
||||
|
||||
@ -413,6 +444,7 @@ chrome.networkingPrivate.ManagedIPSecProperties;
|
||||
* SaveCredentials: (boolean|undefined),
|
||||
* Username: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-L2TPProperties
|
||||
*/
|
||||
chrome.networkingPrivate.L2TPProperties;
|
||||
|
||||
@ -423,6 +455,7 @@ chrome.networkingPrivate.L2TPProperties;
|
||||
* SaveCredentials: (!chrome.networkingPrivate.ManagedBoolean|undefined),
|
||||
* Username: (!chrome.networkingPrivate.ManagedDOMString|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedL2TPProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedL2TPProperties;
|
||||
|
||||
@ -432,6 +465,7 @@ chrome.networkingPrivate.ManagedL2TPProperties;
|
||||
* PostData: (string|undefined),
|
||||
* Url: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-PaymentPortal
|
||||
*/
|
||||
chrome.networkingPrivate.PaymentPortal;
|
||||
|
||||
@ -440,6 +474,7 @@ chrome.networkingPrivate.PaymentPortal;
|
||||
* Host: string,
|
||||
* Port: number
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ProxyLocation
|
||||
*/
|
||||
chrome.networkingPrivate.ProxyLocation;
|
||||
|
||||
@ -448,6 +483,7 @@ chrome.networkingPrivate.ProxyLocation;
|
||||
* Host: !chrome.networkingPrivate.ManagedDOMString,
|
||||
* Port: !chrome.networkingPrivate.ManagedLong
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedProxyLocation
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedProxyLocation;
|
||||
|
||||
@ -458,6 +494,7 @@ chrome.networkingPrivate.ManagedProxyLocation;
|
||||
* FTPProxy: (!chrome.networkingPrivate.ProxyLocation|undefined),
|
||||
* SOCKS: (!chrome.networkingPrivate.ProxyLocation|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManualProxySettings
|
||||
*/
|
||||
chrome.networkingPrivate.ManualProxySettings;
|
||||
|
||||
@ -468,6 +505,7 @@ chrome.networkingPrivate.ManualProxySettings;
|
||||
* FTPProxy: (!chrome.networkingPrivate.ManagedProxyLocation|undefined),
|
||||
* SOCKS: (!chrome.networkingPrivate.ManagedProxyLocation|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedManualProxySettings
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedManualProxySettings;
|
||||
|
||||
@ -478,6 +516,7 @@ chrome.networkingPrivate.ManagedManualProxySettings;
|
||||
* ExcludeDomains: (!Array<string>|undefined),
|
||||
* PAC: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ProxySettings
|
||||
*/
|
||||
chrome.networkingPrivate.ProxySettings;
|
||||
|
||||
@ -488,6 +527,7 @@ chrome.networkingPrivate.ProxySettings;
|
||||
* ExcludeDomains: (!chrome.networkingPrivate.ManagedDOMStringList|undefined),
|
||||
* PAC: (!chrome.networkingPrivate.ManagedDOMString|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedProxySettings
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedProxySettings;
|
||||
|
||||
@ -496,6 +536,7 @@ chrome.networkingPrivate.ManagedProxySettings;
|
||||
* Name: (string|undefined),
|
||||
* Type: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-VerifyX509
|
||||
*/
|
||||
chrome.networkingPrivate.VerifyX509;
|
||||
|
||||
@ -504,6 +545,7 @@ chrome.networkingPrivate.VerifyX509;
|
||||
* Name: (!chrome.networkingPrivate.ManagedDOMString|undefined),
|
||||
* Type: (!chrome.networkingPrivate.ManagedDOMString|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedVerifyX509
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedVerifyX509;
|
||||
|
||||
@ -548,6 +590,7 @@ chrome.networkingPrivate.ManagedVerifyX509;
|
||||
* VerifyHash: (string|undefined),
|
||||
* VerifyX509: (!chrome.networkingPrivate.VerifyX509|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-OpenVPNProperties
|
||||
*/
|
||||
chrome.networkingPrivate.OpenVPNProperties;
|
||||
|
||||
@ -592,6 +635,7 @@ chrome.networkingPrivate.OpenVPNProperties;
|
||||
* VerifyHash: (!chrome.networkingPrivate.ManagedDOMString|undefined),
|
||||
* VerifyX509: (!chrome.networkingPrivate.ManagedVerifyX509|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedOpenVPNProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedOpenVPNProperties;
|
||||
|
||||
@ -601,6 +645,7 @@ chrome.networkingPrivate.ManagedOpenVPNProperties;
|
||||
* LockEnabled: boolean,
|
||||
* RetriesLeft: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-SIMLockStatus
|
||||
*/
|
||||
chrome.networkingPrivate.SIMLockStatus;
|
||||
|
||||
@ -609,6 +654,7 @@ chrome.networkingPrivate.SIMLockStatus;
|
||||
* ExtensionID: string,
|
||||
* ProviderName: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ThirdPartyVPNProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ThirdPartyVPNProperties;
|
||||
|
||||
@ -617,6 +663,7 @@ chrome.networkingPrivate.ThirdPartyVPNProperties;
|
||||
* ExtensionID: !chrome.networkingPrivate.ManagedDOMString,
|
||||
* ProviderName: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedThirdPartyVPNProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedThirdPartyVPNProperties;
|
||||
|
||||
@ -655,6 +702,7 @@ chrome.networkingPrivate.ManagedThirdPartyVPNProperties;
|
||||
* SupportNetworkScan: (boolean|undefined),
|
||||
* SupportedCarriers: (!Array<string>|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-CellularProperties
|
||||
*/
|
||||
chrome.networkingPrivate.CellularProperties;
|
||||
|
||||
@ -693,6 +741,7 @@ chrome.networkingPrivate.CellularProperties;
|
||||
* SupportNetworkScan: (boolean|undefined),
|
||||
* SupportedCarriers: (!Array<string>|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedCellularProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedCellularProperties;
|
||||
|
||||
@ -705,6 +754,7 @@ chrome.networkingPrivate.ManagedCellularProperties;
|
||||
* SIMPresent: (boolean|undefined),
|
||||
* SignalStrength: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-CellularStateProperties
|
||||
*/
|
||||
chrome.networkingPrivate.CellularStateProperties;
|
||||
|
||||
@ -714,6 +764,7 @@ chrome.networkingPrivate.CellularStateProperties;
|
||||
* Authentication: (string|undefined),
|
||||
* EAP: (!chrome.networkingPrivate.EAPProperties|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-EthernetProperties
|
||||
*/
|
||||
chrome.networkingPrivate.EthernetProperties;
|
||||
|
||||
@ -723,6 +774,7 @@ chrome.networkingPrivate.EthernetProperties;
|
||||
* Authentication: (!chrome.networkingPrivate.ManagedDOMString|undefined),
|
||||
* EAP: (!chrome.networkingPrivate.ManagedEAPProperties|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedEthernetProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedEthernetProperties;
|
||||
|
||||
@ -730,6 +782,7 @@ chrome.networkingPrivate.ManagedEthernetProperties;
|
||||
* @typedef {{
|
||||
* Authentication: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-EthernetStateProperties
|
||||
*/
|
||||
chrome.networkingPrivate.EthernetStateProperties;
|
||||
|
||||
@ -740,6 +793,7 @@ chrome.networkingPrivate.EthernetStateProperties;
|
||||
* HasConnectedToHost: boolean,
|
||||
* SignalStrength: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-TetherProperties
|
||||
*/
|
||||
chrome.networkingPrivate.TetherProperties;
|
||||
|
||||
@ -753,6 +807,7 @@ chrome.networkingPrivate.TetherProperties;
|
||||
* ThirdPartyVPN: (!chrome.networkingPrivate.ThirdPartyVPNProperties|undefined),
|
||||
* Type: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-VPNProperties
|
||||
*/
|
||||
chrome.networkingPrivate.VPNProperties;
|
||||
|
||||
@ -766,6 +821,7 @@ chrome.networkingPrivate.VPNProperties;
|
||||
* ThirdPartyVPN: (!chrome.networkingPrivate.ManagedThirdPartyVPNProperties|undefined),
|
||||
* Type: (!chrome.networkingPrivate.ManagedDOMString|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedVPNProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedVPNProperties;
|
||||
|
||||
@ -775,6 +831,7 @@ chrome.networkingPrivate.ManagedVPNProperties;
|
||||
* IPsec: (!chrome.networkingPrivate.IPSecProperties|undefined),
|
||||
* ThirdPartyVPN: (!chrome.networkingPrivate.ThirdPartyVPNProperties|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-VPNStateProperties
|
||||
*/
|
||||
chrome.networkingPrivate.VPNStateProperties;
|
||||
|
||||
@ -795,6 +852,7 @@ chrome.networkingPrivate.VPNStateProperties;
|
||||
* Security: (string|undefined),
|
||||
* SignalStrength: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-WiFiProperties
|
||||
*/
|
||||
chrome.networkingPrivate.WiFiProperties;
|
||||
|
||||
@ -815,6 +873,7 @@ chrome.networkingPrivate.WiFiProperties;
|
||||
* Security: !chrome.networkingPrivate.ManagedDOMString,
|
||||
* SignalStrength: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedWiFiProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedWiFiProperties;
|
||||
|
||||
@ -827,6 +886,7 @@ chrome.networkingPrivate.ManagedWiFiProperties;
|
||||
* SignalStrength: (number|undefined),
|
||||
* SSID: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-WiFiStateProperties
|
||||
*/
|
||||
chrome.networkingPrivate.WiFiStateProperties;
|
||||
|
||||
@ -836,6 +896,7 @@ chrome.networkingPrivate.WiFiStateProperties;
|
||||
* EAP: (!chrome.networkingPrivate.EAPProperties|undefined),
|
||||
* SignalStrength: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-WiMAXProperties
|
||||
*/
|
||||
chrome.networkingPrivate.WiMAXProperties;
|
||||
|
||||
@ -845,6 +906,7 @@ chrome.networkingPrivate.WiMAXProperties;
|
||||
* EAP: (!chrome.networkingPrivate.ManagedEAPProperties|undefined),
|
||||
* SignalStrength: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedWiMAXProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedWiMAXProperties;
|
||||
|
||||
@ -852,6 +914,7 @@ chrome.networkingPrivate.ManagedWiMAXProperties;
|
||||
* @typedef {{
|
||||
* SignalStrength: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-WiMAXStateProperties
|
||||
*/
|
||||
chrome.networkingPrivate.WiMAXStateProperties;
|
||||
|
||||
@ -871,6 +934,7 @@ chrome.networkingPrivate.WiMAXStateProperties;
|
||||
* WiFi: (!chrome.networkingPrivate.WiFiProperties|undefined),
|
||||
* WiMAX: (!chrome.networkingPrivate.WiMAXProperties|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-NetworkConfigProperties
|
||||
*/
|
||||
chrome.networkingPrivate.NetworkConfigProperties;
|
||||
|
||||
@ -899,6 +963,7 @@ chrome.networkingPrivate.NetworkConfigProperties;
|
||||
* WiFi: (!chrome.networkingPrivate.WiFiProperties|undefined),
|
||||
* WiMAX: (!chrome.networkingPrivate.WiMAXProperties|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-NetworkProperties
|
||||
*/
|
||||
chrome.networkingPrivate.NetworkProperties;
|
||||
|
||||
@ -927,6 +992,7 @@ chrome.networkingPrivate.NetworkProperties;
|
||||
* WiFi: (!chrome.networkingPrivate.ManagedWiFiProperties|undefined),
|
||||
* WiMAX: (!chrome.networkingPrivate.ManagedWiMAXProperties|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedProperties
|
||||
*/
|
||||
chrome.networkingPrivate.ManagedProperties;
|
||||
|
||||
@ -947,6 +1013,7 @@ chrome.networkingPrivate.ManagedProperties;
|
||||
* WiFi: (!chrome.networkingPrivate.WiFiStateProperties|undefined),
|
||||
* WiMAX: (!chrome.networkingPrivate.WiMAXStateProperties|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-NetworkStateProperties
|
||||
*/
|
||||
chrome.networkingPrivate.NetworkStateProperties;
|
||||
|
||||
@ -958,6 +1025,7 @@ chrome.networkingPrivate.NetworkStateProperties;
|
||||
* State: !chrome.networkingPrivate.DeviceStateType,
|
||||
* Type: !chrome.networkingPrivate.NetworkType
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-DeviceStateProperties
|
||||
*/
|
||||
chrome.networkingPrivate.DeviceStateProperties;
|
||||
|
||||
@ -972,6 +1040,7 @@ chrome.networkingPrivate.DeviceStateProperties;
|
||||
* deviceSsid: string,
|
||||
* deviceBssid: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-VerificationProperties
|
||||
*/
|
||||
chrome.networkingPrivate.VerificationProperties;
|
||||
|
||||
@ -982,6 +1051,7 @@ chrome.networkingPrivate.VerificationProperties;
|
||||
* configured: (boolean|undefined),
|
||||
* limit: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-NetworkFilter
|
||||
*/
|
||||
chrome.networkingPrivate.NetworkFilter;
|
||||
|
||||
@ -990,6 +1060,7 @@ chrome.networkingPrivate.NetworkFilter;
|
||||
* AllowOnlyPolicyNetworksToAutoconnect: (boolean|undefined),
|
||||
* AllowOnlyPolicyNetworksToConnect: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-GlobalPolicy
|
||||
*/
|
||||
chrome.networkingPrivate.GlobalPolicy;
|
||||
|
||||
@ -1002,6 +1073,7 @@ chrome.networkingPrivate.GlobalPolicy;
|
||||
* PKCS11Id: (string|undefined),
|
||||
* hardwareBacked: boolean
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-Certificate
|
||||
*/
|
||||
chrome.networkingPrivate.Certificate;
|
||||
|
||||
@ -1010,6 +1082,7 @@ chrome.networkingPrivate.Certificate;
|
||||
* serverCaCertificates: !Array<!chrome.networkingPrivate.Certificate>,
|
||||
* userCertificates: !Array<!chrome.networkingPrivate.Certificate>
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#type-CertificateLists
|
||||
*/
|
||||
chrome.networkingPrivate.CertificateLists;
|
||||
|
||||
@ -1019,6 +1092,7 @@ chrome.networkingPrivate.CertificateLists;
|
||||
* @param {string} networkGuid The GUID of the network to get properties for.
|
||||
* @param {function(!chrome.networkingPrivate.NetworkProperties):void} callback
|
||||
* Called with the network properties when received.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-getProperties
|
||||
*/
|
||||
chrome.networkingPrivate.getProperties = function(networkGuid, callback) {};
|
||||
|
||||
@ -1029,6 +1103,7 @@ chrome.networkingPrivate.getProperties = function(networkGuid, callback) {};
|
||||
* @param {string} networkGuid The GUID of the network to get properties for.
|
||||
* @param {function(!chrome.networkingPrivate.ManagedProperties):void} callback
|
||||
* Called with the managed network properties when received.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-getManagedProperties
|
||||
*/
|
||||
chrome.networkingPrivate.getManagedProperties = function(networkGuid, callback) {};
|
||||
|
||||
@ -1043,6 +1118,7 @@ chrome.networkingPrivate.getManagedProperties = function(networkGuid, callback)
|
||||
* @param {string} networkGuid The GUID of the network to get properties for.
|
||||
* @param {function(!chrome.networkingPrivate.NetworkStateProperties):void}
|
||||
* callback Called immediately with the network state properties.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-getState
|
||||
*/
|
||||
chrome.networkingPrivate.getState = function(networkGuid, callback) {};
|
||||
|
||||
@ -1054,6 +1130,7 @@ chrome.networkingPrivate.getState = function(networkGuid, callback) {};
|
||||
* @param {!chrome.networkingPrivate.NetworkConfigProperties} properties The
|
||||
* properties to set.
|
||||
* @param {function():void=} callback Called when the operation has completed.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-setProperties
|
||||
*/
|
||||
chrome.networkingPrivate.setProperties = function(networkGuid, properties, callback) {};
|
||||
|
||||
@ -1067,6 +1144,7 @@ chrome.networkingPrivate.setProperties = function(networkGuid, properties, callb
|
||||
* properties to configure the new network with.
|
||||
* @param {function(string):void=} callback Called with the GUID for the new
|
||||
* network configuration once the network has been created.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-createNetwork
|
||||
*/
|
||||
chrome.networkingPrivate.createNetwork = function(shared, properties, callback) {};
|
||||
|
||||
@ -1077,6 +1155,7 @@ chrome.networkingPrivate.createNetwork = function(shared, properties, callback)
|
||||
* configuration exists, an error will be set and the operation will fail.
|
||||
* @param {string} networkGuid The GUID of the network to forget.
|
||||
* @param {function():void=} callback Called when the operation has completed.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-forgetNetwork
|
||||
*/
|
||||
chrome.networkingPrivate.forgetNetwork = function(networkGuid, callback) {};
|
||||
|
||||
@ -1091,6 +1170,7 @@ chrome.networkingPrivate.forgetNetwork = function(networkGuid, callback) {};
|
||||
* @param {function(!Array<!chrome.networkingPrivate.NetworkStateProperties>):void}
|
||||
* callback Called with a dictionary of networks and their state
|
||||
* properties when received.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-getNetworks
|
||||
*/
|
||||
chrome.networkingPrivate.getNetworks = function(filter, callback) {};
|
||||
|
||||
@ -1101,6 +1181,7 @@ chrome.networkingPrivate.getNetworks = function(filter, callback) {};
|
||||
* @param {function(!Array<!chrome.networkingPrivate.NetworkStateProperties>):void}
|
||||
* callback
|
||||
* @deprecated Use getNetworks.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-getVisibleNetworks
|
||||
*/
|
||||
chrome.networkingPrivate.getVisibleNetworks = function(networkType, callback) {};
|
||||
|
||||
@ -1109,6 +1190,7 @@ chrome.networkingPrivate.getVisibleNetworks = function(networkType, callback) {}
|
||||
* @param {function(!Array<!chrome.networkingPrivate.NetworkType>):void}
|
||||
* callback
|
||||
* @deprecated Use getDeviceStates.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-getEnabledNetworkTypes
|
||||
*/
|
||||
chrome.networkingPrivate.getEnabledNetworkTypes = function(callback) {};
|
||||
|
||||
@ -1116,6 +1198,7 @@ chrome.networkingPrivate.getEnabledNetworkTypes = function(callback) {};
|
||||
* Returns a list of $(ref:networkingPrivate.DeviceStateProperties) objects.
|
||||
* @param {function(!Array<!chrome.networkingPrivate.DeviceStateProperties>):void}
|
||||
* callback Called with a list of devices and their state.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-getDeviceStates
|
||||
*/
|
||||
chrome.networkingPrivate.getDeviceStates = function(callback) {};
|
||||
|
||||
@ -1124,6 +1207,7 @@ chrome.networkingPrivate.getDeviceStates = function(callback) {};
|
||||
* represent multiple network types (e.g. 'Wireless').
|
||||
* @param {!chrome.networkingPrivate.NetworkType} networkType The type of
|
||||
* network to enable.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-enableNetworkType
|
||||
*/
|
||||
chrome.networkingPrivate.enableNetworkType = function(networkType) {};
|
||||
|
||||
@ -1132,6 +1216,7 @@ chrome.networkingPrivate.enableNetworkType = function(networkType) {};
|
||||
* $(ref:networkingPrivate.enableNetworkType).
|
||||
* @param {!chrome.networkingPrivate.NetworkType} networkType The type of
|
||||
* network to disable.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-disableNetworkType
|
||||
*/
|
||||
chrome.networkingPrivate.disableNetworkType = function(networkType) {};
|
||||
|
||||
@ -1143,6 +1228,7 @@ chrome.networkingPrivate.disableNetworkType = function(networkType) {};
|
||||
* @param {!chrome.networkingPrivate.NetworkType=} networkType If provided,
|
||||
* requests a scan specific to the type. For Cellular a mobile network
|
||||
* scan will be requested if supported.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-requestNetworkScan
|
||||
*/
|
||||
chrome.networkingPrivate.requestNetworkScan = function(networkType) {};
|
||||
|
||||
@ -1155,6 +1241,7 @@ chrome.networkingPrivate.requestNetworkScan = function(networkType) {};
|
||||
* If the connect request immediately failed (e.g. the network is
|
||||
* unconfigured), $(ref:runtime.lastError) will be set with a failure
|
||||
* reason.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-startConnect
|
||||
*/
|
||||
chrome.networkingPrivate.startConnect = function(networkGuid, callback) {};
|
||||
|
||||
@ -1163,6 +1250,7 @@ chrome.networkingPrivate.startConnect = function(networkGuid, callback) {};
|
||||
* @param {string} networkGuid The GUID of the network to disconnect from.
|
||||
* @param {function():void=} callback Called when the disconnect request has
|
||||
* been sent. See note for $(ref:startConnect).
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-startDisconnect
|
||||
*/
|
||||
chrome.networkingPrivate.startDisconnect = function(networkGuid, callback) {};
|
||||
|
||||
@ -1175,6 +1263,7 @@ chrome.networkingPrivate.startDisconnect = function(networkGuid, callback) {};
|
||||
* @param {string=} carrier Optional name of carrier to activate.
|
||||
* @param {function():void=} callback Called when the activation request has
|
||||
* been sent. See note for $(ref:startConnect).
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-startActivate
|
||||
*/
|
||||
chrome.networkingPrivate.startActivate = function(networkGuid, carrier, callback) {};
|
||||
|
||||
@ -1186,6 +1275,7 @@ chrome.networkingPrivate.startActivate = function(networkGuid, carrier, callback
|
||||
* @param {function(boolean):void} callback A callback function that indicates
|
||||
* whether or not the device is a trusted device.
|
||||
* @deprecated Use networking.castPrivate API.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-verifyDestination
|
||||
*/
|
||||
chrome.networkingPrivate.verifyDestination = function(properties, callback) {};
|
||||
|
||||
@ -1199,6 +1289,7 @@ chrome.networkingPrivate.verifyDestination = function(properties, callback) {};
|
||||
* @param {function(string):void} callback A callback function that receives
|
||||
* base64-encoded encrypted credential data to send to a trusted device.
|
||||
* @deprecated Use networking.castPrivate API.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-verifyAndEncryptCredentials
|
||||
*/
|
||||
chrome.networkingPrivate.verifyAndEncryptCredentials = function(properties, networkGuid, callback) {};
|
||||
|
||||
@ -1212,6 +1303,7 @@ chrome.networkingPrivate.verifyAndEncryptCredentials = function(properties, netw
|
||||
* @param {function(string):void} callback A callback function that receives
|
||||
* base64-encoded encrypted data to send to a trusted device.
|
||||
* @deprecated Use networking.castPrivate API.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-verifyAndEncryptData
|
||||
*/
|
||||
chrome.networkingPrivate.verifyAndEncryptData = function(properties, data, callback) {};
|
||||
|
||||
@ -1227,6 +1319,7 @@ chrome.networkingPrivate.verifyAndEncryptData = function(properties, data, callb
|
||||
* indicates that the lookup timed out. Otherwise a valid status is
|
||||
* returned (see $(ref:getWifiTDLSStatus)).
|
||||
* @deprecated Use networking.castPrivate API.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-setWifiTDLSEnabledState
|
||||
*/
|
||||
chrome.networkingPrivate.setWifiTDLSEnabledState = function(ip_or_mac_address, enabled, callback) {};
|
||||
|
||||
@ -1237,6 +1330,7 @@ chrome.networkingPrivate.setWifiTDLSEnabledState = function(ip_or_mac_address, e
|
||||
* string with the current TDLS status which can be 'Connected',
|
||||
* 'Disabled', 'Disconnected', 'Nonexistent', or 'Unknown'.
|
||||
* @deprecated Use networking.castPrivate API.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-getWifiTDLSStatus
|
||||
*/
|
||||
chrome.networkingPrivate.getWifiTDLSStatus = function(ip_or_mac_address, callback) {};
|
||||
|
||||
@ -1247,6 +1341,7 @@ chrome.networkingPrivate.getWifiTDLSStatus = function(ip_or_mac_address, callbac
|
||||
* @param {function(!chrome.networkingPrivate.CaptivePortalStatus):void}
|
||||
* callback A callback function that returns the results of the query for
|
||||
* network captive portal status.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-getCaptivePortalStatus
|
||||
*/
|
||||
chrome.networkingPrivate.getCaptivePortalStatus = function(networkGuid, callback) {};
|
||||
|
||||
@ -1261,6 +1356,7 @@ chrome.networkingPrivate.getCaptivePortalStatus = function(networkGuid, callback
|
||||
* @param {string} pin The current SIM PIN, or the new PIN if PUK is provided.
|
||||
* @param {string=} puk The operator provided PUK for unblocking a blocked SIM.
|
||||
* @param {function():void=} callback Called when the operation has completed.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-unlockCellularSim
|
||||
*/
|
||||
chrome.networkingPrivate.unlockCellularSim = function(networkGuid, pin, puk, callback) {};
|
||||
|
||||
@ -1277,6 +1373,7 @@ chrome.networkingPrivate.unlockCellularSim = function(networkGuid, pin, puk, cal
|
||||
* @param {!chrome.networkingPrivate.CellularSimState} simState The SIM state to
|
||||
* set.
|
||||
* @param {function():void=} callback Called when the operation has completed.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-setCellularSimState
|
||||
*/
|
||||
chrome.networkingPrivate.setCellularSimState = function(networkGuid, simState, callback) {};
|
||||
|
||||
@ -1288,6 +1385,7 @@ chrome.networkingPrivate.setCellularSimState = function(networkGuid, simState, c
|
||||
* network for. If empty, the default cellular device will be used.
|
||||
* @param {string} networkId The networkId to select.
|
||||
* @param {function():void=} callback Called when the operation has completed.
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-selectCellularMobileNetwork
|
||||
*/
|
||||
chrome.networkingPrivate.selectCellularMobileNetwork = function(networkGuid, networkId, callback) {};
|
||||
|
||||
@ -1295,12 +1393,14 @@ chrome.networkingPrivate.selectCellularMobileNetwork = function(networkGuid, net
|
||||
* Gets the global policy properties. These properties are not expected to
|
||||
* change during a session.
|
||||
* @param {function(!chrome.networkingPrivate.GlobalPolicy):void} callback
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-getGlobalPolicy
|
||||
*/
|
||||
chrome.networkingPrivate.getGlobalPolicy = function(callback) {};
|
||||
|
||||
/**
|
||||
* Gets the lists of certificates available for network configuration.
|
||||
* @param {function(!chrome.networkingPrivate.CertificateLists):void} callback
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#method-getCertificateLists
|
||||
*/
|
||||
chrome.networkingPrivate.getCertificateLists = function(callback) {};
|
||||
|
||||
@ -1308,6 +1408,7 @@ chrome.networkingPrivate.getCertificateLists = function(callback) {};
|
||||
* Fired when the properties change on any of the networks. Sends a list of
|
||||
* GUIDs for networks whose properties have changed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#event-onNetworksChanged
|
||||
*/
|
||||
chrome.networkingPrivate.onNetworksChanged;
|
||||
|
||||
@ -1315,6 +1416,7 @@ chrome.networkingPrivate.onNetworksChanged;
|
||||
* Fired when the list of networks has changed. Sends a complete list of GUIDs
|
||||
* for all the current networks.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#event-onNetworkListChanged
|
||||
*/
|
||||
chrome.networkingPrivate.onNetworkListChanged;
|
||||
|
||||
@ -1322,6 +1424,7 @@ chrome.networkingPrivate.onNetworkListChanged;
|
||||
* Fired when the list of devices has changed or any device state properties
|
||||
* have changed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#event-onDeviceStateListChanged
|
||||
*/
|
||||
chrome.networkingPrivate.onDeviceStateListChanged;
|
||||
|
||||
@ -1329,11 +1432,13 @@ chrome.networkingPrivate.onDeviceStateListChanged;
|
||||
* Fired when a portal detection for a network completes. Sends the guid of the
|
||||
* network and the corresponding captive portal status.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#event-onPortalDetectionCompleted
|
||||
*/
|
||||
chrome.networkingPrivate.onPortalDetectionCompleted;
|
||||
|
||||
/**
|
||||
* Fired when any certificate list has changed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/networkingPrivate#event-onCertificateListsChanged
|
||||
*/
|
||||
chrome.networkingPrivate.onCertificateListsChanged;
|
||||
|
||||
@ -18,6 +18,7 @@ chrome.passwordsPrivate = {};
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#type-ExportProgressStatus
|
||||
*/
|
||||
chrome.passwordsPrivate.ExportProgressStatus = {
|
||||
NOT_STARTED: 'NOT_STARTED',
|
||||
@ -33,6 +34,7 @@ chrome.passwordsPrivate.ExportProgressStatus = {
|
||||
* shown: string,
|
||||
* link: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#type-UrlCollection
|
||||
*/
|
||||
chrome.passwordsPrivate.UrlCollection;
|
||||
|
||||
@ -41,6 +43,7 @@ chrome.passwordsPrivate.UrlCollection;
|
||||
* urls: !chrome.passwordsPrivate.UrlCollection,
|
||||
* username: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#type-LoginPair
|
||||
*/
|
||||
chrome.passwordsPrivate.LoginPair;
|
||||
|
||||
@ -51,6 +54,7 @@ chrome.passwordsPrivate.LoginPair;
|
||||
* federationText: (string|undefined),
|
||||
* index: number
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#type-PasswordUiEntry
|
||||
*/
|
||||
chrome.passwordsPrivate.PasswordUiEntry;
|
||||
|
||||
@ -59,6 +63,7 @@ chrome.passwordsPrivate.PasswordUiEntry;
|
||||
* index: number,
|
||||
* plaintextPassword: string
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#type-PlaintextPasswordEventParameters
|
||||
*/
|
||||
chrome.passwordsPrivate.PlaintextPasswordEventParameters;
|
||||
|
||||
@ -67,6 +72,7 @@ chrome.passwordsPrivate.PlaintextPasswordEventParameters;
|
||||
* urls: !chrome.passwordsPrivate.UrlCollection,
|
||||
* index: number
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#type-ExceptionEntry
|
||||
*/
|
||||
chrome.passwordsPrivate.ExceptionEntry;
|
||||
|
||||
@ -75,6 +81,7 @@ chrome.passwordsPrivate.ExceptionEntry;
|
||||
* status: !chrome.passwordsPrivate.ExportProgressStatus,
|
||||
* message: (string|undefined),
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#type-PasswordExportProgress
|
||||
*/
|
||||
chrome.passwordsPrivate.PasswordExportProgress;
|
||||
|
||||
@ -82,6 +89,7 @@ chrome.passwordsPrivate.PasswordExportProgress;
|
||||
* Removes the saved password corresponding to |loginPair|. If no saved password
|
||||
* for this pair exists, this function is a no-op.
|
||||
* @param {number} index The index for the password entry being removed.
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#method-removeSavedPassword
|
||||
*/
|
||||
chrome.passwordsPrivate.removeSavedPassword = function(index) {};
|
||||
|
||||
@ -89,11 +97,13 @@ chrome.passwordsPrivate.removeSavedPassword = function(index) {};
|
||||
* Removes the saved password exception corresponding to |exceptionUrl|. If no
|
||||
* exception with this URL exists, this function is a no-op.
|
||||
* @param {number} index The index for the exception url entry being removed.
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#method-removePasswordException
|
||||
*/
|
||||
chrome.passwordsPrivate.removePasswordException = function(index) {};
|
||||
|
||||
/**
|
||||
* Undoes the last removal of a saved password or exception.
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#method-undoRemoveSavedPasswordOrException
|
||||
*/
|
||||
chrome.passwordsPrivate.undoRemoveSavedPasswordOrException = function() {};
|
||||
|
||||
@ -104,6 +114,7 @@ chrome.passwordsPrivate.undoRemoveSavedPasswordOrException = function() {};
|
||||
* onPlaintextPasswordRetrieved event. TODO(hcarmona): Investigate using a
|
||||
* callback for consistency.
|
||||
* @param {number} index The index for the password entry being being retrieved.
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#method-requestPlaintextPassword
|
||||
*/
|
||||
chrome.passwordsPrivate.requestPlaintextPassword = function(index) {};
|
||||
|
||||
@ -111,6 +122,7 @@ chrome.passwordsPrivate.requestPlaintextPassword = function(index) {};
|
||||
* Returns the list of saved passwords.
|
||||
* @param {function(!Array<!chrome.passwordsPrivate.PasswordUiEntry>):void}
|
||||
* callback Called with the list of saved passwords.
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#method-getSavedPasswordList
|
||||
*/
|
||||
chrome.passwordsPrivate.getSavedPasswordList = function(callback) {};
|
||||
|
||||
@ -118,11 +130,13 @@ chrome.passwordsPrivate.getSavedPasswordList = function(callback) {};
|
||||
* Returns the list of password exceptions.
|
||||
* @param {function(!Array<!chrome.passwordsPrivate.ExceptionEntry>):void}
|
||||
* callback Called with the list of password exceptions.
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#method-getPasswordExceptionList
|
||||
*/
|
||||
chrome.passwordsPrivate.getPasswordExceptionList = function(callback) {};
|
||||
|
||||
/**
|
||||
* Triggers the Password Manager password import functionality.
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#method-importPasswords
|
||||
*/
|
||||
chrome.passwordsPrivate.importPasswords = function() {};
|
||||
|
||||
@ -132,11 +146,13 @@ chrome.passwordsPrivate.importPasswords = function() {};
|
||||
* callback Called with no error, if the new export request was accepted and
|
||||
* started. If rejected, <code>chrome.runtime.lastError</code> will be
|
||||
* set to 'in-progress'.
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#method-exportPasswords
|
||||
*/
|
||||
chrome.passwordsPrivate.exportPasswords = function(callback) {};
|
||||
|
||||
/**
|
||||
* Triggers the cancelling of a password export flow.
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#method-cancelExportPasswords
|
||||
*/
|
||||
chrome.passwordsPrivate.cancelExportPasswords = function() {};
|
||||
|
||||
@ -144,6 +160,7 @@ chrome.passwordsPrivate.cancelExportPasswords = function() {};
|
||||
* Triggers the Password Manager password export status query functionality.
|
||||
* @param {function(!chrome.passwordsPrivate.ExportProgressStatus):void}
|
||||
* callback Called with the status of the current export.
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#method-requestExportProgressStatus
|
||||
*/
|
||||
chrome.passwordsPrivate.requestExportProgressStatus = function(callback) {};
|
||||
|
||||
@ -151,6 +168,7 @@ chrome.passwordsPrivate.requestExportProgressStatus = function(callback) {};
|
||||
* Fired when the saved passwords list has changed, meaning that an entry has
|
||||
* been added or removed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#event-onSavedPasswordsListChanged
|
||||
*/
|
||||
chrome.passwordsPrivate.onSavedPasswordsListChanged;
|
||||
|
||||
@ -158,6 +176,7 @@ chrome.passwordsPrivate.onSavedPasswordsListChanged;
|
||||
* Fired when the password exceptions list has changed, meaning that an entry
|
||||
* has been added or removed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#event-onPasswordExceptionsListChanged
|
||||
*/
|
||||
chrome.passwordsPrivate.onPasswordExceptionsListChanged;
|
||||
|
||||
@ -165,6 +184,7 @@ chrome.passwordsPrivate.onPasswordExceptionsListChanged;
|
||||
* Fired when a plaintext password has been fetched in response to a call to
|
||||
* chrome.passwordsPrivate.requestPlaintextPassword().
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#event-onPlaintextPasswordRetrieved
|
||||
*/
|
||||
chrome.passwordsPrivate.onPlaintextPasswordRetrieved;
|
||||
|
||||
@ -172,5 +192,6 @@ chrome.passwordsPrivate.onPlaintextPasswordRetrieved;
|
||||
/**
|
||||
* Fired when status of the export has progressed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/passwordsPrivate#event-onPasswordsExportCompleted
|
||||
*/
|
||||
chrome.passwordsPrivate.onPasswordsFileExportProgress;
|
||||
|
||||
@ -21,11 +21,13 @@ chrome.quickUnlockPrivate = {};
|
||||
* token: string,
|
||||
* lifetimeSeconds: number
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#type-TokenInfo
|
||||
*/
|
||||
chrome.quickUnlockPrivate.TokenInfo;
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#type-QuickUnlockMode
|
||||
*/
|
||||
chrome.quickUnlockPrivate.QuickUnlockMode = {
|
||||
PIN: 'PIN',
|
||||
@ -33,6 +35,7 @@ chrome.quickUnlockPrivate.QuickUnlockMode = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#type-CredentialProblem
|
||||
*/
|
||||
chrome.quickUnlockPrivate.CredentialProblem = {
|
||||
TOO_SHORT: 'TOO_SHORT',
|
||||
@ -46,6 +49,7 @@ chrome.quickUnlockPrivate.CredentialProblem = {
|
||||
* errors: !Array<!chrome.quickUnlockPrivate.CredentialProblem>,
|
||||
* warnings: !Array<!chrome.quickUnlockPrivate.CredentialProblem>
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#type-CredentialCheck
|
||||
*/
|
||||
chrome.quickUnlockPrivate.CredentialCheck;
|
||||
|
||||
@ -54,6 +58,7 @@ chrome.quickUnlockPrivate.CredentialCheck;
|
||||
* minLength: number,
|
||||
* maxLength: number
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#type-CredentialRequirements
|
||||
*/
|
||||
chrome.quickUnlockPrivate.CredentialRequirements;
|
||||
|
||||
@ -62,6 +67,7 @@ chrome.quickUnlockPrivate.CredentialRequirements;
|
||||
* seconds until the token expires.
|
||||
* @param {string} accountPassword The account password for the logged in user.
|
||||
* @param {function(!chrome.quickUnlockPrivate.TokenInfo):void} onComplete
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-getAuthToken
|
||||
*/
|
||||
chrome.quickUnlockPrivate.getAuthToken = function(accountPassword, onComplete) {};
|
||||
|
||||
@ -73,6 +79,7 @@ chrome.quickUnlockPrivate.getAuthToken = function(accountPassword, onComplete) {
|
||||
* @param {string} token The token returned by $(ref:getAuthToken).
|
||||
* @param {boolean} enabled
|
||||
* @param {function():void=} onComplete
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-setLockScreenEnabled
|
||||
*/
|
||||
chrome.quickUnlockPrivate.setLockScreenEnabled = function(token, enabled, onComplete) {};
|
||||
|
||||
@ -81,6 +88,7 @@ chrome.quickUnlockPrivate.setLockScreenEnabled = function(token, enabled, onComp
|
||||
* Some quick unlock modes may be disabled by policy.
|
||||
* @param {function(!Array<!chrome.quickUnlockPrivate.QuickUnlockMode>):void}
|
||||
* onComplete
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-getAvailableModes
|
||||
*/
|
||||
chrome.quickUnlockPrivate.getAvailableModes = function(onComplete) {};
|
||||
|
||||
@ -89,6 +97,7 @@ chrome.quickUnlockPrivate.getAvailableModes = function(onComplete) {};
|
||||
* lock screen.
|
||||
* @param {function(!Array<!chrome.quickUnlockPrivate.QuickUnlockMode>):void}
|
||||
* onComplete
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-getActiveModes
|
||||
*/
|
||||
chrome.quickUnlockPrivate.getActiveModes = function(onComplete) {};
|
||||
|
||||
@ -101,6 +110,7 @@ chrome.quickUnlockPrivate.getActiveModes = function(onComplete) {};
|
||||
* @param {function(!chrome.quickUnlockPrivate.CredentialCheck):void} onComplete
|
||||
* Called with a list of warnings and errors the given |credential| has
|
||||
* (or an empty list if there are none).
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-checkCredential
|
||||
*/
|
||||
chrome.quickUnlockPrivate.checkCredential = function(mode, credential, onComplete) {};
|
||||
|
||||
@ -111,6 +121,7 @@ chrome.quickUnlockPrivate.checkCredential = function(mode, credential, onComplet
|
||||
* @param {function(!chrome.quickUnlockPrivate.CredentialRequirements):void}
|
||||
* onComplete Called with the credential requirements of the given
|
||||
* |mode|.
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-getCredentialRequirements
|
||||
*/
|
||||
chrome.quickUnlockPrivate.getCredentialRequirements = function(mode, onComplete) {};
|
||||
|
||||
@ -125,11 +136,13 @@ chrome.quickUnlockPrivate.getCredentialRequirements = function(mode, onComplete)
|
||||
* @param {function():void} onComplete Called with true if the quick unlock
|
||||
* state was updated, false otherwise. The update is treated as a single
|
||||
* atomic operation.
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-setModes
|
||||
*/
|
||||
chrome.quickUnlockPrivate.setModes = function(token, modes, credentials, onComplete) {};
|
||||
|
||||
/**
|
||||
* Called after the active set of quick unlock modes has changed.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/quickUnlockPrivate#event-onActiveModesChanged
|
||||
*/
|
||||
chrome.quickUnlockPrivate.onActiveModesChanged;
|
||||
|
||||
@ -22,6 +22,7 @@ chrome.safeBrowsingPrivate = {};
|
||||
* userName: string,
|
||||
* isPhishing: boolean
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/safeBrowsingPrivate#type-PolicySpecifiedPasswordReuse
|
||||
*/
|
||||
chrome.safeBrowsingPrivate.PolicySpecifiedPasswordReuse;
|
||||
|
||||
@ -32,6 +33,7 @@ chrome.safeBrowsingPrivate.PolicySpecifiedPasswordReuse;
|
||||
* sha256: string,
|
||||
* userName: (string|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/safeBrowsingPrivate#type-DangerousDownloadInfo
|
||||
*/
|
||||
chrome.safeBrowsingPrivate.DangerousDownloadInfo;
|
||||
|
||||
@ -41,35 +43,41 @@ chrome.safeBrowsingPrivate.DangerousDownloadInfo;
|
||||
* reason: string,
|
||||
* netErrorCode: (number|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/safeBrowsingPrivate#type-InterstitialInfo
|
||||
*/
|
||||
chrome.safeBrowsingPrivate.InterstitialInfo;
|
||||
|
||||
/**
|
||||
* Fired when Chrome detects a reuse of a policy specified password.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/safeBrowsingPrivate#event-onPolicySpecifiedPasswordReuseDetected
|
||||
*/
|
||||
chrome.safeBrowsingPrivate.onPolicySpecifiedPasswordReuseDetected;
|
||||
|
||||
/**
|
||||
* Fired when the user changed their policy specified password.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/safeBrowsingPrivate#event-onPolicySpecifiedPasswordChanged
|
||||
*/
|
||||
chrome.safeBrowsingPrivate.onPolicySpecifiedPasswordChanged;
|
||||
|
||||
/**
|
||||
* Fired when the user opened a dangerous download.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/safeBrowsingPrivate#event-onDangerousDownloadOpened
|
||||
*/
|
||||
chrome.safeBrowsingPrivate.onDangerousDownloadOpened;
|
||||
|
||||
/**
|
||||
* Fired when a security interstitial is shown to the user.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/safeBrowsingPrivate#event-onInterstitialShown
|
||||
*/
|
||||
chrome.safeBrowsingPrivate.onInterstitialShown;
|
||||
|
||||
/**
|
||||
* Fired when the user clicked-through a security interstitial.
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/safeBrowsingPrivate#event-onInterstitialProceeded
|
||||
*/
|
||||
chrome.safeBrowsingPrivate.onInterstitialProceeded;
|
||||
|
||||
@ -18,6 +18,7 @@ chrome.settingsPrivate = {};
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/settingsPrivate#type-PrefType
|
||||
*/
|
||||
chrome.settingsPrivate.PrefType = {
|
||||
BOOLEAN: 'BOOLEAN',
|
||||
@ -30,6 +31,7 @@ chrome.settingsPrivate.PrefType = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/settingsPrivate#type-ControlledBy
|
||||
*/
|
||||
chrome.settingsPrivate.ControlledBy = {
|
||||
DEVICE_POLICY: 'DEVICE_POLICY',
|
||||
@ -41,6 +43,7 @@ chrome.settingsPrivate.ControlledBy = {
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @see https://developer.chrome.com/extensions/settingsPrivate#type-Enforcement
|
||||
*/
|
||||
chrome.settingsPrivate.Enforcement = {
|
||||
ENFORCED: 'ENFORCED',
|
||||
@ -59,6 +62,7 @@ chrome.settingsPrivate.Enforcement = {
|
||||
* extensionId: (string|undefined),
|
||||
* extensionCanBeDisabled: (boolean|undefined)
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/settingsPrivate#type-PrefObject
|
||||
*/
|
||||
chrome.settingsPrivate.PrefObject;
|
||||
|
||||
@ -69,12 +73,14 @@ chrome.settingsPrivate.PrefObject;
|
||||
* @param {string} pageId The user metrics identifier or null.
|
||||
* @param {function(boolean):void} callback The callback for whether the pref
|
||||
* was set or not.
|
||||
* @see https://developer.chrome.com/extensions/settingsPrivate#method-setPref
|
||||
*/
|
||||
chrome.settingsPrivate.setPref = function(name, value, pageId, callback) {};
|
||||
|
||||
/**
|
||||
* Gets an array of all the prefs.
|
||||
* @param {function(!Array<!chrome.settingsPrivate.PrefObject>):void} callback
|
||||
* @see https://developer.chrome.com/extensions/settingsPrivate#method-getAllPrefs
|
||||
*/
|
||||
chrome.settingsPrivate.getAllPrefs = function(callback) {};
|
||||
|
||||
@ -82,6 +88,7 @@ chrome.settingsPrivate.getAllPrefs = function(callback) {};
|
||||
* Gets the value of a specific pref.
|
||||
* @param {string} name
|
||||
* @param {function(!chrome.settingsPrivate.PrefObject):void} callback
|
||||
* @see https://developer.chrome.com/extensions/settingsPrivate#method-getPref
|
||||
*/
|
||||
chrome.settingsPrivate.getPref = function(name, callback) {};
|
||||
|
||||
@ -89,6 +96,7 @@ chrome.settingsPrivate.getPref = function(name, callback) {};
|
||||
* Gets the default page zoom factor. Possible values are currently between 0.25
|
||||
* and 5. For a full list, see zoom::kPresetZoomFactors.
|
||||
* @param {function(number):void} callback
|
||||
* @see https://developer.chrome.com/extensions/settingsPrivate#method-getDefaultZoom
|
||||
*/
|
||||
chrome.settingsPrivate.getDefaultZoom = function(callback) {};
|
||||
|
||||
@ -97,6 +105,7 @@ chrome.settingsPrivate.getDefaultZoom = function(callback) {};
|
||||
* zoom::kPresetZoomFactors.
|
||||
* @param {number} zoom
|
||||
* @param {function(boolean):void=} callback
|
||||
* @see https://developer.chrome.com/extensions/settingsPrivate#method-setDefaultZoom
|
||||
*/
|
||||
chrome.settingsPrivate.setDefaultZoom = function(zoom, callback) {};
|
||||
|
||||
@ -104,5 +113,6 @@ chrome.settingsPrivate.setDefaultZoom = function(zoom, callback) {};
|
||||
* <p>Fired when a set of prefs has changed.</p><p>|prefs| The prefs that
|
||||
* changed.</p>
|
||||
* @type {!ChromeEvent}
|
||||
* @see https://developer.chrome.com/extensions/settingsPrivate#event-onPrefsChanged
|
||||
*/
|
||||
chrome.settingsPrivate.onPrefsChanged;
|
||||
|
||||
@ -25,12 +25,14 @@ chrome.usersPrivate = {};
|
||||
* isSupervised: boolean,
|
||||
* isChild: boolean
|
||||
* }}
|
||||
* @see https://developer.chrome.com/extensions/usersPrivate#type-User
|
||||
*/
|
||||
chrome.usersPrivate.User;
|
||||
|
||||
/**
|
||||
* Gets a list of the currently whitelisted users.
|
||||
* @param {function(!Array<!chrome.usersPrivate.User>):void} callback
|
||||
* @see https://developer.chrome.com/extensions/usersPrivate#method-getWhitelistedUsers
|
||||
*/
|
||||
chrome.usersPrivate.getWhitelistedUsers = function(callback) {};
|
||||
|
||||
@ -40,6 +42,7 @@ chrome.usersPrivate.getWhitelistedUsers = function(callback) {};
|
||||
* because the user was already present, or the current user isn't the owner).
|
||||
* @param {string} email
|
||||
* @param {function(boolean):void} callback
|
||||
* @see https://developer.chrome.com/extensions/usersPrivate#method-addWhitelistedUser
|
||||
*/
|
||||
chrome.usersPrivate.addWhitelistedUser = function(email, callback) {};
|
||||
|
||||
@ -50,17 +53,20 @@ chrome.usersPrivate.addWhitelistedUser = function(email, callback) {};
|
||||
* owner).
|
||||
* @param {string} email
|
||||
* @param {function(boolean):void} callback
|
||||
* @see https://developer.chrome.com/extensions/usersPrivate#method-removeWhitelistedUser
|
||||
*/
|
||||
chrome.usersPrivate.removeWhitelistedUser = function(email, callback) {};
|
||||
|
||||
/**
|
||||
* Whether the whitelist is managed by enterprise.
|
||||
* @param {function(boolean):void} callback
|
||||
* @see https://developer.chrome.com/extensions/usersPrivate#method-isWhitelistManaged
|
||||
*/
|
||||
chrome.usersPrivate.isWhitelistManaged = function(callback) {};
|
||||
|
||||
/**
|
||||
* Returns the current user.
|
||||
* @param {function(!chrome.usersPrivate.User):void} callback
|
||||
* @see https://developer.chrome.com/extensions/usersPrivate#method-getCurrentUser
|
||||
*/
|
||||
chrome.usersPrivate.getCurrentUser = function(callback) {};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user