- e2f6b8ac647271815b4fed2991f405524dd762c3 Release cctz microbenchmarks. by Alex Strelnikov <strel@google.com>
- 924ba2a3f9fca695d73c6bf491d20669e2b96b8e Changed RawPtr to use std::addressof() instead of operato... by Abseil Team <absl-team@google.com> - e8cf67f9fa74d4c5632da35547025ad2301c6819 Import of CCTZ from GitHub. by Alex Strelnikov <strel@google.com> - 2ece8a96611afcddd7b91e0197dadb896248250c Abandon ".inc" files in favor of ".h" headers. by Jorg Brown <jorg@google.com> - 37f5ed5da4058f90fb3e6a2733fce5b1fd0aaedf Add exception safety tests for absl::optional<T> by Abseil Team <absl-team@google.com> - 337f995a866b8f905f64ca6b271b5fec8f248a60 Update WORKSPACE to grab specific commits of dependencies... by Alex Strelnikov <strel@google.com> - 93e5b134607a554993387ad913e6c1621606004b Release Charmap microbenchmark. by Alex Strelnikov <strel@google.com> - 95c2e29b6d93ec1334484ee37d91f63101c45307 Release OStringStream microbenchmarks. by Alex Strelnikov <strel@google.com> - 250f51839ed26dd1e6b658d35aa291413e5f4825 Internal change by Greg Falcon <gfalcon@google.com> - ce34900fa3d1a95a8446bc943cdd801fac95be25 Improve compatibility of cctz cc_test targets for portabl... by Shaindel Schwartz <shaindel@google.com> - ce7e31dbf2c1ee93c79aae5b7dc7c603cb4babcf Improve portability of cc_tests. (Mark more tests that ca... by Abseil Team <absl-team@google.com> - dfcd4e455923703c1a1dcd523c5f915f7990fa2a Accept strings with custom allocators as arguments to abs... by Greg Falcon <gfalcon@google.com> - 2946b41ed3d5b8b5a8dc11182e443cf1ab6e3bde Link against benchmark_main instead of using BENCHMARK_MA... by Alex Strelnikov <strel@google.com> - f09de9e03bf8edd363069c4b352d8009423f531c Adds link to doc about the formats allowed by SimpleAtof(... by Greg Miller <jgm@google.com> - 59b0977e7a308e0800277886cf60226b2cc426a1 Simplify the HideMask() calculation so that it doesn't us... by Jorg Brown <jorg@google.com> GitOrigin-RevId: e2f6b8ac647271815b4fed2991f405524dd762c3 Change-Id: Ib9c8547ed7fe217fad6cb3ab1362e96181aa5cfa
This commit is contained in:
		
							parent
							
								
									99477fa9f1
								
							
						
					
					
						commit
						7aacab8ae0
					
				
					 37 changed files with 1879 additions and 349 deletions
				
			
		
							
								
								
									
										12
									
								
								WORKSPACE
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								WORKSPACE
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -13,20 +13,20 @@ http_archive(
 | 
			
		|||
# GoogleTest/GoogleMock framework. Used by most unit-tests.
 | 
			
		||||
http_archive(
 | 
			
		||||
     name = "com_google_googletest",
 | 
			
		||||
     urls = ["https://github.com/google/googletest/archive/master.zip"],
 | 
			
		||||
     strip_prefix = "googletest-master",
 | 
			
		||||
     urls = ["https://github.com/google/googletest/archive/4e4df226fc197c0dda6e37f5c8c3845ca1e73a49.zip"],
 | 
			
		||||
     strip_prefix = "googletest-4e4df226fc197c0dda6e37f5c8c3845ca1e73a49",
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# Google benchmark.
 | 
			
		||||
http_archive(
 | 
			
		||||
    name = "com_github_google_benchmark",
 | 
			
		||||
    urls = ["https://github.com/google/benchmark/archive/master.zip"],
 | 
			
		||||
    strip_prefix = "benchmark-master",
 | 
			
		||||
    urls = ["https://github.com/google/benchmark/archive/16703ff83c1ae6d53e5155df3bb3ab0bc96083be.zip"],
 | 
			
		||||
    strip_prefix = "benchmark-16703ff83c1ae6d53e5155df3bb3ab0bc96083be",
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# RE2 regular-expression framework. Used by some unit-tests.
 | 
			
		||||
http_archive(
 | 
			
		||||
    name = "com_googlesource_code_re2",
 | 
			
		||||
    urls = ["https://github.com/google/re2/archive/master.zip"],
 | 
			
		||||
    strip_prefix = "re2-master",
 | 
			
		||||
    urls = ["https://github.com/google/re2/archive/6cf8ccd82dbaab2668e9b13596c68183c9ecd13f.zip"],
 | 
			
		||||
    strip_prefix = "re2-6cf8ccd82dbaab2668e9b13596c68183c9ecd13f",
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ cc_test(
 | 
			
		|||
    deps = [
 | 
			
		||||
        ":algorithm",
 | 
			
		||||
        "//absl/base:core_headers",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -124,5 +124,3 @@ BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, EightBits)
 | 
			
		|||
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -392,11 +392,6 @@ cc_test(
 | 
			
		|||
        "//absl:windows": [],
 | 
			
		||||
        "//conditions:default": ["-pthread"],
 | 
			
		||||
    }),
 | 
			
		||||
    tags = [
 | 
			
		||||
        "no_test_android_arm",
 | 
			
		||||
        "no_test_android_arm64",
 | 
			
		||||
        "no_test_android_x86",
 | 
			
		||||
    ],
 | 
			
		||||
    deps = [":malloc_internal"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -426,6 +421,6 @@ cc_test(
 | 
			
		|||
    deps = [
 | 
			
		||||
        ":base",
 | 
			
		||||
        "//absl/synchronization",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,9 +23,7 @@ namespace base_internal {
 | 
			
		|||
// Arbitrary value with high bits set. Xor'ing with it is unlikely
 | 
			
		||||
// to map one valid pointer to another valid pointer.
 | 
			
		||||
constexpr uintptr_t HideMask() {
 | 
			
		||||
  static_assert(sizeof(uintptr_t) == 4 || sizeof(uintptr_t) == 8,
 | 
			
		||||
                "uintptr_t must be 32 or 64 bits");
 | 
			
		||||
  return sizeof(uintptr_t) == 8 ? 0xF03A5F7BF03A5F7BULL : 0xF03A5F7BUL;
 | 
			
		||||
  return (uintptr_t{0xF03A5F7BU} << (sizeof(uintptr_t) - 4) * 8) | 0xF03A5F7BU;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Hide a pointer from the leak checker. For internal use only.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,5 +36,3 @@ void BM_UnsafeCurrentThreadIdentity(benchmark::State& state) {
 | 
			
		|||
BENCHMARK(BM_UnsafeCurrentThreadIdentity);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,11 +42,6 @@ cc_test(
 | 
			
		|||
    name = "fixed_array_test",
 | 
			
		||||
    srcs = ["fixed_array_test.cc"],
 | 
			
		||||
    copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
 | 
			
		||||
    tags = [
 | 
			
		||||
        "no_test_android_arm",
 | 
			
		||||
        "no_test_android_arm64",
 | 
			
		||||
        "no_test_android_x86",
 | 
			
		||||
    ],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":fixed_array",
 | 
			
		||||
        "//absl/base:exception_testing",
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +69,7 @@ cc_test(
 | 
			
		|||
    tags = ["benchmark"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":fixed_array",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +126,7 @@ cc_test(
 | 
			
		|||
        ":inlined_vector",
 | 
			
		||||
        "//absl/base",
 | 
			
		||||
        "//absl/strings",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,5 +64,3 @@ BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 256)->Range(0, 1 << 16);
 | 
			
		|||
BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 65536)->Range(0, 1 << 16);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -372,5 +372,3 @@ void BM_StdVectorEmpty(benchmark::State& state) {
 | 
			
		|||
BENCHMARK(BM_StdVectorEmpty);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -179,9 +179,9 @@ typename memory_internal::MakeUniqueResult<T>::invalid make_unique(
 | 
			
		|||
// useful within templates that need to handle a complement of raw pointers,
 | 
			
		||||
// `std::nullptr_t`, and smart pointers.
 | 
			
		||||
template <typename T>
 | 
			
		||||
auto RawPtr(T&& ptr) -> decltype(&*ptr) {
 | 
			
		||||
auto RawPtr(T&& ptr) -> decltype(std::addressof(*ptr)) {
 | 
			
		||||
  // ptr is a forwarding reference to support Ts with non-const operators.
 | 
			
		||||
  return (ptr != nullptr) ? &*ptr : nullptr;
 | 
			
		||||
  return (ptr != nullptr) ? std::addressof(*ptr) : nullptr;
 | 
			
		||||
}
 | 
			
		||||
inline std::nullptr_t RawPtr(std::nullptr_t) { return nullptr; }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -111,7 +111,7 @@ cc_test(
 | 
			
		|||
    size = "small",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "escaping_test.cc",
 | 
			
		||||
        "internal/escaping_test_common.inc",
 | 
			
		||||
        "internal/escaping_test_common.h",
 | 
			
		||||
    ],
 | 
			
		||||
    copts = ABSL_TEST_COPTS,
 | 
			
		||||
    visibility = ["//visibility:private"],
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +127,7 @@ cc_test(
 | 
			
		|||
    name = "escaping_benchmark",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "escaping_benchmark.cc",
 | 
			
		||||
        "internal/escaping_test_common.inc",
 | 
			
		||||
        "internal/escaping_test_common.h",
 | 
			
		||||
    ],
 | 
			
		||||
    copts = ABSL_TEST_COPTS,
 | 
			
		||||
    tags = ["benchmark"],
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +135,7 @@ cc_test(
 | 
			
		|||
    deps = [
 | 
			
		||||
        ":strings",
 | 
			
		||||
        "//absl/base",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -199,7 +199,7 @@ cc_test(
 | 
			
		|||
        ":strings",
 | 
			
		||||
        "//absl/base",
 | 
			
		||||
        "//absl/base:core_headers",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -240,7 +240,7 @@ cc_test(
 | 
			
		|||
    deps = [
 | 
			
		||||
        ":strings",
 | 
			
		||||
        "//absl/base",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -278,7 +278,7 @@ cc_test(
 | 
			
		|||
    deps = [
 | 
			
		||||
        ":strings",
 | 
			
		||||
        "//absl/base",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -294,6 +294,18 @@ cc_test(
 | 
			
		|||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_test(
 | 
			
		||||
    name = "ostringstream_benchmark",
 | 
			
		||||
    srcs = ["internal/ostringstream_benchmark.cc"],
 | 
			
		||||
    copts = ABSL_TEST_COPTS,
 | 
			
		||||
    tags = ["benchmark"],
 | 
			
		||||
    visibility = ["//visibility:private"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":internal",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_test(
 | 
			
		||||
    name = "resize_uninitialized_test",
 | 
			
		||||
    size = "small",
 | 
			
		||||
| 
						 | 
				
			
			@ -333,7 +345,7 @@ cc_test(
 | 
			
		|||
    deps = [
 | 
			
		||||
        ":strings",
 | 
			
		||||
        "//absl/memory",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -358,7 +370,7 @@ cc_test(
 | 
			
		|||
    visibility = ["//visibility:private"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":strings",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -366,7 +378,7 @@ cc_test(
 | 
			
		|||
    name = "numbers_test",
 | 
			
		||||
    size = "small",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "internal/numbers_test_common.inc",
 | 
			
		||||
        "internal/numbers_test_common.h",
 | 
			
		||||
        "numbers_test.cc",
 | 
			
		||||
    ],
 | 
			
		||||
    copts = ABSL_TEST_COPTS,
 | 
			
		||||
| 
						 | 
				
			
			@ -411,3 +423,14 @@ cc_test(
 | 
			
		|||
        "@com_google_googletest//:gtest_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_test(
 | 
			
		||||
    name = "char_map_benchmark",
 | 
			
		||||
    srcs = ["internal/char_map_benchmark.cc"],
 | 
			
		||||
    copts = ABSL_TEST_COPTS,
 | 
			
		||||
    tags = ["benchmark"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":internal",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@
 | 
			
		|||
 | 
			
		||||
#include "benchmark/benchmark.h"
 | 
			
		||||
#include "absl/base/internal/raw_logging.h"
 | 
			
		||||
#include "absl/strings/internal/escaping_test_common.inc"
 | 
			
		||||
#include "absl/strings/internal/escaping_test_common.h"
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ BENCHMARK(BM_CUnescapeHexString);
 | 
			
		|||
void BM_WebSafeBase64Escape_string(benchmark::State& state) {
 | 
			
		||||
  std::string raw;
 | 
			
		||||
  for (int i = 0; i < 10; ++i) {
 | 
			
		||||
    for (const auto& test_set : base64_strings) {
 | 
			
		||||
    for (const auto& test_set : absl::strings_internal::base64_strings()) {
 | 
			
		||||
      raw += std::string(test_set.plaintext);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -92,5 +92,3 @@ void BM_CEscape_MostEscaped(benchmark::State& state) {
 | 
			
		|||
BENCHMARK(BM_CEscape_MostEscaped)->Range(1, 1 << 14);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,7 @@
 | 
			
		|||
#include "absl/container/fixed_array.h"
 | 
			
		||||
#include "absl/strings/str_cat.h"
 | 
			
		||||
 | 
			
		||||
#include "absl/strings/internal/escaping_test_common.inc"
 | 
			
		||||
#include "absl/strings/internal/escaping_test_common.h"
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -575,7 +575,7 @@ TEST(Base64, EscapeAndUnescape) {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  // Now try the long strings, this tests the streaming
 | 
			
		||||
  for (const auto& tc : base64_strings) {
 | 
			
		||||
  for (const auto& tc : absl::strings_internal::base64_strings()) {
 | 
			
		||||
    std::string buffer;
 | 
			
		||||
    absl::WebSafeBase64Escape(tc.plaintext, &buffer);
 | 
			
		||||
    EXPECT_EQ(tc.cyphertext, buffer);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										61
									
								
								absl/strings/internal/char_map_benchmark.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								absl/strings/internal/char_map_benchmark.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
// Copyright 2017 The Abseil Authors.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
#include "absl/strings/internal/char_map.h"
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
#include "benchmark/benchmark.h"
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
absl::strings_internal::Charmap MakeBenchmarkMap() {
 | 
			
		||||
  absl::strings_internal::Charmap m;
 | 
			
		||||
  uint32_t x[] = {0x0, 0x1, 0x2, 0x3, 0xf, 0xe, 0xd, 0xc};
 | 
			
		||||
  for (uint32_t& t : x) t *= static_cast<uint32_t>(0x11111111UL);
 | 
			
		||||
  for (uint32_t i = 0; i < 256; ++i) {
 | 
			
		||||
    if ((x[i / 32] >> (i % 32)) & 1)
 | 
			
		||||
      m = m | absl::strings_internal::Charmap::Char(i);
 | 
			
		||||
  }
 | 
			
		||||
  return m;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Micro-benchmark for Charmap::contains.
 | 
			
		||||
void BM_Contains(benchmark::State& state) {
 | 
			
		||||
  // Loop-body replicated 10 times to increase time per iteration.
 | 
			
		||||
  // Argument continuously changed to avoid generating common subexpressions.
 | 
			
		||||
  const absl::strings_internal::Charmap benchmark_map = MakeBenchmarkMap();
 | 
			
		||||
  unsigned char c = 0;
 | 
			
		||||
  int ops = 0;
 | 
			
		||||
  for (auto _ : state) {
 | 
			
		||||
    ops += benchmark_map.contains(c++);
 | 
			
		||||
    ops += benchmark_map.contains(c++);
 | 
			
		||||
    ops += benchmark_map.contains(c++);
 | 
			
		||||
    ops += benchmark_map.contains(c++);
 | 
			
		||||
    ops += benchmark_map.contains(c++);
 | 
			
		||||
    ops += benchmark_map.contains(c++);
 | 
			
		||||
    ops += benchmark_map.contains(c++);
 | 
			
		||||
    ops += benchmark_map.contains(c++);
 | 
			
		||||
    ops += benchmark_map.contains(c++);
 | 
			
		||||
    ops += benchmark_map.contains(c++);
 | 
			
		||||
  }
 | 
			
		||||
  benchmark::DoNotOptimize(ops);
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Contains);
 | 
			
		||||
 | 
			
		||||
// We don't bother benchmarking Charmap::IsZero or Charmap::IntersectsWith;
 | 
			
		||||
// their running time is data-dependent and it is not worth characterizing
 | 
			
		||||
// "typical" data.
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
							
								
								
									
										131
									
								
								absl/strings/internal/escaping_test_common.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								absl/strings/internal/escaping_test_common.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,131 @@
 | 
			
		|||
// Copyright 2017 The Abseil Authors.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
//
 | 
			
		||||
// This test contains common things needed by both escaping_test.cc and
 | 
			
		||||
// escaping_benchmark.cc.
 | 
			
		||||
 | 
			
		||||
#ifndef ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_
 | 
			
		||||
#define ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include "absl/strings/string_view.h"
 | 
			
		||||
 | 
			
		||||
namespace absl {
 | 
			
		||||
namespace strings_internal {
 | 
			
		||||
 | 
			
		||||
struct base64_testcase {
 | 
			
		||||
  absl::string_view plaintext;
 | 
			
		||||
  absl::string_view cyphertext;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline const std::array<base64_testcase, 5>& base64_strings() {
 | 
			
		||||
  static const std::array<base64_testcase, 5> testcase{{
 | 
			
		||||
      // Some google quotes
 | 
			
		||||
      // Cyphertext created with "uuencode (GNU sharutils) 4.6.3"
 | 
			
		||||
      // (Note that we're testing the websafe encoding, though, so if
 | 
			
		||||
      // you add messages, be sure to run "tr -- '+/' '-_'" on the output)
 | 
			
		||||
      { "I was always good at math and science, and I never realized "
 | 
			
		||||
        "that was unusual or somehow undesirable. So one of the things "
 | 
			
		||||
        "I care a lot about is helping to remove that stigma, "
 | 
			
		||||
        "to show girls that you can be feminine, you can like the things "
 | 
			
		||||
        "that girls like, but you can also be really good at technology. "
 | 
			
		||||
        "You can be really good at building things."
 | 
			
		||||
        " - Marissa Meyer, Newsweek, 2010-12-22" "\n",
 | 
			
		||||
 | 
			
		||||
        "SSB3YXMgYWx3YXlzIGdvb2QgYXQgbWF0aCBhbmQgc2NpZW5jZSwgYW5kIEkg"
 | 
			
		||||
        "bmV2ZXIgcmVhbGl6ZWQgdGhhdCB3YXMgdW51c3VhbCBvciBzb21laG93IHVu"
 | 
			
		||||
        "ZGVzaXJhYmxlLiBTbyBvbmUgb2YgdGhlIHRoaW5ncyBJIGNhcmUgYSBsb3Qg"
 | 
			
		||||
        "YWJvdXQgaXMgaGVscGluZyB0byByZW1vdmUgdGhhdCBzdGlnbWEsIHRvIHNo"
 | 
			
		||||
        "b3cgZ2lybHMgdGhhdCB5b3UgY2FuIGJlIGZlbWluaW5lLCB5b3UgY2FuIGxp"
 | 
			
		||||
        "a2UgdGhlIHRoaW5ncyB0aGF0IGdpcmxzIGxpa2UsIGJ1dCB5b3UgY2FuIGFs"
 | 
			
		||||
        "c28gYmUgcmVhbGx5IGdvb2QgYXQgdGVjaG5vbG9neS4gWW91IGNhbiBiZSBy"
 | 
			
		||||
        "ZWFsbHkgZ29vZCBhdCBidWlsZGluZyB0aGluZ3MuIC0gTWFyaXNzYSBNZXll"
 | 
			
		||||
        "ciwgTmV3c3dlZWssIDIwMTAtMTItMjIK" },
 | 
			
		||||
 | 
			
		||||
      { "Typical first year for a new cluster: "
 | 
			
		||||
        "~0.5 overheating "
 | 
			
		||||
        "~1 PDU failure "
 | 
			
		||||
        "~1 rack-move "
 | 
			
		||||
        "~1 network rewiring "
 | 
			
		||||
        "~20 rack failures "
 | 
			
		||||
        "~5 racks go wonky "
 | 
			
		||||
        "~8 network maintenances "
 | 
			
		||||
        "~12 router reloads "
 | 
			
		||||
        "~3 router failures "
 | 
			
		||||
        "~dozens of minor 30-second blips for dns "
 | 
			
		||||
        "~1000 individual machine failures "
 | 
			
		||||
        "~thousands of hard drive failures "
 | 
			
		||||
        "slow disks, bad memory, misconfigured machines, flaky machines, etc."
 | 
			
		||||
        " - Jeff Dean, The Joys of Real Hardware" "\n",
 | 
			
		||||
 | 
			
		||||
        "VHlwaWNhbCBmaXJzdCB5ZWFyIGZvciBhIG5ldyBjbHVzdGVyOiB-MC41IG92"
 | 
			
		||||
        "ZXJoZWF0aW5nIH4xIFBEVSBmYWlsdXJlIH4xIHJhY2stbW92ZSB-MSBuZXR3"
 | 
			
		||||
        "b3JrIHJld2lyaW5nIH4yMCByYWNrIGZhaWx1cmVzIH41IHJhY2tzIGdvIHdv"
 | 
			
		||||
        "bmt5IH44IG5ldHdvcmsgbWFpbnRlbmFuY2VzIH4xMiByb3V0ZXIgcmVsb2Fk"
 | 
			
		||||
        "cyB-MyByb3V0ZXIgZmFpbHVyZXMgfmRvemVucyBvZiBtaW5vciAzMC1zZWNv"
 | 
			
		||||
        "bmQgYmxpcHMgZm9yIGRucyB-MTAwMCBpbmRpdmlkdWFsIG1hY2hpbmUgZmFp"
 | 
			
		||||
        "bHVyZXMgfnRob3VzYW5kcyBvZiBoYXJkIGRyaXZlIGZhaWx1cmVzIHNsb3cg"
 | 
			
		||||
        "ZGlza3MsIGJhZCBtZW1vcnksIG1pc2NvbmZpZ3VyZWQgbWFjaGluZXMsIGZs"
 | 
			
		||||
        "YWt5IG1hY2hpbmVzLCBldGMuIC0gSmVmZiBEZWFuLCBUaGUgSm95cyBvZiBS"
 | 
			
		||||
        "ZWFsIEhhcmR3YXJlCg" },
 | 
			
		||||
 | 
			
		||||
      { "I'm the head of the webspam team at Google.  "
 | 
			
		||||
        "That means that if you type your name into Google and get porn back, "
 | 
			
		||||
        "it's my fault. Unless you're a porn star, in which case porn is a "
 | 
			
		||||
        "completely reasonable response."
 | 
			
		||||
        " - Matt Cutts, Google Plus" "\n",
 | 
			
		||||
 | 
			
		||||
        "SSdtIHRoZSBoZWFkIG9mIHRoZSB3ZWJzcGFtIHRlYW0gYXQgR29vZ2xlLiAg"
 | 
			
		||||
        "VGhhdCBtZWFucyB0aGF0IGlmIHlvdSB0eXBlIHlvdXIgbmFtZSBpbnRvIEdv"
 | 
			
		||||
        "b2dsZSBhbmQgZ2V0IHBvcm4gYmFjaywgaXQncyBteSBmYXVsdC4gVW5sZXNz"
 | 
			
		||||
        "IHlvdSdyZSBhIHBvcm4gc3RhciwgaW4gd2hpY2ggY2FzZSBwb3JuIGlzIGEg"
 | 
			
		||||
        "Y29tcGxldGVseSByZWFzb25hYmxlIHJlc3BvbnNlLiAtIE1hdHQgQ3V0dHMs"
 | 
			
		||||
        "IEdvb2dsZSBQbHVzCg" },
 | 
			
		||||
 | 
			
		||||
      { "It will still be a long time before machines approach human "
 | 
			
		||||
        "intelligence. "
 | 
			
		||||
        "But luckily, machines don't actually have to be intelligent; "
 | 
			
		||||
        "they just have to fake it. Access to a wealth of information, "
 | 
			
		||||
        "combined with a rudimentary decision-making capacity, "
 | 
			
		||||
        "can often be almost as useful. Of course, the results are better yet "
 | 
			
		||||
        "when coupled with intelligence. A reference librarian with access to "
 | 
			
		||||
        "a good search engine is a formidable tool."
 | 
			
		||||
        " - Craig Silverstein, Siemens Pictures of the Future, Spring 2004"
 | 
			
		||||
        "\n",
 | 
			
		||||
 | 
			
		||||
        "SXQgd2lsbCBzdGlsbCBiZSBhIGxvbmcgdGltZSBiZWZvcmUgbWFjaGluZXMg"
 | 
			
		||||
        "YXBwcm9hY2ggaHVtYW4gaW50ZWxsaWdlbmNlLiBCdXQgbHVja2lseSwgbWFj"
 | 
			
		||||
        "aGluZXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSB0byBiZSBpbnRlbGxpZ2VudDsg"
 | 
			
		||||
        "dGhleSBqdXN0IGhhdmUgdG8gZmFrZSBpdC4gQWNjZXNzIHRvIGEgd2VhbHRo"
 | 
			
		||||
        "IG9mIGluZm9ybWF0aW9uLCBjb21iaW5lZCB3aXRoIGEgcnVkaW1lbnRhcnkg"
 | 
			
		||||
        "ZGVjaXNpb24tbWFraW5nIGNhcGFjaXR5LCBjYW4gb2Z0ZW4gYmUgYWxtb3N0"
 | 
			
		||||
        "IGFzIHVzZWZ1bC4gT2YgY291cnNlLCB0aGUgcmVzdWx0cyBhcmUgYmV0dGVy"
 | 
			
		||||
        "IHlldCB3aGVuIGNvdXBsZWQgd2l0aCBpbnRlbGxpZ2VuY2UuIEEgcmVmZXJl"
 | 
			
		||||
        "bmNlIGxpYnJhcmlhbiB3aXRoIGFjY2VzcyB0byBhIGdvb2Qgc2VhcmNoIGVu"
 | 
			
		||||
        "Z2luZSBpcyBhIGZvcm1pZGFibGUgdG9vbC4gLSBDcmFpZyBTaWx2ZXJzdGVp"
 | 
			
		||||
        "biwgU2llbWVucyBQaWN0dXJlcyBvZiB0aGUgRnV0dXJlLCBTcHJpbmcgMjAw"
 | 
			
		||||
        "NAo" },
 | 
			
		||||
 | 
			
		||||
      // Degenerate edge case
 | 
			
		||||
      { "",
 | 
			
		||||
        "" },
 | 
			
		||||
  }};
 | 
			
		||||
 | 
			
		||||
  return testcase;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace strings_internal
 | 
			
		||||
}  // namespace absl
 | 
			
		||||
 | 
			
		||||
#endif  // ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,113 +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.
 | 
			
		||||
//
 | 
			
		||||
// This test contains common things needed by both escaping_test.cc and
 | 
			
		||||
// escaping_benchmark.cc.
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
struct {
 | 
			
		||||
  absl::string_view plaintext;
 | 
			
		||||
  absl::string_view cyphertext;
 | 
			
		||||
} const base64_strings[] = {
 | 
			
		||||
  // Some google quotes
 | 
			
		||||
  // Cyphertext created with "uuencode (GNU sharutils) 4.6.3"
 | 
			
		||||
  // (Note that we're testing the websafe encoding, though, so if
 | 
			
		||||
  // you add messages, be sure to run "tr -- '+/' '-_'" on the output)
 | 
			
		||||
  { "I was always good at math and science, and I never realized "
 | 
			
		||||
    "that was unusual or somehow undesirable. So one of the things "
 | 
			
		||||
    "I care a lot about is helping to remove that stigma, "
 | 
			
		||||
    "to show girls that you can be feminine, you can like the things "
 | 
			
		||||
    "that girls like, but you can also be really good at technology. "
 | 
			
		||||
    "You can be really good at building things."
 | 
			
		||||
    " - Marissa Meyer, Newsweek, 2010-12-22" "\n",
 | 
			
		||||
 | 
			
		||||
    "SSB3YXMgYWx3YXlzIGdvb2QgYXQgbWF0aCBhbmQgc2NpZW5jZSwgYW5kIEkg"
 | 
			
		||||
    "bmV2ZXIgcmVhbGl6ZWQgdGhhdCB3YXMgdW51c3VhbCBvciBzb21laG93IHVu"
 | 
			
		||||
    "ZGVzaXJhYmxlLiBTbyBvbmUgb2YgdGhlIHRoaW5ncyBJIGNhcmUgYSBsb3Qg"
 | 
			
		||||
    "YWJvdXQgaXMgaGVscGluZyB0byByZW1vdmUgdGhhdCBzdGlnbWEsIHRvIHNo"
 | 
			
		||||
    "b3cgZ2lybHMgdGhhdCB5b3UgY2FuIGJlIGZlbWluaW5lLCB5b3UgY2FuIGxp"
 | 
			
		||||
    "a2UgdGhlIHRoaW5ncyB0aGF0IGdpcmxzIGxpa2UsIGJ1dCB5b3UgY2FuIGFs"
 | 
			
		||||
    "c28gYmUgcmVhbGx5IGdvb2QgYXQgdGVjaG5vbG9neS4gWW91IGNhbiBiZSBy"
 | 
			
		||||
    "ZWFsbHkgZ29vZCBhdCBidWlsZGluZyB0aGluZ3MuIC0gTWFyaXNzYSBNZXll"
 | 
			
		||||
    "ciwgTmV3c3dlZWssIDIwMTAtMTItMjIK" },
 | 
			
		||||
 | 
			
		||||
  { "Typical first year for a new cluster: "
 | 
			
		||||
    "~0.5 overheating "
 | 
			
		||||
    "~1 PDU failure "
 | 
			
		||||
    "~1 rack-move "
 | 
			
		||||
    "~1 network rewiring "
 | 
			
		||||
    "~20 rack failures "
 | 
			
		||||
    "~5 racks go wonky "
 | 
			
		||||
    "~8 network maintenances "
 | 
			
		||||
    "~12 router reloads "
 | 
			
		||||
    "~3 router failures "
 | 
			
		||||
    "~dozens of minor 30-second blips for dns "
 | 
			
		||||
    "~1000 individual machine failures "
 | 
			
		||||
    "~thousands of hard drive failures "
 | 
			
		||||
    "slow disks, bad memory, misconfigured machines, flaky machines, etc."
 | 
			
		||||
    " - Jeff Dean, The Joys of Real Hardware" "\n",
 | 
			
		||||
 | 
			
		||||
    "VHlwaWNhbCBmaXJzdCB5ZWFyIGZvciBhIG5ldyBjbHVzdGVyOiB-MC41IG92"
 | 
			
		||||
    "ZXJoZWF0aW5nIH4xIFBEVSBmYWlsdXJlIH4xIHJhY2stbW92ZSB-MSBuZXR3"
 | 
			
		||||
    "b3JrIHJld2lyaW5nIH4yMCByYWNrIGZhaWx1cmVzIH41IHJhY2tzIGdvIHdv"
 | 
			
		||||
    "bmt5IH44IG5ldHdvcmsgbWFpbnRlbmFuY2VzIH4xMiByb3V0ZXIgcmVsb2Fk"
 | 
			
		||||
    "cyB-MyByb3V0ZXIgZmFpbHVyZXMgfmRvemVucyBvZiBtaW5vciAzMC1zZWNv"
 | 
			
		||||
    "bmQgYmxpcHMgZm9yIGRucyB-MTAwMCBpbmRpdmlkdWFsIG1hY2hpbmUgZmFp"
 | 
			
		||||
    "bHVyZXMgfnRob3VzYW5kcyBvZiBoYXJkIGRyaXZlIGZhaWx1cmVzIHNsb3cg"
 | 
			
		||||
    "ZGlza3MsIGJhZCBtZW1vcnksIG1pc2NvbmZpZ3VyZWQgbWFjaGluZXMsIGZs"
 | 
			
		||||
    "YWt5IG1hY2hpbmVzLCBldGMuIC0gSmVmZiBEZWFuLCBUaGUgSm95cyBvZiBS"
 | 
			
		||||
    "ZWFsIEhhcmR3YXJlCg" },
 | 
			
		||||
 | 
			
		||||
  { "I'm the head of the webspam team at Google.  "
 | 
			
		||||
    "That means that if you type your name into Google and get porn back, "
 | 
			
		||||
    "it's my fault. Unless you're a porn star, in which case porn is a "
 | 
			
		||||
    "completely reasonable response."
 | 
			
		||||
    " - Matt Cutts, Google Plus" "\n",
 | 
			
		||||
 | 
			
		||||
    "SSdtIHRoZSBoZWFkIG9mIHRoZSB3ZWJzcGFtIHRlYW0gYXQgR29vZ2xlLiAg"
 | 
			
		||||
    "VGhhdCBtZWFucyB0aGF0IGlmIHlvdSB0eXBlIHlvdXIgbmFtZSBpbnRvIEdv"
 | 
			
		||||
    "b2dsZSBhbmQgZ2V0IHBvcm4gYmFjaywgaXQncyBteSBmYXVsdC4gVW5sZXNz"
 | 
			
		||||
    "IHlvdSdyZSBhIHBvcm4gc3RhciwgaW4gd2hpY2ggY2FzZSBwb3JuIGlzIGEg"
 | 
			
		||||
    "Y29tcGxldGVseSByZWFzb25hYmxlIHJlc3BvbnNlLiAtIE1hdHQgQ3V0dHMs"
 | 
			
		||||
    "IEdvb2dsZSBQbHVzCg" },
 | 
			
		||||
 | 
			
		||||
  { "It will still be a long time before machines approach human intelligence. "
 | 
			
		||||
    "But luckily, machines don't actually have to be intelligent; "
 | 
			
		||||
    "they just have to fake it. Access to a wealth of information, "
 | 
			
		||||
    "combined with a rudimentary decision-making capacity, "
 | 
			
		||||
    "can often be almost as useful. Of course, the results are better yet "
 | 
			
		||||
    "when coupled with intelligence. A reference librarian with access to "
 | 
			
		||||
    "a good search engine is a formidable tool."
 | 
			
		||||
    " - Craig Silverstein, Siemens Pictures of the Future, Spring 2004" "\n",
 | 
			
		||||
 | 
			
		||||
    "SXQgd2lsbCBzdGlsbCBiZSBhIGxvbmcgdGltZSBiZWZvcmUgbWFjaGluZXMg"
 | 
			
		||||
    "YXBwcm9hY2ggaHVtYW4gaW50ZWxsaWdlbmNlLiBCdXQgbHVja2lseSwgbWFj"
 | 
			
		||||
    "aGluZXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSB0byBiZSBpbnRlbGxpZ2VudDsg"
 | 
			
		||||
    "dGhleSBqdXN0IGhhdmUgdG8gZmFrZSBpdC4gQWNjZXNzIHRvIGEgd2VhbHRo"
 | 
			
		||||
    "IG9mIGluZm9ybWF0aW9uLCBjb21iaW5lZCB3aXRoIGEgcnVkaW1lbnRhcnkg"
 | 
			
		||||
    "ZGVjaXNpb24tbWFraW5nIGNhcGFjaXR5LCBjYW4gb2Z0ZW4gYmUgYWxtb3N0"
 | 
			
		||||
    "IGFzIHVzZWZ1bC4gT2YgY291cnNlLCB0aGUgcmVzdWx0cyBhcmUgYmV0dGVy"
 | 
			
		||||
    "IHlldCB3aGVuIGNvdXBsZWQgd2l0aCBpbnRlbGxpZ2VuY2UuIEEgcmVmZXJl"
 | 
			
		||||
    "bmNlIGxpYnJhcmlhbiB3aXRoIGFjY2VzcyB0byBhIGdvb2Qgc2VhcmNoIGVu"
 | 
			
		||||
    "Z2luZSBpcyBhIGZvcm1pZGFibGUgdG9vbC4gLSBDcmFpZyBTaWx2ZXJzdGVp"
 | 
			
		||||
    "biwgU2llbWVucyBQaWN0dXJlcyBvZiB0aGUgRnV0dXJlLCBTcHJpbmcgMjAw"
 | 
			
		||||
    "NAo" },
 | 
			
		||||
 | 
			
		||||
  // Degenerate edge case
 | 
			
		||||
  { "",
 | 
			
		||||
    "" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
							
								
								
									
										178
									
								
								absl/strings/internal/numbers_test_common.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								absl/strings/internal/numbers_test_common.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,178 @@
 | 
			
		|||
// Copyright 2017 The Abseil Authors.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
//
 | 
			
		||||
// This file contains common things needed by numbers_test.cc,
 | 
			
		||||
// numbers_legacy_test.cc and numbers_benchmark.cc.
 | 
			
		||||
 | 
			
		||||
#ifndef ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_
 | 
			
		||||
#define ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
namespace absl {
 | 
			
		||||
namespace strings_internal {
 | 
			
		||||
 | 
			
		||||
template <typename IntType>
 | 
			
		||||
inline bool Itoa(IntType value, int base, std::string* destination) {
 | 
			
		||||
  destination->clear();
 | 
			
		||||
  if (base <= 1 || base > 36) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (value == 0) {
 | 
			
		||||
    destination->push_back('0');
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool negative = value < 0;
 | 
			
		||||
  while (value != 0) {
 | 
			
		||||
    const IntType next_value = value / base;
 | 
			
		||||
    // Can't use std::abs here because of problems when IntType is unsigned.
 | 
			
		||||
    int remainder = value > next_value * base ? value - next_value * base
 | 
			
		||||
                                              : next_value * base - value;
 | 
			
		||||
    char c = remainder < 10 ? '0' + remainder : 'A' + remainder - 10;
 | 
			
		||||
    destination->insert(0, 1, c);
 | 
			
		||||
    value = next_value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (negative) {
 | 
			
		||||
    destination->insert(0, 1, '-');
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct uint32_test_case {
 | 
			
		||||
  const char* str;
 | 
			
		||||
  bool expect_ok;
 | 
			
		||||
  int base;  // base to pass to the conversion function
 | 
			
		||||
  uint32_t expected;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline const std::array<uint32_test_case, 27>& strtouint32_test_cases() {
 | 
			
		||||
  static const std::array<uint32_test_case, 27> test_cases{{
 | 
			
		||||
      {"0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()},
 | 
			
		||||
      {"0x34234324", true, 16, 0x34234324},
 | 
			
		||||
      {"34234324", true, 16, 0x34234324},
 | 
			
		||||
      {"0", true, 16, 0},
 | 
			
		||||
      {" \t\n 0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()},
 | 
			
		||||
      {" \f\v 46", true, 10, 46},  // must accept weird whitespace
 | 
			
		||||
      {" \t\n 72717222", true, 8, 072717222},
 | 
			
		||||
      {" \t\n 072717222", true, 8, 072717222},
 | 
			
		||||
      {" \t\n 072717228", false, 8, 07271722},
 | 
			
		||||
      {"0", true, 0, 0},
 | 
			
		||||
 | 
			
		||||
      // Base-10 version.
 | 
			
		||||
      {"34234324", true, 0, 34234324},
 | 
			
		||||
      {"4294967295", true, 0, std::numeric_limits<uint32_t>::max()},
 | 
			
		||||
      {"34234324 \n\t", true, 10, 34234324},
 | 
			
		||||
 | 
			
		||||
      // Unusual base
 | 
			
		||||
      {"0", true, 3, 0},
 | 
			
		||||
      {"2", true, 3, 2},
 | 
			
		||||
      {"11", true, 3, 4},
 | 
			
		||||
 | 
			
		||||
      // Invalid uints.
 | 
			
		||||
      {"", false, 0, 0},
 | 
			
		||||
      {"  ", false, 0, 0},
 | 
			
		||||
      {"abc", false, 0, 0},  // would be valid hex, but prefix is missing
 | 
			
		||||
      {"34234324a", false, 0, 34234324},
 | 
			
		||||
      {"34234.3", false, 0, 34234},
 | 
			
		||||
      {"-1", false, 0, 0},
 | 
			
		||||
      {"   -123", false, 0, 0},
 | 
			
		||||
      {" \t\n -123", false, 0, 0},
 | 
			
		||||
 | 
			
		||||
      // Out of bounds.
 | 
			
		||||
      {"4294967296", false, 0, std::numeric_limits<uint32_t>::max()},
 | 
			
		||||
      {"0x100000000", false, 0, std::numeric_limits<uint32_t>::max()},
 | 
			
		||||
      {nullptr, false, 0, 0},
 | 
			
		||||
  }};
 | 
			
		||||
  return test_cases;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct uint64_test_case {
 | 
			
		||||
  const char* str;
 | 
			
		||||
  bool expect_ok;
 | 
			
		||||
  int base;
 | 
			
		||||
  uint64_t expected;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline const std::array<uint64_test_case, 34>& strtouint64_test_cases() {
 | 
			
		||||
  static const std::array<uint64_test_case, 34> test_cases{{
 | 
			
		||||
      {"0x3423432448783446", true, 16, int64_t{0x3423432448783446}},
 | 
			
		||||
      {"3423432448783446", true, 16, int64_t{0x3423432448783446}},
 | 
			
		||||
 | 
			
		||||
      {"0", true, 16, 0},
 | 
			
		||||
      {"000", true, 0, 0},
 | 
			
		||||
      {"0", true, 0, 0},
 | 
			
		||||
      {" \t\n 0xffffffffffffffff", true, 16,
 | 
			
		||||
       std::numeric_limits<uint64_t>::max()},
 | 
			
		||||
 | 
			
		||||
      {"012345670123456701234", true, 8, int64_t{012345670123456701234}},
 | 
			
		||||
      {"12345670123456701234", true, 8, int64_t{012345670123456701234}},
 | 
			
		||||
 | 
			
		||||
      {"12845670123456701234", false, 8, 0},
 | 
			
		||||
 | 
			
		||||
      // Base-10 version.
 | 
			
		||||
      {"34234324487834466", true, 0, int64_t{34234324487834466}},
 | 
			
		||||
 | 
			
		||||
      {" \t\n 18446744073709551615", true, 0,
 | 
			
		||||
       std::numeric_limits<uint64_t>::max()},
 | 
			
		||||
 | 
			
		||||
      {"34234324487834466 \n\t ", true, 0, int64_t{34234324487834466}},
 | 
			
		||||
 | 
			
		||||
      {" \f\v 46", true, 10, 46},  // must accept weird whitespace
 | 
			
		||||
 | 
			
		||||
      // Unusual base
 | 
			
		||||
      {"0", true, 3, 0},
 | 
			
		||||
      {"2", true, 3, 2},
 | 
			
		||||
      {"11", true, 3, 4},
 | 
			
		||||
 | 
			
		||||
      {"0", true, 0, 0},
 | 
			
		||||
 | 
			
		||||
      // Invalid uints.
 | 
			
		||||
      {"", false, 0, 0},
 | 
			
		||||
      {"  ", false, 0, 0},
 | 
			
		||||
      {"abc", false, 0, 0},
 | 
			
		||||
      {"34234324487834466a", false, 0, 0},
 | 
			
		||||
      {"34234487834466.3", false, 0, 0},
 | 
			
		||||
      {"-1", false, 0, 0},
 | 
			
		||||
      {"   -123", false, 0, 0},
 | 
			
		||||
      {" \t\n -123", false, 0, 0},
 | 
			
		||||
 | 
			
		||||
      // Out of bounds.
 | 
			
		||||
      {"18446744073709551616", false, 10, 0},
 | 
			
		||||
      {"18446744073709551616", false, 0, 0},
 | 
			
		||||
      {"0x10000000000000000", false, 16, std::numeric_limits<uint64_t>::max()},
 | 
			
		||||
      {"0X10000000000000000", false, 16,
 | 
			
		||||
       std::numeric_limits<uint64_t>::max()},  // 0X versus 0x.
 | 
			
		||||
      {"0x10000000000000000", false, 0, std::numeric_limits<uint64_t>::max()},
 | 
			
		||||
      {"0X10000000000000000", false, 0,
 | 
			
		||||
       std::numeric_limits<uint64_t>::max()},  // 0X versus 0x.
 | 
			
		||||
 | 
			
		||||
      {"0x1234", true, 16, 0x1234},
 | 
			
		||||
 | 
			
		||||
      // Base-10 std::string version.
 | 
			
		||||
      {"1234", true, 0, 1234},
 | 
			
		||||
      {nullptr, false, 0, 0},
 | 
			
		||||
  }};
 | 
			
		||||
  return test_cases;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace strings_internal
 | 
			
		||||
}  // namespace absl
 | 
			
		||||
 | 
			
		||||
#endif  // ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,156 +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.
 | 
			
		||||
//
 | 
			
		||||
// This file contains common things needed by numbers_test.cc,
 | 
			
		||||
// numbers_legacy_test.cc and numbers_benchmark.cc.
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
template <typename IntType>
 | 
			
		||||
bool Itoa(IntType value, int base, std::string* destination) {
 | 
			
		||||
  destination->clear();
 | 
			
		||||
  if (base <= 1 || base > 36) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (value == 0) {
 | 
			
		||||
    destination->push_back('0');
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool negative = value < 0;
 | 
			
		||||
  while (value != 0) {
 | 
			
		||||
    const IntType next_value = value / base;
 | 
			
		||||
    // Can't use std::abs here because of problems when IntType is unsigned.
 | 
			
		||||
    int remainder = value > next_value * base ? value - next_value * base
 | 
			
		||||
                                              : next_value * base - value;
 | 
			
		||||
    char c = remainder < 10 ? '0' + remainder : 'A' + remainder - 10;
 | 
			
		||||
    destination->insert(0, 1, c);
 | 
			
		||||
    value = next_value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (negative) {
 | 
			
		||||
    destination->insert(0, 1, '-');
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct uint32_test_case {
 | 
			
		||||
  const char* str;
 | 
			
		||||
  bool expect_ok;
 | 
			
		||||
  int base;  // base to pass to the conversion function
 | 
			
		||||
  uint32_t expected;
 | 
			
		||||
} const strtouint32_test_cases[] = {
 | 
			
		||||
    {"0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()},
 | 
			
		||||
    {"0x34234324", true, 16, 0x34234324},
 | 
			
		||||
    {"34234324", true, 16, 0x34234324},
 | 
			
		||||
    {"0", true, 16, 0},
 | 
			
		||||
    {" \t\n 0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()},
 | 
			
		||||
    {" \f\v 46", true, 10, 46},  // must accept weird whitespace
 | 
			
		||||
    {" \t\n 72717222", true, 8, 072717222},
 | 
			
		||||
    {" \t\n 072717222", true, 8, 072717222},
 | 
			
		||||
    {" \t\n 072717228", false, 8, 07271722},
 | 
			
		||||
    {"0", true, 0, 0},
 | 
			
		||||
 | 
			
		||||
    // Base-10 version.
 | 
			
		||||
    {"34234324", true, 0, 34234324},
 | 
			
		||||
    {"4294967295", true, 0, std::numeric_limits<uint32_t>::max()},
 | 
			
		||||
    {"34234324 \n\t", true, 10, 34234324},
 | 
			
		||||
 | 
			
		||||
    // Unusual base
 | 
			
		||||
    {"0", true, 3, 0},
 | 
			
		||||
    {"2", true, 3, 2},
 | 
			
		||||
    {"11", true, 3, 4},
 | 
			
		||||
 | 
			
		||||
    // Invalid uints.
 | 
			
		||||
    {"", false, 0, 0},
 | 
			
		||||
    {"  ", false, 0, 0},
 | 
			
		||||
    {"abc", false, 0, 0},  // would be valid hex, but prefix is missing
 | 
			
		||||
    {"34234324a", false, 0, 34234324},
 | 
			
		||||
    {"34234.3", false, 0, 34234},
 | 
			
		||||
    {"-1", false, 0, 0},
 | 
			
		||||
    {"   -123", false, 0, 0},
 | 
			
		||||
    {" \t\n -123", false, 0, 0},
 | 
			
		||||
 | 
			
		||||
    // Out of bounds.
 | 
			
		||||
    {"4294967296", false, 0, std::numeric_limits<uint32_t>::max()},
 | 
			
		||||
    {"0x100000000", false, 0, std::numeric_limits<uint32_t>::max()},
 | 
			
		||||
    {nullptr, false, 0, 0},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct uint64_test_case {
 | 
			
		||||
  const char* str;
 | 
			
		||||
  bool expect_ok;
 | 
			
		||||
  int base;
 | 
			
		||||
  uint64_t expected;
 | 
			
		||||
} const strtouint64_test_cases[] = {
 | 
			
		||||
    {"0x3423432448783446", true, 16, int64_t{0x3423432448783446}},
 | 
			
		||||
    {"3423432448783446", true, 16, int64_t{0x3423432448783446}},
 | 
			
		||||
 | 
			
		||||
    {"0", true, 16, 0},
 | 
			
		||||
    {"000", true, 0, 0},
 | 
			
		||||
    {"0", true, 0, 0},
 | 
			
		||||
    {" \t\n 0xffffffffffffffff", true, 16,
 | 
			
		||||
     std::numeric_limits<uint64_t>::max()},
 | 
			
		||||
 | 
			
		||||
    {"012345670123456701234", true, 8, int64_t{012345670123456701234}},
 | 
			
		||||
    {"12345670123456701234", true, 8, int64_t{012345670123456701234}},
 | 
			
		||||
 | 
			
		||||
    {"12845670123456701234", false, 8, 0},
 | 
			
		||||
 | 
			
		||||
    // Base-10 version.
 | 
			
		||||
    {"34234324487834466", true, 0, int64_t{34234324487834466}},
 | 
			
		||||
 | 
			
		||||
    {" \t\n 18446744073709551615", true, 0,
 | 
			
		||||
     std::numeric_limits<uint64_t>::max()},
 | 
			
		||||
 | 
			
		||||
    {"34234324487834466 \n\t ", true, 0, int64_t{34234324487834466}},
 | 
			
		||||
 | 
			
		||||
    {" \f\v 46", true, 10, 46},  // must accept weird whitespace
 | 
			
		||||
 | 
			
		||||
    // Unusual base
 | 
			
		||||
    {"0", true, 3, 0},
 | 
			
		||||
    {"2", true, 3, 2},
 | 
			
		||||
    {"11", true, 3, 4},
 | 
			
		||||
 | 
			
		||||
    {"0", true, 0, 0},
 | 
			
		||||
 | 
			
		||||
    // Invalid uints.
 | 
			
		||||
    {"", false, 0, 0},
 | 
			
		||||
    {"  ", false, 0, 0},
 | 
			
		||||
    {"abc", false, 0, 0},
 | 
			
		||||
    {"34234324487834466a", false, 0, 0},
 | 
			
		||||
    {"34234487834466.3", false, 0, 0},
 | 
			
		||||
    {"-1", false, 0, 0},
 | 
			
		||||
    {"   -123", false, 0, 0},
 | 
			
		||||
    {" \t\n -123", false, 0, 0},
 | 
			
		||||
 | 
			
		||||
    // Out of bounds.
 | 
			
		||||
    {"18446744073709551616", false, 10, 0},
 | 
			
		||||
    {"18446744073709551616", false, 0, 0},
 | 
			
		||||
    {"0x10000000000000000", false, 16, std::numeric_limits<uint64_t>::max()},
 | 
			
		||||
    {"0X10000000000000000", false, 16,
 | 
			
		||||
     std::numeric_limits<uint64_t>::max()},  // 0X versus 0x.
 | 
			
		||||
    {"0x10000000000000000", false, 0, std::numeric_limits<uint64_t>::max()},
 | 
			
		||||
    {"0X10000000000000000", false, 0,
 | 
			
		||||
     std::numeric_limits<uint64_t>::max()},  // 0X versus 0x.
 | 
			
		||||
 | 
			
		||||
    {"0x1234", true, 16, 0x1234},
 | 
			
		||||
 | 
			
		||||
    // Base-10 std::string version.
 | 
			
		||||
    {"1234", true, 0, 1234},
 | 
			
		||||
    {nullptr, false, 0, 0},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
							
								
								
									
										106
									
								
								absl/strings/internal/ostringstream_benchmark.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								absl/strings/internal/ostringstream_benchmark.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,106 @@
 | 
			
		|||
// Copyright 2018 The Abseil Authors.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
#include "absl/strings/internal/ostringstream.h"
 | 
			
		||||
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "benchmark/benchmark.h"
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
enum StringType {
 | 
			
		||||
  kNone,
 | 
			
		||||
  kStdString,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Benchmarks for std::ostringstream.
 | 
			
		||||
template <StringType kOutput>
 | 
			
		||||
void BM_StdStream(benchmark::State& state) {
 | 
			
		||||
  const int num_writes = state.range(0);
 | 
			
		||||
  const int bytes_per_write = state.range(1);
 | 
			
		||||
  const std::string payload(bytes_per_write, 'x');
 | 
			
		||||
  for (auto _ : state) {
 | 
			
		||||
    std::ostringstream strm;
 | 
			
		||||
    benchmark::DoNotOptimize(strm);
 | 
			
		||||
    for (int i = 0; i != num_writes; ++i) {
 | 
			
		||||
      strm << payload;
 | 
			
		||||
    }
 | 
			
		||||
    switch (kOutput) {
 | 
			
		||||
      case kNone: {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case kStdString: {
 | 
			
		||||
        std::string s = strm.str();
 | 
			
		||||
        benchmark::DoNotOptimize(s);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create the stream, optionally write to it, then destroy it.
 | 
			
		||||
BENCHMARK_TEMPLATE(BM_StdStream, kNone)
 | 
			
		||||
    ->ArgPair(0, 0)
 | 
			
		||||
    ->ArgPair(1, 16)   // 16 bytes is small enough for SSO
 | 
			
		||||
    ->ArgPair(1, 256)  // 256 bytes requires heap allocation
 | 
			
		||||
    ->ArgPair(1024, 256);
 | 
			
		||||
// Create the stream, write to it, get std::string out, then destroy.
 | 
			
		||||
BENCHMARK_TEMPLATE(BM_StdStream, kStdString)
 | 
			
		||||
    ->ArgPair(1, 16)   // 16 bytes is small enough for SSO
 | 
			
		||||
    ->ArgPair(1, 256)  // 256 bytes requires heap allocation
 | 
			
		||||
    ->ArgPair(1024, 256);
 | 
			
		||||
 | 
			
		||||
// Benchmarks for OStringStream.
 | 
			
		||||
template <StringType kOutput>
 | 
			
		||||
void BM_CustomStream(benchmark::State& state) {
 | 
			
		||||
  const int num_writes = state.range(0);
 | 
			
		||||
  const int bytes_per_write = state.range(1);
 | 
			
		||||
  const std::string payload(bytes_per_write, 'x');
 | 
			
		||||
  for (auto _ : state) {
 | 
			
		||||
    std::string out;
 | 
			
		||||
    absl::strings_internal::OStringStream strm(&out);
 | 
			
		||||
    benchmark::DoNotOptimize(strm);
 | 
			
		||||
    for (int i = 0; i != num_writes; ++i) {
 | 
			
		||||
      strm << payload;
 | 
			
		||||
    }
 | 
			
		||||
    switch (kOutput) {
 | 
			
		||||
      case kNone: {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case kStdString: {
 | 
			
		||||
        std::string s = out;
 | 
			
		||||
        benchmark::DoNotOptimize(s);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create the stream, optionally write to it, then destroy it.
 | 
			
		||||
BENCHMARK_TEMPLATE(BM_CustomStream, kNone)
 | 
			
		||||
    ->ArgPair(0, 0)
 | 
			
		||||
    ->ArgPair(1, 16)   // 16 bytes is small enough for SSO
 | 
			
		||||
    ->ArgPair(1, 256)  // 256 bytes requires heap allocation
 | 
			
		||||
    ->ArgPair(1024, 256);
 | 
			
		||||
// Create the stream, write to it, get std::string out, then destroy.
 | 
			
		||||
// It's not useful in practice to extract std::string from OStringStream; we
 | 
			
		||||
// measure it for completeness.
 | 
			
		||||
BENCHMARK_TEMPLATE(BM_CustomStream, kStdString)
 | 
			
		||||
    ->ArgPair(1, 16)   // 16 bytes is small enough for SSO
 | 
			
		||||
    ->ArgPair(1, 256)  // 256 bytes requires heap allocation
 | 
			
		||||
    ->ArgPair(1024, 256);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
| 
						 | 
				
			
			@ -52,12 +52,16 @@ ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out);
 | 
			
		|||
//
 | 
			
		||||
// Converts the given std::string (optionally followed or preceded by ASCII
 | 
			
		||||
// whitespace) into a float, which may be rounded on overflow or underflow.
 | 
			
		||||
// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the
 | 
			
		||||
// allowed formats for `str`.
 | 
			
		||||
ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* value);
 | 
			
		||||
 | 
			
		||||
// SimpleAtod()
 | 
			
		||||
//
 | 
			
		||||
// Converts the given std::string (optionally followed or preceded by ASCII
 | 
			
		||||
// whitespace) into a double, which may be rounded on overflow or underflow.
 | 
			
		||||
// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the
 | 
			
		||||
// allowed formats for `str`.
 | 
			
		||||
ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* value);
 | 
			
		||||
 | 
			
		||||
// SimpleAtob()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,7 +38,7 @@
 | 
			
		|||
#include "absl/base/internal/raw_logging.h"
 | 
			
		||||
#include "absl/strings/str_cat.h"
 | 
			
		||||
 | 
			
		||||
#include "absl/strings/internal/numbers_test_common.inc"
 | 
			
		||||
#include "absl/strings/internal/numbers_test_common.h"
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +48,9 @@ using absl::numbers_internal::safe_strto64_base;
 | 
			
		|||
using absl::numbers_internal::safe_strtou32_base;
 | 
			
		||||
using absl::numbers_internal::safe_strtou64_base;
 | 
			
		||||
using absl::numbers_internal::SixDigitsToBuffer;
 | 
			
		||||
using absl::strings_internal::Itoa;
 | 
			
		||||
using absl::strings_internal::strtouint32_test_cases;
 | 
			
		||||
using absl::strings_internal::strtouint64_test_cases;
 | 
			
		||||
using absl::SimpleAtoi;
 | 
			
		||||
using testing::Eq;
 | 
			
		||||
using testing::MatchesRegex;
 | 
			
		||||
| 
						 | 
				
			
			@ -654,8 +657,8 @@ TEST(stringtest, safe_strtou64_random) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
TEST(stringtest, safe_strtou32_base) {
 | 
			
		||||
  for (int i = 0; strtouint32_test_cases[i].str != nullptr; ++i) {
 | 
			
		||||
    const auto& e = strtouint32_test_cases[i];
 | 
			
		||||
  for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
 | 
			
		||||
    const auto& e = strtouint32_test_cases()[i];
 | 
			
		||||
    uint32_t value;
 | 
			
		||||
    EXPECT_EQ(e.expect_ok, safe_strtou32_base(e.str, &value, e.base))
 | 
			
		||||
        << "str=\"" << e.str << "\" base=" << e.base;
 | 
			
		||||
| 
						 | 
				
			
			@ -667,8 +670,8 @@ TEST(stringtest, safe_strtou32_base) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
TEST(stringtest, safe_strtou32_base_length_delimited) {
 | 
			
		||||
  for (int i = 0; strtouint32_test_cases[i].str != nullptr; ++i) {
 | 
			
		||||
    const auto& e = strtouint32_test_cases[i];
 | 
			
		||||
  for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
 | 
			
		||||
    const auto& e = strtouint32_test_cases()[i];
 | 
			
		||||
    std::string tmp(e.str);
 | 
			
		||||
    tmp.append("12");  // Adds garbage at the end.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -685,8 +688,8 @@ TEST(stringtest, safe_strtou32_base_length_delimited) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
TEST(stringtest, safe_strtou64_base) {
 | 
			
		||||
  for (int i = 0; strtouint64_test_cases[i].str != nullptr; ++i) {
 | 
			
		||||
    const auto& e = strtouint64_test_cases[i];
 | 
			
		||||
  for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
 | 
			
		||||
    const auto& e = strtouint64_test_cases()[i];
 | 
			
		||||
    uint64_t value;
 | 
			
		||||
    EXPECT_EQ(e.expect_ok, safe_strtou64_base(e.str, &value, e.base))
 | 
			
		||||
        << "str=\"" << e.str << "\" base=" << e.base;
 | 
			
		||||
| 
						 | 
				
			
			@ -697,8 +700,8 @@ TEST(stringtest, safe_strtou64_base) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
TEST(stringtest, safe_strtou64_base_length_delimited) {
 | 
			
		||||
  for (int i = 0; strtouint64_test_cases[i].str != nullptr; ++i) {
 | 
			
		||||
    const auto& e = strtouint64_test_cases[i];
 | 
			
		||||
  for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
 | 
			
		||||
    const auto& e = strtouint64_test_cases()[i];
 | 
			
		||||
    std::string tmp(e.str);
 | 
			
		||||
    tmp.append("12");  // Adds garbage at the end.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -138,5 +138,3 @@ void BM_DoubleToString_By_SixDigits(benchmark::State& state) {
 | 
			
		|||
BENCHMARK(BM_DoubleToString_By_SixDigits);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,5 +94,3 @@ BENCHMARK(BM_JoinStreamable)
 | 
			
		|||
    ->ArgPair(256, 256);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,5 +120,3 @@ void BM_StrReplaceAll(benchmark::State& state) {
 | 
			
		|||
BENCHMARK(BM_StrReplaceAll);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -154,5 +154,3 @@ BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharLiteral);
 | 
			
		|||
BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharStringLiteral);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -327,5 +327,3 @@ void BM_AppendToStringNative(benchmark::State& state) {
 | 
			
		|||
BENCHMARK(BM_AppendToStringNative)->Range(1 << 3, 1 << 12);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,7 +99,10 @@ class Arg {
 | 
			
		|||
  // Explicitly overload `const char*` so the compiler doesn't cast to `bool`.
 | 
			
		||||
  Arg(const char* value)  // NOLINT(runtime/explicit)
 | 
			
		||||
      : piece_(absl::NullSafeStringView(value)) {}
 | 
			
		||||
  Arg(const std::string& value)  // NOLINT(runtime/explicit)
 | 
			
		||||
  template <typename Allocator>
 | 
			
		||||
  Arg(  // NOLINT
 | 
			
		||||
      const std::basic_string<char, std::char_traits<char>, Allocator>&
 | 
			
		||||
          value) noexcept
 | 
			
		||||
      : piece_(value) {}
 | 
			
		||||
  Arg(absl::string_view value)  // NOLINT(runtime/explicit)
 | 
			
		||||
      : piece_(value) {}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -130,7 +130,7 @@ cc_test(
 | 
			
		|||
    deps = [
 | 
			
		||||
        ":graphcycles_internal",
 | 
			
		||||
        "//absl/base",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +176,7 @@ cc_test(
 | 
			
		|||
        ":synchronization",
 | 
			
		||||
        ":thread_pool",
 | 
			
		||||
        "//absl/base",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,5 +42,3 @@ void BM_StressTest(benchmark::State& state) {
 | 
			
		|||
BENCHMARK(BM_StressTest)->Range(2048, 1048576);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -92,5 +92,3 @@ BENCHMARK(BM_ContendedMutex)->Threads(1);
 | 
			
		|||
BENCHMARK(BM_ContendedMutex)->ThreadPerCpu();
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
BENCHMARK_MAIN();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,10 +81,6 @@ cc_test(
 | 
			
		|||
    ],
 | 
			
		||||
    copts = ABSL_TEST_COPTS,
 | 
			
		||||
    tags = [
 | 
			
		||||
        "no_test_android_arm",
 | 
			
		||||
        "no_test_android_arm64",
 | 
			
		||||
        "no_test_android_x86",
 | 
			
		||||
        "no_test_ios_x86_64",
 | 
			
		||||
        "no_test_loonix",
 | 
			
		||||
    ],
 | 
			
		||||
    deps = [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,6 +81,11 @@ cc_test(
 | 
			
		|||
    size = "small",
 | 
			
		||||
    srcs = ["src/time_zone_format_test.cc"],
 | 
			
		||||
    data = [":zoneinfo"],
 | 
			
		||||
    tags = [
 | 
			
		||||
        "no_test_android_arm",
 | 
			
		||||
        "no_test_android_arm64",
 | 
			
		||||
        "no_test_android_x86",
 | 
			
		||||
    ],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":civil_time",
 | 
			
		||||
        ":time_zone",
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +98,11 @@ cc_test(
 | 
			
		|||
    size = "small",
 | 
			
		||||
    srcs = ["src/time_zone_lookup_test.cc"],
 | 
			
		||||
    data = [":zoneinfo"],
 | 
			
		||||
    tags = [
 | 
			
		||||
        "no_test_android_arm",
 | 
			
		||||
        "no_test_android_arm64",
 | 
			
		||||
        "no_test_android_x86",
 | 
			
		||||
    ],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":civil_time",
 | 
			
		||||
        ":time_zone",
 | 
			
		||||
| 
						 | 
				
			
			@ -102,6 +112,24 @@ cc_test(
 | 
			
		|||
 | 
			
		||||
### benchmarks
 | 
			
		||||
 | 
			
		||||
cc_test(
 | 
			
		||||
    name = "cctz_benchmark",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "src/cctz_benchmark.cc",
 | 
			
		||||
        "src/time_zone_if.h",
 | 
			
		||||
        "src/time_zone_impl.h",
 | 
			
		||||
        "src/time_zone_info.h",
 | 
			
		||||
        "src/tzfile.h",
 | 
			
		||||
    ],
 | 
			
		||||
    linkstatic = 1,
 | 
			
		||||
    tags = ["benchmark"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":civil_time",
 | 
			
		||||
        ":time_zone",
 | 
			
		||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
### examples
 | 
			
		||||
 | 
			
		||||
### binaries
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										982
									
								
								absl/time/internal/cctz/src/cctz_benchmark.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										982
									
								
								absl/time/internal/cctz/src/cctz_benchmark.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,982 @@
 | 
			
		|||
// Copyright 2016 Google Inc. All Rights Reserved.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//   http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
//   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
//   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
//   See the License for the specific language governing permissions and
 | 
			
		||||
//   limitations under the License.
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
#include <random>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "benchmark/benchmark.h"
 | 
			
		||||
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
 | 
			
		||||
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
 | 
			
		||||
#include "time_zone_impl.h"
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
namespace cctz = absl::time_internal::cctz;
 | 
			
		||||
 | 
			
		||||
void BM_Difference_Days(benchmark::State& state) {
 | 
			
		||||
  const cctz::civil_day c(2014, 8, 22);
 | 
			
		||||
  const cctz::civil_day epoch(1970, 1, 1);
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    benchmark::DoNotOptimize(c - epoch);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Difference_Days);
 | 
			
		||||
 | 
			
		||||
void BM_Step_Days(benchmark::State& state) {
 | 
			
		||||
  const cctz::civil_day kStart(2014, 8, 22);
 | 
			
		||||
  cctz::civil_day c = kStart;
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    benchmark::DoNotOptimize(++c);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Step_Days);
 | 
			
		||||
 | 
			
		||||
const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
 | 
			
		||||
const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
 | 
			
		||||
 | 
			
		||||
const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z";
 | 
			
		||||
const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z";
 | 
			
		||||
 | 
			
		||||
// A list of known time-zone names.
 | 
			
		||||
// TODO: Refactor with src/time_zone_lookup_test.cc.
 | 
			
		||||
const char* const kTimeZoneNames[] = {
 | 
			
		||||
  "Africa/Abidjan",
 | 
			
		||||
  "Africa/Accra",
 | 
			
		||||
  "Africa/Addis_Ababa",
 | 
			
		||||
  "Africa/Algiers",
 | 
			
		||||
  "Africa/Asmara",
 | 
			
		||||
  "Africa/Asmera",
 | 
			
		||||
  "Africa/Bamako",
 | 
			
		||||
  "Africa/Bangui",
 | 
			
		||||
  "Africa/Banjul",
 | 
			
		||||
  "Africa/Bissau",
 | 
			
		||||
  "Africa/Blantyre",
 | 
			
		||||
  "Africa/Brazzaville",
 | 
			
		||||
  "Africa/Bujumbura",
 | 
			
		||||
  "Africa/Cairo",
 | 
			
		||||
  "Africa/Casablanca",
 | 
			
		||||
  "Africa/Ceuta",
 | 
			
		||||
  "Africa/Conakry",
 | 
			
		||||
  "Africa/Dakar",
 | 
			
		||||
  "Africa/Dar_es_Salaam",
 | 
			
		||||
  "Africa/Djibouti",
 | 
			
		||||
  "Africa/Douala",
 | 
			
		||||
  "Africa/El_Aaiun",
 | 
			
		||||
  "Africa/Freetown",
 | 
			
		||||
  "Africa/Gaborone",
 | 
			
		||||
  "Africa/Harare",
 | 
			
		||||
  "Africa/Johannesburg",
 | 
			
		||||
  "Africa/Juba",
 | 
			
		||||
  "Africa/Kampala",
 | 
			
		||||
  "Africa/Khartoum",
 | 
			
		||||
  "Africa/Kigali",
 | 
			
		||||
  "Africa/Kinshasa",
 | 
			
		||||
  "Africa/Lagos",
 | 
			
		||||
  "Africa/Libreville",
 | 
			
		||||
  "Africa/Lome",
 | 
			
		||||
  "Africa/Luanda",
 | 
			
		||||
  "Africa/Lubumbashi",
 | 
			
		||||
  "Africa/Lusaka",
 | 
			
		||||
  "Africa/Malabo",
 | 
			
		||||
  "Africa/Maputo",
 | 
			
		||||
  "Africa/Maseru",
 | 
			
		||||
  "Africa/Mbabane",
 | 
			
		||||
  "Africa/Mogadishu",
 | 
			
		||||
  "Africa/Monrovia",
 | 
			
		||||
  "Africa/Nairobi",
 | 
			
		||||
  "Africa/Ndjamena",
 | 
			
		||||
  "Africa/Niamey",
 | 
			
		||||
  "Africa/Nouakchott",
 | 
			
		||||
  "Africa/Ouagadougou",
 | 
			
		||||
  "Africa/Porto-Novo",
 | 
			
		||||
  "Africa/Sao_Tome",
 | 
			
		||||
  "Africa/Timbuktu",
 | 
			
		||||
  "Africa/Tripoli",
 | 
			
		||||
  "Africa/Tunis",
 | 
			
		||||
  "Africa/Windhoek",
 | 
			
		||||
  "America/Adak",
 | 
			
		||||
  "America/Anchorage",
 | 
			
		||||
  "America/Anguilla",
 | 
			
		||||
  "America/Antigua",
 | 
			
		||||
  "America/Araguaina",
 | 
			
		||||
  "America/Argentina/Buenos_Aires",
 | 
			
		||||
  "America/Argentina/Catamarca",
 | 
			
		||||
  "America/Argentina/ComodRivadavia",
 | 
			
		||||
  "America/Argentina/Cordoba",
 | 
			
		||||
  "America/Argentina/Jujuy",
 | 
			
		||||
  "America/Argentina/La_Rioja",
 | 
			
		||||
  "America/Argentina/Mendoza",
 | 
			
		||||
  "America/Argentina/Rio_Gallegos",
 | 
			
		||||
  "America/Argentina/Salta",
 | 
			
		||||
  "America/Argentina/San_Juan",
 | 
			
		||||
  "America/Argentina/San_Luis",
 | 
			
		||||
  "America/Argentina/Tucuman",
 | 
			
		||||
  "America/Argentina/Ushuaia",
 | 
			
		||||
  "America/Aruba",
 | 
			
		||||
  "America/Asuncion",
 | 
			
		||||
  "America/Atikokan",
 | 
			
		||||
  "America/Atka",
 | 
			
		||||
  "America/Bahia",
 | 
			
		||||
  "America/Bahia_Banderas",
 | 
			
		||||
  "America/Barbados",
 | 
			
		||||
  "America/Belem",
 | 
			
		||||
  "America/Belize",
 | 
			
		||||
  "America/Blanc-Sablon",
 | 
			
		||||
  "America/Boa_Vista",
 | 
			
		||||
  "America/Bogota",
 | 
			
		||||
  "America/Boise",
 | 
			
		||||
  "America/Buenos_Aires",
 | 
			
		||||
  "America/Cambridge_Bay",
 | 
			
		||||
  "America/Campo_Grande",
 | 
			
		||||
  "America/Cancun",
 | 
			
		||||
  "America/Caracas",
 | 
			
		||||
  "America/Catamarca",
 | 
			
		||||
  "America/Cayenne",
 | 
			
		||||
  "America/Cayman",
 | 
			
		||||
  "America/Chicago",
 | 
			
		||||
  "America/Chihuahua",
 | 
			
		||||
  "America/Coral_Harbour",
 | 
			
		||||
  "America/Cordoba",
 | 
			
		||||
  "America/Costa_Rica",
 | 
			
		||||
  "America/Creston",
 | 
			
		||||
  "America/Cuiaba",
 | 
			
		||||
  "America/Curacao",
 | 
			
		||||
  "America/Danmarkshavn",
 | 
			
		||||
  "America/Dawson",
 | 
			
		||||
  "America/Dawson_Creek",
 | 
			
		||||
  "America/Denver",
 | 
			
		||||
  "America/Detroit",
 | 
			
		||||
  "America/Dominica",
 | 
			
		||||
  "America/Edmonton",
 | 
			
		||||
  "America/Eirunepe",
 | 
			
		||||
  "America/El_Salvador",
 | 
			
		||||
  "America/Ensenada",
 | 
			
		||||
  "America/Fort_Nelson",
 | 
			
		||||
  "America/Fort_Wayne",
 | 
			
		||||
  "America/Fortaleza",
 | 
			
		||||
  "America/Glace_Bay",
 | 
			
		||||
  "America/Godthab",
 | 
			
		||||
  "America/Goose_Bay",
 | 
			
		||||
  "America/Grand_Turk",
 | 
			
		||||
  "America/Grenada",
 | 
			
		||||
  "America/Guadeloupe",
 | 
			
		||||
  "America/Guatemala",
 | 
			
		||||
  "America/Guayaquil",
 | 
			
		||||
  "America/Guyana",
 | 
			
		||||
  "America/Halifax",
 | 
			
		||||
  "America/Havana",
 | 
			
		||||
  "America/Hermosillo",
 | 
			
		||||
  "America/Indiana/Indianapolis",
 | 
			
		||||
  "America/Indiana/Knox",
 | 
			
		||||
  "America/Indiana/Marengo",
 | 
			
		||||
  "America/Indiana/Petersburg",
 | 
			
		||||
  "America/Indiana/Tell_City",
 | 
			
		||||
  "America/Indiana/Vevay",
 | 
			
		||||
  "America/Indiana/Vincennes",
 | 
			
		||||
  "America/Indiana/Winamac",
 | 
			
		||||
  "America/Indianapolis",
 | 
			
		||||
  "America/Inuvik",
 | 
			
		||||
  "America/Iqaluit",
 | 
			
		||||
  "America/Jamaica",
 | 
			
		||||
  "America/Jujuy",
 | 
			
		||||
  "America/Juneau",
 | 
			
		||||
  "America/Kentucky/Louisville",
 | 
			
		||||
  "America/Kentucky/Monticello",
 | 
			
		||||
  "America/Knox_IN",
 | 
			
		||||
  "America/Kralendijk",
 | 
			
		||||
  "America/La_Paz",
 | 
			
		||||
  "America/Lima",
 | 
			
		||||
  "America/Los_Angeles",
 | 
			
		||||
  "America/Louisville",
 | 
			
		||||
  "America/Lower_Princes",
 | 
			
		||||
  "America/Maceio",
 | 
			
		||||
  "America/Managua",
 | 
			
		||||
  "America/Manaus",
 | 
			
		||||
  "America/Marigot",
 | 
			
		||||
  "America/Martinique",
 | 
			
		||||
  "America/Matamoros",
 | 
			
		||||
  "America/Mazatlan",
 | 
			
		||||
  "America/Mendoza",
 | 
			
		||||
  "America/Menominee",
 | 
			
		||||
  "America/Merida",
 | 
			
		||||
  "America/Metlakatla",
 | 
			
		||||
  "America/Mexico_City",
 | 
			
		||||
  "America/Miquelon",
 | 
			
		||||
  "America/Moncton",
 | 
			
		||||
  "America/Monterrey",
 | 
			
		||||
  "America/Montevideo",
 | 
			
		||||
  "America/Montreal",
 | 
			
		||||
  "America/Montserrat",
 | 
			
		||||
  "America/Nassau",
 | 
			
		||||
  "America/New_York",
 | 
			
		||||
  "America/Nipigon",
 | 
			
		||||
  "America/Nome",
 | 
			
		||||
  "America/Noronha",
 | 
			
		||||
  "America/North_Dakota/Beulah",
 | 
			
		||||
  "America/North_Dakota/Center",
 | 
			
		||||
  "America/North_Dakota/New_Salem",
 | 
			
		||||
  "America/Ojinaga",
 | 
			
		||||
  "America/Panama",
 | 
			
		||||
  "America/Pangnirtung",
 | 
			
		||||
  "America/Paramaribo",
 | 
			
		||||
  "America/Phoenix",
 | 
			
		||||
  "America/Port-au-Prince",
 | 
			
		||||
  "America/Port_of_Spain",
 | 
			
		||||
  "America/Porto_Acre",
 | 
			
		||||
  "America/Porto_Velho",
 | 
			
		||||
  "America/Puerto_Rico",
 | 
			
		||||
  "America/Punta_Arenas",
 | 
			
		||||
  "America/Rainy_River",
 | 
			
		||||
  "America/Rankin_Inlet",
 | 
			
		||||
  "America/Recife",
 | 
			
		||||
  "America/Regina",
 | 
			
		||||
  "America/Resolute",
 | 
			
		||||
  "America/Rio_Branco",
 | 
			
		||||
  "America/Rosario",
 | 
			
		||||
  "America/Santa_Isabel",
 | 
			
		||||
  "America/Santarem",
 | 
			
		||||
  "America/Santiago",
 | 
			
		||||
  "America/Santo_Domingo",
 | 
			
		||||
  "America/Sao_Paulo",
 | 
			
		||||
  "America/Scoresbysund",
 | 
			
		||||
  "America/Shiprock",
 | 
			
		||||
  "America/Sitka",
 | 
			
		||||
  "America/St_Barthelemy",
 | 
			
		||||
  "America/St_Johns",
 | 
			
		||||
  "America/St_Kitts",
 | 
			
		||||
  "America/St_Lucia",
 | 
			
		||||
  "America/St_Thomas",
 | 
			
		||||
  "America/St_Vincent",
 | 
			
		||||
  "America/Swift_Current",
 | 
			
		||||
  "America/Tegucigalpa",
 | 
			
		||||
  "America/Thule",
 | 
			
		||||
  "America/Thunder_Bay",
 | 
			
		||||
  "America/Tijuana",
 | 
			
		||||
  "America/Toronto",
 | 
			
		||||
  "America/Tortola",
 | 
			
		||||
  "America/Vancouver",
 | 
			
		||||
  "America/Virgin",
 | 
			
		||||
  "America/Whitehorse",
 | 
			
		||||
  "America/Winnipeg",
 | 
			
		||||
  "America/Yakutat",
 | 
			
		||||
  "America/Yellowknife",
 | 
			
		||||
  "Antarctica/Casey",
 | 
			
		||||
  "Antarctica/Davis",
 | 
			
		||||
  "Antarctica/DumontDUrville",
 | 
			
		||||
  "Antarctica/Macquarie",
 | 
			
		||||
  "Antarctica/Mawson",
 | 
			
		||||
  "Antarctica/McMurdo",
 | 
			
		||||
  "Antarctica/Palmer",
 | 
			
		||||
  "Antarctica/Rothera",
 | 
			
		||||
  "Antarctica/South_Pole",
 | 
			
		||||
  "Antarctica/Syowa",
 | 
			
		||||
  "Antarctica/Troll",
 | 
			
		||||
  "Antarctica/Vostok",
 | 
			
		||||
  "Arctic/Longyearbyen",
 | 
			
		||||
  "Asia/Aden",
 | 
			
		||||
  "Asia/Almaty",
 | 
			
		||||
  "Asia/Amman",
 | 
			
		||||
  "Asia/Anadyr",
 | 
			
		||||
  "Asia/Aqtau",
 | 
			
		||||
  "Asia/Aqtobe",
 | 
			
		||||
  "Asia/Ashgabat",
 | 
			
		||||
  "Asia/Ashkhabad",
 | 
			
		||||
  "Asia/Atyrau",
 | 
			
		||||
  "Asia/Baghdad",
 | 
			
		||||
  "Asia/Bahrain",
 | 
			
		||||
  "Asia/Baku",
 | 
			
		||||
  "Asia/Bangkok",
 | 
			
		||||
  "Asia/Barnaul",
 | 
			
		||||
  "Asia/Beirut",
 | 
			
		||||
  "Asia/Bishkek",
 | 
			
		||||
  "Asia/Brunei",
 | 
			
		||||
  "Asia/Calcutta",
 | 
			
		||||
  "Asia/Chita",
 | 
			
		||||
  "Asia/Choibalsan",
 | 
			
		||||
  "Asia/Chongqing",
 | 
			
		||||
  "Asia/Chungking",
 | 
			
		||||
  "Asia/Colombo",
 | 
			
		||||
  "Asia/Dacca",
 | 
			
		||||
  "Asia/Damascus",
 | 
			
		||||
  "Asia/Dhaka",
 | 
			
		||||
  "Asia/Dili",
 | 
			
		||||
  "Asia/Dubai",
 | 
			
		||||
  "Asia/Dushanbe",
 | 
			
		||||
  "Asia/Famagusta",
 | 
			
		||||
  "Asia/Gaza",
 | 
			
		||||
  "Asia/Harbin",
 | 
			
		||||
  "Asia/Hebron",
 | 
			
		||||
  "Asia/Ho_Chi_Minh",
 | 
			
		||||
  "Asia/Hong_Kong",
 | 
			
		||||
  "Asia/Hovd",
 | 
			
		||||
  "Asia/Irkutsk",
 | 
			
		||||
  "Asia/Istanbul",
 | 
			
		||||
  "Asia/Jakarta",
 | 
			
		||||
  "Asia/Jayapura",
 | 
			
		||||
  "Asia/Jerusalem",
 | 
			
		||||
  "Asia/Kabul",
 | 
			
		||||
  "Asia/Kamchatka",
 | 
			
		||||
  "Asia/Karachi",
 | 
			
		||||
  "Asia/Kashgar",
 | 
			
		||||
  "Asia/Kathmandu",
 | 
			
		||||
  "Asia/Katmandu",
 | 
			
		||||
  "Asia/Khandyga",
 | 
			
		||||
  "Asia/Kolkata",
 | 
			
		||||
  "Asia/Krasnoyarsk",
 | 
			
		||||
  "Asia/Kuala_Lumpur",
 | 
			
		||||
  "Asia/Kuching",
 | 
			
		||||
  "Asia/Kuwait",
 | 
			
		||||
  "Asia/Macao",
 | 
			
		||||
  "Asia/Macau",
 | 
			
		||||
  "Asia/Magadan",
 | 
			
		||||
  "Asia/Makassar",
 | 
			
		||||
  "Asia/Manila",
 | 
			
		||||
  "Asia/Muscat",
 | 
			
		||||
  "Asia/Nicosia",
 | 
			
		||||
  "Asia/Novokuznetsk",
 | 
			
		||||
  "Asia/Novosibirsk",
 | 
			
		||||
  "Asia/Omsk",
 | 
			
		||||
  "Asia/Oral",
 | 
			
		||||
  "Asia/Phnom_Penh",
 | 
			
		||||
  "Asia/Pontianak",
 | 
			
		||||
  "Asia/Pyongyang",
 | 
			
		||||
  "Asia/Qatar",
 | 
			
		||||
  "Asia/Qyzylorda",
 | 
			
		||||
  "Asia/Rangoon",
 | 
			
		||||
  "Asia/Riyadh",
 | 
			
		||||
  "Asia/Saigon",
 | 
			
		||||
  "Asia/Sakhalin",
 | 
			
		||||
  "Asia/Samarkand",
 | 
			
		||||
  "Asia/Seoul",
 | 
			
		||||
  "Asia/Shanghai",
 | 
			
		||||
  "Asia/Singapore",
 | 
			
		||||
  "Asia/Srednekolymsk",
 | 
			
		||||
  "Asia/Taipei",
 | 
			
		||||
  "Asia/Tashkent",
 | 
			
		||||
  "Asia/Tbilisi",
 | 
			
		||||
  "Asia/Tehran",
 | 
			
		||||
  "Asia/Tel_Aviv",
 | 
			
		||||
  "Asia/Thimbu",
 | 
			
		||||
  "Asia/Thimphu",
 | 
			
		||||
  "Asia/Tokyo",
 | 
			
		||||
  "Asia/Tomsk",
 | 
			
		||||
  "Asia/Ujung_Pandang",
 | 
			
		||||
  "Asia/Ulaanbaatar",
 | 
			
		||||
  "Asia/Ulan_Bator",
 | 
			
		||||
  "Asia/Urumqi",
 | 
			
		||||
  "Asia/Ust-Nera",
 | 
			
		||||
  "Asia/Vientiane",
 | 
			
		||||
  "Asia/Vladivostok",
 | 
			
		||||
  "Asia/Yakutsk",
 | 
			
		||||
  "Asia/Yangon",
 | 
			
		||||
  "Asia/Yekaterinburg",
 | 
			
		||||
  "Asia/Yerevan",
 | 
			
		||||
  "Atlantic/Azores",
 | 
			
		||||
  "Atlantic/Bermuda",
 | 
			
		||||
  "Atlantic/Canary",
 | 
			
		||||
  "Atlantic/Cape_Verde",
 | 
			
		||||
  "Atlantic/Faeroe",
 | 
			
		||||
  "Atlantic/Faroe",
 | 
			
		||||
  "Atlantic/Jan_Mayen",
 | 
			
		||||
  "Atlantic/Madeira",
 | 
			
		||||
  "Atlantic/Reykjavik",
 | 
			
		||||
  "Atlantic/South_Georgia",
 | 
			
		||||
  "Atlantic/St_Helena",
 | 
			
		||||
  "Atlantic/Stanley",
 | 
			
		||||
  "Australia/ACT",
 | 
			
		||||
  "Australia/Adelaide",
 | 
			
		||||
  "Australia/Brisbane",
 | 
			
		||||
  "Australia/Broken_Hill",
 | 
			
		||||
  "Australia/Canberra",
 | 
			
		||||
  "Australia/Currie",
 | 
			
		||||
  "Australia/Darwin",
 | 
			
		||||
  "Australia/Eucla",
 | 
			
		||||
  "Australia/Hobart",
 | 
			
		||||
  "Australia/LHI",
 | 
			
		||||
  "Australia/Lindeman",
 | 
			
		||||
  "Australia/Lord_Howe",
 | 
			
		||||
  "Australia/Melbourne",
 | 
			
		||||
  "Australia/NSW",
 | 
			
		||||
  "Australia/North",
 | 
			
		||||
  "Australia/Perth",
 | 
			
		||||
  "Australia/Queensland",
 | 
			
		||||
  "Australia/South",
 | 
			
		||||
  "Australia/Sydney",
 | 
			
		||||
  "Australia/Tasmania",
 | 
			
		||||
  "Australia/Victoria",
 | 
			
		||||
  "Australia/West",
 | 
			
		||||
  "Australia/Yancowinna",
 | 
			
		||||
  "Brazil/Acre",
 | 
			
		||||
  "Brazil/DeNoronha",
 | 
			
		||||
  "Brazil/East",
 | 
			
		||||
  "Brazil/West",
 | 
			
		||||
  "CET",
 | 
			
		||||
  "CST6CDT",
 | 
			
		||||
  "Canada/Atlantic",
 | 
			
		||||
  "Canada/Central",
 | 
			
		||||
  "Canada/Eastern",
 | 
			
		||||
  "Canada/Mountain",
 | 
			
		||||
  "Canada/Newfoundland",
 | 
			
		||||
  "Canada/Pacific",
 | 
			
		||||
  "Canada/Saskatchewan",
 | 
			
		||||
  "Canada/Yukon",
 | 
			
		||||
  "Chile/Continental",
 | 
			
		||||
  "Chile/EasterIsland",
 | 
			
		||||
  "Cuba",
 | 
			
		||||
  "EET",
 | 
			
		||||
  "EST",
 | 
			
		||||
  "EST5EDT",
 | 
			
		||||
  "Egypt",
 | 
			
		||||
  "Eire",
 | 
			
		||||
  "Etc/GMT",
 | 
			
		||||
  "Etc/GMT+0",
 | 
			
		||||
  "Etc/GMT+1",
 | 
			
		||||
  "Etc/GMT+10",
 | 
			
		||||
  "Etc/GMT+11",
 | 
			
		||||
  "Etc/GMT+12",
 | 
			
		||||
  "Etc/GMT+2",
 | 
			
		||||
  "Etc/GMT+3",
 | 
			
		||||
  "Etc/GMT+4",
 | 
			
		||||
  "Etc/GMT+5",
 | 
			
		||||
  "Etc/GMT+6",
 | 
			
		||||
  "Etc/GMT+7",
 | 
			
		||||
  "Etc/GMT+8",
 | 
			
		||||
  "Etc/GMT+9",
 | 
			
		||||
  "Etc/GMT-0",
 | 
			
		||||
  "Etc/GMT-1",
 | 
			
		||||
  "Etc/GMT-10",
 | 
			
		||||
  "Etc/GMT-11",
 | 
			
		||||
  "Etc/GMT-12",
 | 
			
		||||
  "Etc/GMT-13",
 | 
			
		||||
  "Etc/GMT-14",
 | 
			
		||||
  "Etc/GMT-2",
 | 
			
		||||
  "Etc/GMT-3",
 | 
			
		||||
  "Etc/GMT-4",
 | 
			
		||||
  "Etc/GMT-5",
 | 
			
		||||
  "Etc/GMT-6",
 | 
			
		||||
  "Etc/GMT-7",
 | 
			
		||||
  "Etc/GMT-8",
 | 
			
		||||
  "Etc/GMT-9",
 | 
			
		||||
  "Etc/GMT0",
 | 
			
		||||
  "Etc/Greenwich",
 | 
			
		||||
  "Etc/UCT",
 | 
			
		||||
  "Etc/UTC",
 | 
			
		||||
  "Etc/Universal",
 | 
			
		||||
  "Etc/Zulu",
 | 
			
		||||
  "Europe/Amsterdam",
 | 
			
		||||
  "Europe/Andorra",
 | 
			
		||||
  "Europe/Astrakhan",
 | 
			
		||||
  "Europe/Athens",
 | 
			
		||||
  "Europe/Belfast",
 | 
			
		||||
  "Europe/Belgrade",
 | 
			
		||||
  "Europe/Berlin",
 | 
			
		||||
  "Europe/Bratislava",
 | 
			
		||||
  "Europe/Brussels",
 | 
			
		||||
  "Europe/Bucharest",
 | 
			
		||||
  "Europe/Budapest",
 | 
			
		||||
  "Europe/Busingen",
 | 
			
		||||
  "Europe/Chisinau",
 | 
			
		||||
  "Europe/Copenhagen",
 | 
			
		||||
  "Europe/Dublin",
 | 
			
		||||
  "Europe/Gibraltar",
 | 
			
		||||
  "Europe/Guernsey",
 | 
			
		||||
  "Europe/Helsinki",
 | 
			
		||||
  "Europe/Isle_of_Man",
 | 
			
		||||
  "Europe/Istanbul",
 | 
			
		||||
  "Europe/Jersey",
 | 
			
		||||
  "Europe/Kaliningrad",
 | 
			
		||||
  "Europe/Kiev",
 | 
			
		||||
  "Europe/Kirov",
 | 
			
		||||
  "Europe/Lisbon",
 | 
			
		||||
  "Europe/Ljubljana",
 | 
			
		||||
  "Europe/London",
 | 
			
		||||
  "Europe/Luxembourg",
 | 
			
		||||
  "Europe/Madrid",
 | 
			
		||||
  "Europe/Malta",
 | 
			
		||||
  "Europe/Mariehamn",
 | 
			
		||||
  "Europe/Minsk",
 | 
			
		||||
  "Europe/Monaco",
 | 
			
		||||
  "Europe/Moscow",
 | 
			
		||||
  "Europe/Nicosia",
 | 
			
		||||
  "Europe/Oslo",
 | 
			
		||||
  "Europe/Paris",
 | 
			
		||||
  "Europe/Podgorica",
 | 
			
		||||
  "Europe/Prague",
 | 
			
		||||
  "Europe/Riga",
 | 
			
		||||
  "Europe/Rome",
 | 
			
		||||
  "Europe/Samara",
 | 
			
		||||
  "Europe/San_Marino",
 | 
			
		||||
  "Europe/Sarajevo",
 | 
			
		||||
  "Europe/Saratov",
 | 
			
		||||
  "Europe/Simferopol",
 | 
			
		||||
  "Europe/Skopje",
 | 
			
		||||
  "Europe/Sofia",
 | 
			
		||||
  "Europe/Stockholm",
 | 
			
		||||
  "Europe/Tallinn",
 | 
			
		||||
  "Europe/Tirane",
 | 
			
		||||
  "Europe/Tiraspol",
 | 
			
		||||
  "Europe/Ulyanovsk",
 | 
			
		||||
  "Europe/Uzhgorod",
 | 
			
		||||
  "Europe/Vaduz",
 | 
			
		||||
  "Europe/Vatican",
 | 
			
		||||
  "Europe/Vienna",
 | 
			
		||||
  "Europe/Vilnius",
 | 
			
		||||
  "Europe/Volgograd",
 | 
			
		||||
  "Europe/Warsaw",
 | 
			
		||||
  "Europe/Zagreb",
 | 
			
		||||
  "Europe/Zaporozhye",
 | 
			
		||||
  "Europe/Zurich",
 | 
			
		||||
  "GB",
 | 
			
		||||
  "GB-Eire",
 | 
			
		||||
  "GMT",
 | 
			
		||||
  "GMT+0",
 | 
			
		||||
  "GMT-0",
 | 
			
		||||
  "GMT0",
 | 
			
		||||
  "Greenwich",
 | 
			
		||||
  "HST",
 | 
			
		||||
  "Hongkong",
 | 
			
		||||
  "Iceland",
 | 
			
		||||
  "Indian/Antananarivo",
 | 
			
		||||
  "Indian/Chagos",
 | 
			
		||||
  "Indian/Christmas",
 | 
			
		||||
  "Indian/Cocos",
 | 
			
		||||
  "Indian/Comoro",
 | 
			
		||||
  "Indian/Kerguelen",
 | 
			
		||||
  "Indian/Mahe",
 | 
			
		||||
  "Indian/Maldives",
 | 
			
		||||
  "Indian/Mauritius",
 | 
			
		||||
  "Indian/Mayotte",
 | 
			
		||||
  "Indian/Reunion",
 | 
			
		||||
  "Iran",
 | 
			
		||||
  "Israel",
 | 
			
		||||
  "Jamaica",
 | 
			
		||||
  "Japan",
 | 
			
		||||
  "Kwajalein",
 | 
			
		||||
  "Libya",
 | 
			
		||||
  "MET",
 | 
			
		||||
  "MST",
 | 
			
		||||
  "MST7MDT",
 | 
			
		||||
  "Mexico/BajaNorte",
 | 
			
		||||
  "Mexico/BajaSur",
 | 
			
		||||
  "Mexico/General",
 | 
			
		||||
  "NZ",
 | 
			
		||||
  "NZ-CHAT",
 | 
			
		||||
  "Navajo",
 | 
			
		||||
  "PRC",
 | 
			
		||||
  "PST8PDT",
 | 
			
		||||
  "Pacific/Apia",
 | 
			
		||||
  "Pacific/Auckland",
 | 
			
		||||
  "Pacific/Bougainville",
 | 
			
		||||
  "Pacific/Chatham",
 | 
			
		||||
  "Pacific/Chuuk",
 | 
			
		||||
  "Pacific/Easter",
 | 
			
		||||
  "Pacific/Efate",
 | 
			
		||||
  "Pacific/Enderbury",
 | 
			
		||||
  "Pacific/Fakaofo",
 | 
			
		||||
  "Pacific/Fiji",
 | 
			
		||||
  "Pacific/Funafuti",
 | 
			
		||||
  "Pacific/Galapagos",
 | 
			
		||||
  "Pacific/Gambier",
 | 
			
		||||
  "Pacific/Guadalcanal",
 | 
			
		||||
  "Pacific/Guam",
 | 
			
		||||
  "Pacific/Honolulu",
 | 
			
		||||
  "Pacific/Johnston",
 | 
			
		||||
  "Pacific/Kiritimati",
 | 
			
		||||
  "Pacific/Kosrae",
 | 
			
		||||
  "Pacific/Kwajalein",
 | 
			
		||||
  "Pacific/Majuro",
 | 
			
		||||
  "Pacific/Marquesas",
 | 
			
		||||
  "Pacific/Midway",
 | 
			
		||||
  "Pacific/Nauru",
 | 
			
		||||
  "Pacific/Niue",
 | 
			
		||||
  "Pacific/Norfolk",
 | 
			
		||||
  "Pacific/Noumea",
 | 
			
		||||
  "Pacific/Pago_Pago",
 | 
			
		||||
  "Pacific/Palau",
 | 
			
		||||
  "Pacific/Pitcairn",
 | 
			
		||||
  "Pacific/Pohnpei",
 | 
			
		||||
  "Pacific/Ponape",
 | 
			
		||||
  "Pacific/Port_Moresby",
 | 
			
		||||
  "Pacific/Rarotonga",
 | 
			
		||||
  "Pacific/Saipan",
 | 
			
		||||
  "Pacific/Samoa",
 | 
			
		||||
  "Pacific/Tahiti",
 | 
			
		||||
  "Pacific/Tarawa",
 | 
			
		||||
  "Pacific/Tongatapu",
 | 
			
		||||
  "Pacific/Truk",
 | 
			
		||||
  "Pacific/Wake",
 | 
			
		||||
  "Pacific/Wallis",
 | 
			
		||||
  "Pacific/Yap",
 | 
			
		||||
  "Poland",
 | 
			
		||||
  "Portugal",
 | 
			
		||||
  "ROC",
 | 
			
		||||
  "ROK",
 | 
			
		||||
  "Singapore",
 | 
			
		||||
  "Turkey",
 | 
			
		||||
  "UCT",
 | 
			
		||||
  "US/Alaska",
 | 
			
		||||
  "US/Aleutian",
 | 
			
		||||
  "US/Arizona",
 | 
			
		||||
  "US/Central",
 | 
			
		||||
  "US/East-Indiana",
 | 
			
		||||
  "US/Eastern",
 | 
			
		||||
  "US/Hawaii",
 | 
			
		||||
  "US/Indiana-Starke",
 | 
			
		||||
  "US/Michigan",
 | 
			
		||||
  "US/Mountain",
 | 
			
		||||
  "US/Pacific",
 | 
			
		||||
  "US/Samoa",
 | 
			
		||||
  "UTC",
 | 
			
		||||
  "Universal",
 | 
			
		||||
  "W-SU",
 | 
			
		||||
  "WET",
 | 
			
		||||
  "Zulu",
 | 
			
		||||
  nullptr
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> AllTimeZoneNames() {
 | 
			
		||||
  std::vector<std::string> names;
 | 
			
		||||
  for (const char* const* namep = kTimeZoneNames; *namep != nullptr; ++namep) {
 | 
			
		||||
    names.push_back(std::string("file:") + *namep);
 | 
			
		||||
  }
 | 
			
		||||
  assert(!names.empty());
 | 
			
		||||
 | 
			
		||||
  std::mt19937 urbg(42);  // a UniformRandomBitGenerator with fixed seed
 | 
			
		||||
  std::shuffle(names.begin(), names.end(), urbg);
 | 
			
		||||
  return names;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cctz::time_zone TestTimeZone() {
 | 
			
		||||
  cctz::time_zone tz;
 | 
			
		||||
  cctz::load_time_zone("America/Los_Angeles", &tz);
 | 
			
		||||
  return tz;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BM_Zone_LoadUTCTimeZoneFirst(benchmark::State& state) {
 | 
			
		||||
  cctz::time_zone tz;
 | 
			
		||||
  cctz::load_time_zone("UTC", &tz);  // in case we're first
 | 
			
		||||
  cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Zone_LoadUTCTimeZoneFirst);
 | 
			
		||||
 | 
			
		||||
void BM_Zone_LoadUTCTimeZoneLast(benchmark::State& state) {
 | 
			
		||||
  cctz::time_zone tz;
 | 
			
		||||
  for (const auto& name : AllTimeZoneNames()) {
 | 
			
		||||
    cctz::load_time_zone(name, &tz);  // prime cache
 | 
			
		||||
  }
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Zone_LoadUTCTimeZoneLast);
 | 
			
		||||
 | 
			
		||||
void BM_Zone_LoadTimeZoneFirst(benchmark::State& state) {
 | 
			
		||||
  cctz::time_zone tz = cctz::utc_time_zone();  // in case we're first
 | 
			
		||||
  const std::string name = "file:America/Los_Angeles";
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    state.PauseTiming();
 | 
			
		||||
    cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
 | 
			
		||||
    state.ResumeTiming();
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Zone_LoadTimeZoneFirst);
 | 
			
		||||
 | 
			
		||||
void BM_Zone_LoadTimeZoneCached(benchmark::State& state) {
 | 
			
		||||
  cctz::time_zone tz = cctz::utc_time_zone();  // in case we're first
 | 
			
		||||
  cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
 | 
			
		||||
  const std::string name = "file:America/Los_Angeles";
 | 
			
		||||
  cctz::load_time_zone(name, &tz);  // prime cache
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Zone_LoadTimeZoneCached);
 | 
			
		||||
 | 
			
		||||
void BM_Zone_LoadLocalTimeZoneCached(benchmark::State& state) {
 | 
			
		||||
  cctz::utc_time_zone();  // in case we're first
 | 
			
		||||
  cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
 | 
			
		||||
  cctz::local_time_zone();  // prime cache
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::local_time_zone());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Zone_LoadLocalTimeZoneCached);
 | 
			
		||||
 | 
			
		||||
void BM_Zone_LoadAllTimeZonesFirst(benchmark::State& state) {
 | 
			
		||||
  cctz::time_zone tz;
 | 
			
		||||
  const std::vector<std::string> names = AllTimeZoneNames();
 | 
			
		||||
  for (auto index = names.size(); state.KeepRunning(); ++index) {
 | 
			
		||||
    if (index == names.size()) {
 | 
			
		||||
      index = 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (index == 0) {
 | 
			
		||||
      state.PauseTiming();
 | 
			
		||||
      cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
 | 
			
		||||
      state.ResumeTiming();
 | 
			
		||||
    }
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Zone_LoadAllTimeZonesFirst);
 | 
			
		||||
 | 
			
		||||
void BM_Zone_LoadAllTimeZonesCached(benchmark::State& state) {
 | 
			
		||||
  cctz::time_zone tz;
 | 
			
		||||
  const std::vector<std::string> names = AllTimeZoneNames();
 | 
			
		||||
  for (const auto& name : names) {
 | 
			
		||||
    cctz::load_time_zone(name, &tz);  // prime cache
 | 
			
		||||
  }
 | 
			
		||||
  for (auto index = names.size(); state.KeepRunning(); ++index) {
 | 
			
		||||
    if (index == names.size()) {
 | 
			
		||||
      index = 0;
 | 
			
		||||
    }
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Zone_LoadAllTimeZonesCached);
 | 
			
		||||
 | 
			
		||||
void BM_Zone_TimeZoneImplGetImplicit(benchmark::State& state) {
 | 
			
		||||
  cctz::time_zone tz;  // implicit UTC
 | 
			
		||||
  cctz::time_zone::Impl::get(tz);
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    cctz::time_zone::Impl::get(tz);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Zone_TimeZoneImplGetImplicit);
 | 
			
		||||
 | 
			
		||||
void BM_Zone_TimeZoneImplGetExplicit(benchmark::State& state) {
 | 
			
		||||
  cctz::time_zone tz = cctz::utc_time_zone();  // explicit UTC
 | 
			
		||||
  cctz::time_zone::Impl::get(tz);
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    cctz::time_zone::Impl::get(tz);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Zone_TimeZoneImplGetExplicit);
 | 
			
		||||
 | 
			
		||||
void BM_Zone_UTCTimeZone(benchmark::State& state) {
 | 
			
		||||
  cctz::time_zone tz;
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::utc_time_zone());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Zone_UTCTimeZone);
 | 
			
		||||
 | 
			
		||||
// In each "ToDateTime" benchmark we switch between two instants
 | 
			
		||||
// separated by at least one transition in order to defeat any
 | 
			
		||||
// internal caching of previous results (e.g., see local_time_hint_).
 | 
			
		||||
//
 | 
			
		||||
// The "UTC" variants use UTC instead of the Google/local time zone.
 | 
			
		||||
 | 
			
		||||
void BM_Time_ToDateTime_CCTZ(benchmark::State& state) {
 | 
			
		||||
  const cctz::time_zone tz = TestTimeZone();
 | 
			
		||||
  std::chrono::system_clock::time_point tp =
 | 
			
		||||
      std::chrono::system_clock::from_time_t(1384569027);
 | 
			
		||||
  std::chrono::system_clock::time_point tp2 =
 | 
			
		||||
      std::chrono::system_clock::from_time_t(1418962578);
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    std::swap(tp, tp2);
 | 
			
		||||
    tp += std::chrono::seconds(1);
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::convert(tp, tz));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Time_ToDateTime_CCTZ);
 | 
			
		||||
 | 
			
		||||
void BM_Time_ToDateTime_Libc(benchmark::State& state) {
 | 
			
		||||
  // No timezone support, so just use localtime.
 | 
			
		||||
  time_t t = 1384569027;
 | 
			
		||||
  time_t t2 = 1418962578;
 | 
			
		||||
  struct tm tm;
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    std::swap(t, t2);
 | 
			
		||||
    t += 1;
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
    benchmark::DoNotOptimize(localtime_s(&tm, &t));
 | 
			
		||||
#else
 | 
			
		||||
    benchmark::DoNotOptimize(localtime_r(&t, &tm));
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Time_ToDateTime_Libc);
 | 
			
		||||
 | 
			
		||||
void BM_Time_ToDateTimeUTC_CCTZ(benchmark::State& state) {
 | 
			
		||||
  const cctz::time_zone tz = cctz::utc_time_zone();
 | 
			
		||||
  std::chrono::system_clock::time_point tp =
 | 
			
		||||
      std::chrono::system_clock::from_time_t(1384569027);
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    tp += std::chrono::seconds(1);
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::convert(tp, tz));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Time_ToDateTimeUTC_CCTZ);
 | 
			
		||||
 | 
			
		||||
void BM_Time_ToDateTimeUTC_Libc(benchmark::State& state) {
 | 
			
		||||
  time_t t = 1384569027;
 | 
			
		||||
  struct tm tm;
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    t += 1;
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
    benchmark::DoNotOptimize(gmtime_s(&tm, &t));
 | 
			
		||||
#else
 | 
			
		||||
    benchmark::DoNotOptimize(gmtime_r(&t, &tm));
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Time_ToDateTimeUTC_Libc);
 | 
			
		||||
 | 
			
		||||
// In each "FromDateTime" benchmark we switch between two YMDhms
 | 
			
		||||
// values separated by at least one transition in order to defeat any
 | 
			
		||||
// internal caching of previous results (e.g., see time_local_hint_).
 | 
			
		||||
//
 | 
			
		||||
// The "UTC" variants use UTC instead of the Google/local time zone.
 | 
			
		||||
// The "Day0" variants require normalization of the day of month.
 | 
			
		||||
 | 
			
		||||
void BM_Time_FromDateTime_CCTZ(benchmark::State& state) {
 | 
			
		||||
  const cctz::time_zone tz = TestTimeZone();
 | 
			
		||||
  int i = 0;
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    if ((i++ & 1) == 0) {
 | 
			
		||||
      benchmark::DoNotOptimize(
 | 
			
		||||
          cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz));
 | 
			
		||||
    } else {
 | 
			
		||||
      benchmark::DoNotOptimize(
 | 
			
		||||
          cctz::convert(cctz::civil_second(2013, 11, 15, 18, 30, 27), tz));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Time_FromDateTime_CCTZ);
 | 
			
		||||
 | 
			
		||||
void BM_Time_FromDateTime_Libc(benchmark::State& state) {
 | 
			
		||||
  // No timezone support, so just use localtime.
 | 
			
		||||
  int i = 0;
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    struct tm tm;
 | 
			
		||||
    if ((i++ & 1) == 0) {
 | 
			
		||||
      tm.tm_year = 2014 - 1900;
 | 
			
		||||
      tm.tm_mon = 12 - 1;
 | 
			
		||||
      tm.tm_mday = 18;
 | 
			
		||||
      tm.tm_hour = 20;
 | 
			
		||||
      tm.tm_min = 16;
 | 
			
		||||
      tm.tm_sec = 18;
 | 
			
		||||
    } else {
 | 
			
		||||
      tm.tm_year = 2013 - 1900;
 | 
			
		||||
      tm.tm_mon = 11 - 1;
 | 
			
		||||
      tm.tm_mday = 15;
 | 
			
		||||
      tm.tm_hour = 18;
 | 
			
		||||
      tm.tm_min = 30;
 | 
			
		||||
      tm.tm_sec = 27;
 | 
			
		||||
    }
 | 
			
		||||
    tm.tm_isdst = -1;
 | 
			
		||||
    benchmark::DoNotOptimize(mktime(&tm));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Time_FromDateTime_Libc);
 | 
			
		||||
 | 
			
		||||
void BM_Time_FromDateTimeUTC_CCTZ(benchmark::State& state) {
 | 
			
		||||
  const cctz::time_zone tz = cctz::utc_time_zone();
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    benchmark::DoNotOptimize(
 | 
			
		||||
        cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Time_FromDateTimeUTC_CCTZ);
 | 
			
		||||
 | 
			
		||||
// There is no BM_Time_FromDateTimeUTC_Libc.
 | 
			
		||||
 | 
			
		||||
void BM_Time_FromDateTimeDay0_CCTZ(benchmark::State& state) {
 | 
			
		||||
  const cctz::time_zone tz = TestTimeZone();
 | 
			
		||||
  int i = 0;
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    if ((i++ & 1) == 0) {
 | 
			
		||||
      benchmark::DoNotOptimize(
 | 
			
		||||
          cctz::convert(cctz::civil_second(2014, 12, 0, 20, 16, 18), tz));
 | 
			
		||||
    } else {
 | 
			
		||||
      benchmark::DoNotOptimize(
 | 
			
		||||
          cctz::convert(cctz::civil_second(2013, 11, 0, 18, 30, 27), tz));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Time_FromDateTimeDay0_CCTZ);
 | 
			
		||||
 | 
			
		||||
void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) {
 | 
			
		||||
  // No timezone support, so just use localtime.
 | 
			
		||||
  int i = 0;
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    struct tm tm;
 | 
			
		||||
    if ((i++ & 1) == 0) {
 | 
			
		||||
      tm.tm_year = 2014 - 1900;
 | 
			
		||||
      tm.tm_mon = 12 - 1;
 | 
			
		||||
      tm.tm_mday = 0;
 | 
			
		||||
      tm.tm_hour = 20;
 | 
			
		||||
      tm.tm_min = 16;
 | 
			
		||||
      tm.tm_sec = 18;
 | 
			
		||||
    } else {
 | 
			
		||||
      tm.tm_year = 2013 - 1900;
 | 
			
		||||
      tm.tm_mon = 11 - 1;
 | 
			
		||||
      tm.tm_mday = 0;
 | 
			
		||||
      tm.tm_hour = 18;
 | 
			
		||||
      tm.tm_min = 30;
 | 
			
		||||
      tm.tm_sec = 27;
 | 
			
		||||
    }
 | 
			
		||||
    tm.tm_isdst = -1;
 | 
			
		||||
    benchmark::DoNotOptimize(mktime(&tm));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Time_FromDateTimeDay0_Libc);
 | 
			
		||||
 | 
			
		||||
const char* const kFormats[] = {
 | 
			
		||||
    RFC1123_full,         // 0
 | 
			
		||||
    RFC1123_no_wday,      // 1
 | 
			
		||||
    RFC3339_full,         // 2
 | 
			
		||||
    RFC3339_sec,          // 3
 | 
			
		||||
    "%Y-%m-%dT%H:%M:%S",  // 4
 | 
			
		||||
    "%Y-%m-%d",           // 5
 | 
			
		||||
};
 | 
			
		||||
const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
 | 
			
		||||
 | 
			
		||||
void BM_Format_FormatTime(benchmark::State& state) {
 | 
			
		||||
  const std::string fmt = kFormats[state.range(0)];
 | 
			
		||||
  state.SetLabel(fmt);
 | 
			
		||||
  const cctz::time_zone tz = TestTimeZone();
 | 
			
		||||
  const std::chrono::system_clock::time_point tp =
 | 
			
		||||
      cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) +
 | 
			
		||||
      std::chrono::microseconds(1);
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::format(fmt, tp, tz));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Format_FormatTime)->DenseRange(0, kNumFormats - 1);
 | 
			
		||||
 | 
			
		||||
void BM_Format_ParseTime(benchmark::State& state) {
 | 
			
		||||
  const std::string fmt = kFormats[state.range(0)];
 | 
			
		||||
  state.SetLabel(fmt);
 | 
			
		||||
  const cctz::time_zone tz = TestTimeZone();
 | 
			
		||||
  std::chrono::system_clock::time_point tp =
 | 
			
		||||
      cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) +
 | 
			
		||||
      std::chrono::microseconds(1);
 | 
			
		||||
  const std::string when = cctz::format(fmt, tp, tz);
 | 
			
		||||
  while (state.KeepRunning()) {
 | 
			
		||||
    benchmark::DoNotOptimize(cctz::parse(fmt, when, tz, &tp));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
BENCHMARK(BM_Format_ParseTime)->DenseRange(0, kNumFormats - 1);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
| 
						 | 
				
			
			@ -463,8 +463,13 @@ TEST(Format, ExtendedSecondOffset) {
 | 
			
		|||
 | 
			
		||||
  EXPECT_TRUE(load_time_zone("Europe/Moscow", &tz));
 | 
			
		||||
  tp = convert(civil_second(1919, 6, 30, 23, 59, 59), utc);
 | 
			
		||||
  TestFormatSpecifier(tp, tz, "%E*z", "+04:31:19");
 | 
			
		||||
  TestFormatSpecifier(tp, tz, "%Ez", "+04:31");
 | 
			
		||||
  if (tz.lookup(tp).offset == 4 * 60 * 60) {
 | 
			
		||||
    // We're likely dealing with zoneinfo that doesn't support really old
 | 
			
		||||
    // timestamps, so Europe/Moscow never looks to be on local mean time.
 | 
			
		||||
  } else {
 | 
			
		||||
    TestFormatSpecifier(tp, tz, "%E*z", "+04:31:19");
 | 
			
		||||
    TestFormatSpecifier(tp, tz, "%Ez", "+04:31");
 | 
			
		||||
  }
 | 
			
		||||
  tp += seconds(1);
 | 
			
		||||
  TestFormatSpecifier(tp, tz, "%E*z", "+04:00:00");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -193,6 +193,20 @@ cc_test(
 | 
			
		|||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_test(
 | 
			
		||||
    name = "optional_exception_safety_test",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "optional_exception_safety_test.cc",
 | 
			
		||||
    ],
 | 
			
		||||
    copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":optional",
 | 
			
		||||
        "//absl/base:exception_safety_testing",
 | 
			
		||||
        "@com_google_googletest//:gtest_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
cc_library(
 | 
			
		||||
    name = "variant",
 | 
			
		||||
    srcs = ["internal/variant.h"],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -209,3 +209,20 @@ absl_test(
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# test optional_exception_safety_test
 | 
			
		||||
set(OPTIONAL_EXCEPTION_SAFETY_TEST_SRC "optional_exception_safety_test.cc")
 | 
			
		||||
set(OPTIONAL_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES
 | 
			
		||||
  absl::optional
 | 
			
		||||
  absl_base_internal_exception_safety_testing
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
absl_test(
 | 
			
		||||
  TARGET
 | 
			
		||||
    optional_exception_safety_test
 | 
			
		||||
  SOURCES
 | 
			
		||||
    ${OPTIONAL_EXCEPTION_SAFETY_TEST_SRC}
 | 
			
		||||
  PUBLIC_LIBRARIES
 | 
			
		||||
    ${OPTIONAL_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES}
 | 
			
		||||
  PRIVATE_COMPILE_FLAGS
 | 
			
		||||
    ${ABSL_EXCEPTIONS_FLAG}
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										284
									
								
								absl/types/optional_exception_safety_test.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										284
									
								
								absl/types/optional_exception_safety_test.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,284 @@
 | 
			
		|||
// Copyright 2017 The Abseil Authors.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
#include "absl/types/optional.h"
 | 
			
		||||
 | 
			
		||||
#include "gtest/gtest.h"
 | 
			
		||||
#include "absl/base/internal/exception_safety_testing.h"
 | 
			
		||||
 | 
			
		||||
namespace absl {
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
using ::testing::AssertionFailure;
 | 
			
		||||
using ::testing::AssertionResult;
 | 
			
		||||
using ::testing::AssertionSuccess;
 | 
			
		||||
using ::testing::MakeExceptionSafetyTester;
 | 
			
		||||
 | 
			
		||||
using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>;
 | 
			
		||||
using Optional = absl::optional<Thrower>;
 | 
			
		||||
 | 
			
		||||
using MoveThrower = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>;
 | 
			
		||||
using MoveOptional = absl::optional<MoveThrower>;
 | 
			
		||||
 | 
			
		||||
constexpr int kInitialInteger = 5;
 | 
			
		||||
constexpr int kUpdatedInteger = 10;
 | 
			
		||||
 | 
			
		||||
template <typename OptionalT>
 | 
			
		||||
bool ValueThrowsBadOptionalAccess(const OptionalT& optional) try {
 | 
			
		||||
  return (static_cast<void>(optional.value()), false);
 | 
			
		||||
} catch (absl::bad_optional_access) {
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename OptionalT>
 | 
			
		||||
AssertionResult CheckInvariants(OptionalT* optional_ptr) {
 | 
			
		||||
  // Check the current state post-throw for validity
 | 
			
		||||
  auto& optional = *optional_ptr;
 | 
			
		||||
 | 
			
		||||
  if (optional.has_value() && ValueThrowsBadOptionalAccess(optional)) {
 | 
			
		||||
    return AssertionFailure()
 | 
			
		||||
           << "Optional with value should not throw bad_optional_access when "
 | 
			
		||||
              "accessing the value.";
 | 
			
		||||
  }
 | 
			
		||||
  if (!optional.has_value() && !ValueThrowsBadOptionalAccess(optional)) {
 | 
			
		||||
    return AssertionFailure()
 | 
			
		||||
           << "Optional without a value should throw bad_optional_access when "
 | 
			
		||||
              "accessing the value.";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Reset to a known state
 | 
			
		||||
  optional.reset();
 | 
			
		||||
 | 
			
		||||
  // Confirm that the known post-reset state is valid
 | 
			
		||||
  if (optional.has_value()) {
 | 
			
		||||
    return AssertionFailure()
 | 
			
		||||
           << "Optional should not contain a value after being reset.";
 | 
			
		||||
  }
 | 
			
		||||
  if (!ValueThrowsBadOptionalAccess(optional)) {
 | 
			
		||||
    return AssertionFailure() << "Optional should throw bad_optional_access "
 | 
			
		||||
                                 "when accessing the value after being reset.";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return AssertionSuccess();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename OptionalT>
 | 
			
		||||
AssertionResult CheckDisengaged(OptionalT* optional_ptr) {
 | 
			
		||||
  auto& optional = *optional_ptr;
 | 
			
		||||
 | 
			
		||||
  if (optional.has_value()) {
 | 
			
		||||
    return AssertionFailure()
 | 
			
		||||
           << "Expected optional to not contain a value but a value was found.";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return AssertionSuccess();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename OptionalT>
 | 
			
		||||
AssertionResult CheckEngaged(OptionalT* optional_ptr) {
 | 
			
		||||
  auto& optional = *optional_ptr;
 | 
			
		||||
 | 
			
		||||
  if (!optional.has_value()) {
 | 
			
		||||
    return AssertionFailure()
 | 
			
		||||
           << "Expected optional to contain a value but no value was found.";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return AssertionSuccess();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(OptionalExceptionSafety, ThrowingConstructors) {
 | 
			
		||||
  auto thrower_nonempty = Optional(Thrower(kInitialInteger));
 | 
			
		||||
  testing::TestThrowingCtor<Optional>(thrower_nonempty);
 | 
			
		||||
 | 
			
		||||
  auto integer_nonempty = absl::optional<int>(kInitialInteger);
 | 
			
		||||
  testing::TestThrowingCtor<Optional>(integer_nonempty);
 | 
			
		||||
  testing::TestThrowingCtor<Optional>(std::move(integer_nonempty));  // NOLINT
 | 
			
		||||
 | 
			
		||||
  testing::TestThrowingCtor<Optional>(kInitialInteger);
 | 
			
		||||
  using ThrowerVec = std::vector<Thrower, testing::ThrowingAllocator<Thrower>>;
 | 
			
		||||
  testing::TestThrowingCtor<absl::optional<ThrowerVec>>(
 | 
			
		||||
      absl::in_place,
 | 
			
		||||
      std::initializer_list<Thrower>{Thrower(), Thrower(), Thrower()},
 | 
			
		||||
      testing::ThrowingAllocator<Thrower>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(OptionalExceptionSafety, NothrowConstructors) {
 | 
			
		||||
  // This constructor is marked noexcept. If it throws, the program will
 | 
			
		||||
  // terminate.
 | 
			
		||||
  testing::TestThrowingCtor<MoveOptional>(MoveOptional(kUpdatedInteger));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(OptionalExceptionSafety, Emplace) {
 | 
			
		||||
  // Test the basic guarantee plus test the result of optional::has_value()
 | 
			
		||||
  // is false in all cases
 | 
			
		||||
  auto disengaged_test = MakeExceptionSafetyTester().WithInvariants(
 | 
			
		||||
      CheckInvariants<Optional>, CheckDisengaged<Optional>);
 | 
			
		||||
  auto disengaged_test_empty = disengaged_test.WithInitialValue(Optional());
 | 
			
		||||
  auto disengaged_test_nonempty =
 | 
			
		||||
      disengaged_test.WithInitialValue(Optional(kInitialInteger));
 | 
			
		||||
 | 
			
		||||
  auto emplace_thrower_directly = [](Optional* optional_ptr) {
 | 
			
		||||
    optional_ptr->emplace(kUpdatedInteger);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(disengaged_test_empty.Test(emplace_thrower_directly));
 | 
			
		||||
  EXPECT_TRUE(disengaged_test_nonempty.Test(emplace_thrower_directly));
 | 
			
		||||
 | 
			
		||||
  auto emplace_thrower_copy = [](Optional* optional_ptr) {
 | 
			
		||||
    auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor);
 | 
			
		||||
    optional_ptr->emplace(thrower);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(disengaged_test_empty.Test(emplace_thrower_copy));
 | 
			
		||||
  EXPECT_TRUE(disengaged_test_nonempty.Test(emplace_thrower_copy));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(OptionalExceptionSafety, EverythingThrowsSwap) {
 | 
			
		||||
  // Test the basic guarantee plus test the result of optional::has_value()
 | 
			
		||||
  // remains the same
 | 
			
		||||
  auto test =
 | 
			
		||||
      MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>);
 | 
			
		||||
  auto disengaged_test_empty = test.WithInitialValue(Optional())
 | 
			
		||||
                                   .WithInvariants(CheckDisengaged<Optional>);
 | 
			
		||||
  auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
 | 
			
		||||
                                   .WithInvariants(CheckEngaged<Optional>);
 | 
			
		||||
 | 
			
		||||
  auto swap_empty = [](Optional* optional_ptr) {
 | 
			
		||||
    auto empty = Optional();
 | 
			
		||||
    optional_ptr->swap(empty);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(engaged_test_nonempty.Test(swap_empty));
 | 
			
		||||
 | 
			
		||||
  auto swap_nonempty = [](Optional* optional_ptr) {
 | 
			
		||||
    auto nonempty =
 | 
			
		||||
        Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor);
 | 
			
		||||
    optional_ptr->swap(nonempty);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(disengaged_test_empty.Test(swap_nonempty));
 | 
			
		||||
  EXPECT_TRUE(engaged_test_nonempty.Test(swap_nonempty));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(OptionalExceptionSafety, NoThrowMoveSwap) {
 | 
			
		||||
  // Tests the nothrow guarantee for optional of T with non-throwing move
 | 
			
		||||
  auto nothrow_test =
 | 
			
		||||
      MakeExceptionSafetyTester().WithInvariants(testing::nothrow_guarantee);
 | 
			
		||||
  auto nothrow_test_empty = nothrow_test.WithInitialValue(MoveOptional());
 | 
			
		||||
  auto nothrow_test_nonempty =
 | 
			
		||||
      nothrow_test.WithInitialValue(MoveOptional(kInitialInteger));
 | 
			
		||||
 | 
			
		||||
  auto swap_empty = [](MoveOptional* optional_ptr) {
 | 
			
		||||
    auto empty = MoveOptional();
 | 
			
		||||
    optional_ptr->swap(empty);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(nothrow_test_nonempty.Test(swap_empty));
 | 
			
		||||
 | 
			
		||||
  auto swap_nonempty = [](MoveOptional* optional_ptr) {
 | 
			
		||||
    auto nonempty =
 | 
			
		||||
        MoveOptional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor);
 | 
			
		||||
    optional_ptr->swap(nonempty);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(nothrow_test_empty.Test(swap_nonempty));
 | 
			
		||||
  EXPECT_TRUE(nothrow_test_nonempty.Test(swap_nonempty));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(OptionalExceptionSafety, CopyAssign) {
 | 
			
		||||
  // Test the basic guarantee plus test the result of optional::has_value()
 | 
			
		||||
  // remains the same
 | 
			
		||||
  auto test =
 | 
			
		||||
      MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>);
 | 
			
		||||
  auto disengaged_test_empty = test.WithInitialValue(Optional())
 | 
			
		||||
                                   .WithInvariants(CheckDisengaged<Optional>);
 | 
			
		||||
  auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
 | 
			
		||||
                                   .WithInvariants(CheckEngaged<Optional>);
 | 
			
		||||
 | 
			
		||||
  auto copyassign_nonempty = [](Optional* optional_ptr) {
 | 
			
		||||
    auto nonempty =
 | 
			
		||||
        Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor);
 | 
			
		||||
    *optional_ptr = nonempty;
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(disengaged_test_empty.Test(copyassign_nonempty));
 | 
			
		||||
  EXPECT_TRUE(engaged_test_nonempty.Test(copyassign_nonempty));
 | 
			
		||||
 | 
			
		||||
  auto copyassign_thrower = [](Optional* optional_ptr) {
 | 
			
		||||
    auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor);
 | 
			
		||||
    *optional_ptr = thrower;
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(disengaged_test_empty.Test(copyassign_thrower));
 | 
			
		||||
  EXPECT_TRUE(engaged_test_nonempty.Test(copyassign_thrower));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(OptionalExceptionSafety, MoveAssign) {
 | 
			
		||||
  // Test the basic guarantee plus test the result of optional::has_value()
 | 
			
		||||
  // remains the same
 | 
			
		||||
  auto test =
 | 
			
		||||
      MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>);
 | 
			
		||||
  auto disengaged_test_empty = test.WithInitialValue(Optional())
 | 
			
		||||
                                   .WithInvariants(CheckDisengaged<Optional>);
 | 
			
		||||
  auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
 | 
			
		||||
                                   .WithInvariants(CheckEngaged<Optional>);
 | 
			
		||||
 | 
			
		||||
  auto moveassign_empty = [](Optional* optional_ptr) {
 | 
			
		||||
    auto empty = Optional();
 | 
			
		||||
    *optional_ptr = std::move(empty);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_empty));
 | 
			
		||||
 | 
			
		||||
  auto moveassign_nonempty = [](Optional* optional_ptr) {
 | 
			
		||||
    auto nonempty =
 | 
			
		||||
        Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor);
 | 
			
		||||
    *optional_ptr = std::move(nonempty);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(disengaged_test_empty.Test(moveassign_nonempty));
 | 
			
		||||
  EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_nonempty));
 | 
			
		||||
 | 
			
		||||
  auto moveassign_thrower = [](Optional* optional_ptr) {
 | 
			
		||||
    auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor);
 | 
			
		||||
    *optional_ptr = std::move(thrower);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(disengaged_test_empty.Test(moveassign_thrower));
 | 
			
		||||
  EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_thrower));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(OptionalExceptionSafety, NothrowMoveAssign) {
 | 
			
		||||
  // Tests the nothrow guarantee for optional of T with non-throwing move
 | 
			
		||||
  auto nothrow_test =
 | 
			
		||||
      MakeExceptionSafetyTester().WithInvariants(testing::nothrow_guarantee);
 | 
			
		||||
  auto nothrow_test_empty = nothrow_test.WithInitialValue(MoveOptional());
 | 
			
		||||
  auto nothrow_test_nonempty =
 | 
			
		||||
      nothrow_test.WithInitialValue(MoveOptional(kInitialInteger));
 | 
			
		||||
 | 
			
		||||
  auto moveassign_empty = [](MoveOptional* optional_ptr) {
 | 
			
		||||
    auto empty = MoveOptional();
 | 
			
		||||
    *optional_ptr = std::move(empty);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(nothrow_test_nonempty.Test(moveassign_empty));
 | 
			
		||||
 | 
			
		||||
  auto moveassign_nonempty = [](MoveOptional* optional_ptr) {
 | 
			
		||||
    auto nonempty =
 | 
			
		||||
        MoveOptional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor);
 | 
			
		||||
    *optional_ptr = std::move(nonempty);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(nothrow_test_empty.Test(moveassign_nonempty));
 | 
			
		||||
  EXPECT_TRUE(nothrow_test_nonempty.Test(moveassign_nonempty));
 | 
			
		||||
 | 
			
		||||
  auto moveassign_thrower = [](MoveOptional* optional_ptr) {
 | 
			
		||||
    auto thrower = MoveThrower(kUpdatedInteger, testing::nothrow_ctor);
 | 
			
		||||
    *optional_ptr = std::move(thrower);
 | 
			
		||||
  };
 | 
			
		||||
  EXPECT_TRUE(nothrow_test_empty.Test(moveassign_thrower));
 | 
			
		||||
  EXPECT_TRUE(nothrow_test_nonempty.Test(moveassign_thrower));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
}  // namespace absl
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue