diff --git a/.gitignore b/.gitignore index 886f443..31f3374 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,2 +1,15 @@ # Ignore all bazel-* symlinks. /bazel-* +# Ignore Bazel verbose explanations +--verbose_explanations +# Ignore CMake usual build directory +build +# Ignore Vim files +*.swp +# Ignore QtCreator Project file +CMakeLists.txt.user +# Ignore VS Code files +.vscode/* +# Ignore generated python artifacts +copts/copts.pyc +copts/__pycache__/
diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake index 0c93417..5402bf5 100644 --- a/CMake/AbseilHelpers.cmake +++ b/CMake/AbseilHelpers.cmake
@@ -15,6 +15,7 @@ # include(CMakeParseArguments) +include(AbseilConfigureCopts) # The IDE folder for Abseil that will be used if Abseil is included in a CMake # project that sets @@ -48,7 +49,11 @@ add_library(${_NAME} STATIC ${ABSL_LIB_SOURCES}) - target_compile_options(${_NAME} PRIVATE ${ABSL_COMPILE_CXXFLAGS} ${ABSL_LIB_PRIVATE_COMPILE_FLAGS}) + target_compile_options(${_NAME} + PRIVATE + ${ABSL_LIB_PRIVATE_COMPILE_FLAGS} + ${ABSL_DEFAULT_COPTS} + ) target_link_libraries(${_NAME} PUBLIC ${ABSL_LIB_PUBLIC_LIBRARIES}) target_include_directories(${_NAME} PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} ${ABSL_LIB_PUBLIC_INCLUDE_DIRS} @@ -57,12 +62,199 @@ # Add all Abseil targets to a a folder in the IDE for organization. set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) + if(ABSL_LIB_EXPORT_NAME) add_library(absl::${ABSL_LIB_EXPORT_NAME} ALIAS ${_NAME}) endif() endfunction() +# CMake function to imitate Bazel's cc_library rule. +# +# Parameters: +# NAME: name of target (see Note) +# HDRS: List of public header files for the library +# SRCS: List of source files for the library +# DEPS: List of other libraries to be linked in to the binary targets +# COPTS: List of private compile options +# DEFINES: List of public defines +# LINKOPTS: List of link options +# PUBLIC: Add this so that this library will be exported under absl:: (see Note). +# Also in IDE, target will appear in Abseil folder while non PUBLIC will be in Abseil/internal. +# TESTONLY: When added, this target will only be built if user passes -DABSL_RUN_TESTS=ON to CMake. +# +# Note: +# By default, absl_cc_library will always create a library named absl_internal_${NAME}, +# and alias target absl::${NAME}. +# This is to reduce namespace pollution. +# +# absl_cc_library( +# NAME +# awesome +# HDRS +# "a.h" +# SRCS +# "a.cc" +# ) +# absl_cc_library( +# NAME +# fantastic_lib +# SRCS +# "b.cc" +# DEPS +# absl_internal_awesome # not "awesome"! +# ) +# +# If PUBLIC is set, absl_cc_library will instead create a target named +# absl_${NAME} and still an alias absl::${NAME}. +# +# absl_cc_library( +# NAME +# main_lib +# ... +# PUBLIC +# ) +# +# User can then use the library as absl::main_lib (although absl_main_lib is defined too). +# +# TODO: Implement "ALWAYSLINK" +function(absl_cc_library) + cmake_parse_arguments(ABSL_CC_LIB + "DISABLE_INSTALL;PUBLIC;TESTONLY" + "NAME" + "HDRS;SRCS;COPTS;DEFINES;LINKOPTS;DEPS" + ${ARGN} + ) + if (NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS) + if (ABSL_CC_LIB_PUBLIC) + set(_NAME "absl_${ABSL_CC_LIB_NAME}") + else() + set(_NAME "absl_internal_${ABSL_CC_LIB_NAME}") + endif() + + # Check if this is a header-only library + if ("${ABSL_CC_LIB_SRCS}" STREQUAL "") + set(ABSL_CC_LIB_IS_INTERFACE 1) + else() + set(ABSL_CC_LIB_IS_INTERFACE 0) + endif() + + if(NOT ABSL_CC_LIB_IS_INTERFACE) + add_library(${_NAME} STATIC "") + target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS}) + target_include_directories(${_NAME} + PUBLIC ${ABSL_COMMON_INCLUDE_DIRS}) + target_compile_options(${_NAME} + PRIVATE ${ABSL_CC_LIB_COPTS}) + target_link_libraries(${_NAME} + PUBLIC ${ABSL_CC_LIB_DEPS} + PRIVATE ${ABSL_CC_LIB_LINKOPTS} + ) + target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES}) + + # Add all Abseil targets to a a folder in the IDE for organization. + if(ABSL_CC_LIB_PUBLIC) + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) + elseif(ABSL_CC_LIB_TESTONLY) + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test) + else() + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/internal) + endif() + + # INTERFACE libraries can't have the CXX_STANDARD property set + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) + else() + # Generating header-only library + add_library(${_NAME} INTERFACE) + target_include_directories(${_NAME} + INTERFACE ${ABSL_COMMON_INCLUDE_DIRS}) + target_link_libraries(${_NAME} + INTERFACE ${ABSL_CC_LIB_DEPS} ${ABSL_CC_LIB_LINKOPTS} + ) + target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES}) + endif() + + add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME}) + endif() +endfunction() + +# absl_cc_test() +# +# CMake function to imitate Bazel's cc_test rule. +# +# Parameters: +# NAME: name of target (see Usage below) +# SRCS: List of source files for the binary +# DEPS: List of other libraries to be linked in to the binary targets +# COPTS: List of private compile options +# DEFINES: List of public defines +# LINKOPTS: List of link options +# +# Note: +# By default, absl_cc_test will always create a binary named absl_${NAME}. +# This will also add it to ctest list as absl_${NAME}. +# +# Usage: +# absl_cc_library( +# NAME +# awesome +# HDRS +# "a.h" +# SRCS +# "a.cc" +# PUBLIC +# ) +# +# absl_cc_test( +# NAME +# awesome_test +# SRCS +# "awesome_test.cc" +# DEPS +# absl::awesome +# gmock +# gtest_main +# ) +function(absl_cc_test) + if(NOT ABSL_RUN_TESTS) + return() + endif() + + cmake_parse_arguments(ABSL_CC_TEST + "" + "NAME" + "SRCS;COPTS;DEFINES;LINKOPTS;DEPS" + ${ARGN} + ) + + set(_NAME "absl_${ABSL_CC_TEST_NAME}") + add_executable(${_NAME} "") + target_sources(${_NAME} PRIVATE ${ABSL_CC_TEST_SRCS}) + target_include_directories(${_NAME} + PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} + PRIVATE ${GMOCK_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS} + ) + target_compile_definitions(${_NAME} + PUBLIC ${ABSL_CC_TEST_DEFINES} + ) + target_compile_options(${_NAME} + PRIVATE ${ABSL_CC_TEST_COPTS} + ) + target_link_libraries(${_NAME} + PUBLIC ${ABSL_CC_TEST_DEPS} + PRIVATE ${ABSL_CC_TEST_LINKOPTS} + ) + # Add all Abseil targets to a a folder in the IDE for organization. + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test) + + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) + + add_test(NAME ${_NAME} COMMAND ${_NAME}) +endfunction() # # header only virtual target creation @@ -103,13 +295,15 @@ # Add all Abseil targets to a a folder in the IDE for organization. set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) + if(ABSL_HO_LIB_EXPORT_NAME) add_library(absl::${ABSL_HO_LIB_EXPORT_NAME} ALIAS ${_NAME}) endif() endfunction() - # # create an abseil unit_test and add it to the executed test list # @@ -137,22 +331,29 @@ if(ABSL_RUN_TESTS) - set(_NAME ${ABSL_TEST_TARGET}) + set(_NAME "absl_${ABSL_TEST_TARGET}") string(TOUPPER ${_NAME} _UPPER_NAME) - add_executable(${_NAME}_bin ${ABSL_TEST_SOURCES}) + add_executable(${_NAME} ${ABSL_TEST_SOURCES}) - target_compile_options(${_NAME}_bin PRIVATE ${ABSL_COMPILE_CXXFLAGS} ${ABSL_TEST_PRIVATE_COMPILE_FLAGS}) - target_link_libraries(${_NAME}_bin PUBLIC ${ABSL_TEST_PUBLIC_LIBRARIES} ${ABSL_TEST_COMMON_LIBRARIES}) - target_include_directories(${_NAME}_bin + target_compile_options(${_NAME} + PRIVATE + ${ABSL_TEST_PRIVATE_COMPILE_FLAGS} + ${ABSL_TEST_COPTS} + ) + target_link_libraries(${_NAME} PUBLIC ${ABSL_TEST_PUBLIC_LIBRARIES} ${ABSL_TEST_COMMON_LIBRARIES}) + target_include_directories(${_NAME} PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} ${ABSL_TEST_PUBLIC_INCLUDE_DIRS} PRIVATE ${GMOCK_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS} ) # Add all Abseil targets to a a folder in the IDE for organization. - set_property(TARGET ${_NAME}_bin PROPERTY FOLDER ${ABSL_IDE_FOLDER}) + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) - add_test(${_NAME} ${_NAME}_bin) + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) + + add_test(NAME ${_NAME} COMMAND ${_NAME}) endif(ABSL_RUN_TESTS) endfunction()
diff --git a/CMake/DownloadGTest.cmake b/CMake/DownloadGTest.cmake index 9d41321..3c682ae 100644 --- a/CMake/DownloadGTest.cmake +++ b/CMake/DownloadGTest.cmake
@@ -4,7 +4,7 @@ # Download the latest googletest from Github master configure_file( ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt.in - googletest-download/CMakeLists.txt + ${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt ) # Configure and build the downloaded googletest source
diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a7e103..3652a69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -17,29 +17,23 @@ # We require 3.0 for modern, target-based CMake. We require 3.1 for the use of # CXX_STANDARD in our targets. cmake_minimum_required(VERSION 3.1) + +# Compiler id for Apple Clang is now AppleClang. +if (POLICY CMP0025) + cmake_policy(SET CMP0025 NEW) +endif() + project(absl) -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake) +list(APPEND CMAKE_MODULE_PATH + ${CMAKE_CURRENT_LIST_DIR}/CMake + ${CMAKE_CURRENT_LIST_DIR}/absl/copts +) include(GNUInstallDirs) include(AbseilHelpers) -# config options -if (MSVC) - # /wd4005 macro-redefinition - # /wd4068 unknown pragma - # /wd4244 conversion from 'type1' to 'type2' - # /wd4267 conversion from 'size_t' to 'type2' - # /wd4800 force value to bool 'true' or 'false' (performance warning) - add_compile_options(/W3 /wd4005 /wd4068 /wd4244 /wd4267 /wd4800) - add_definitions(/DNOMINMAX /DWIN32_LEAN_AND_MEAN=1 /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS) -else() - set(ABSL_STD_CXX_FLAG "-std=c++11" CACHE STRING "c++ std flag (default: c++11)") -endif() - - - ## ## Using absl targets ## @@ -54,12 +48,15 @@ # include current path list(APPEND ABSL_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) -# -std=X -set(CMAKE_CXX_FLAGS "${ABSL_STD_CXX_FLAG} ${CMAKE_CXX_FLAGS}") - # -fexceptions set(ABSL_EXCEPTIONS_FLAG "${CMAKE_CXX_EXCEPTIONS}") +if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + set(ABSL_USING_CLANG ON) +else() + set(ABSL_USING_CLANG OFF) +endif() + # find dependencies ## pthread find_package(Threads REQUIRED)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 40351dd..f4cb4a2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md
@@ -18,6 +18,53 @@ (even if it was for a different project), you probably don't need to do it again. +## Contribution Guidelines + +Potential contributors sometimes ask us if the Abseil project is the appropriate +home for their utility library code or for specific functions implementing +missing portions of the standard. Often, the answer to this question is "no". +We’d like to articulate our thinking on this issue so that our choices can be +understood by everyone and so that contributors can have a better intuition +about whether Abseil might be interested in adopting a new library. + +### Priorities + +Although our mission is to augment the C++ standard library, our goal is not to +provide a full forward-compatible implementation of the latest standard. For us +to consider a library for inclusion in Abseil, it is not enough that a library +is useful. We generally choose to release a library when it meets at least one +of the following criteria: + +* **Widespread usage** - Using our internal codebase to help gauge usage, most + of the libraries we've released have tens of thousands of users. +* **Anticipated widespread usage** - Pre-adoption of some standard-compliant + APIs may not have broad adoption initially but can be expected to pick up + usage when it replaces legacy APIs. `absl::from_chars`, for example, + replaces existing code that converts strings to numbers and will therefore + likely see usage growth. +* **High impact** - APIs that provide a key solution to a specific problem, + such as `absl::FixedArray`, have higher impact than usage numbers may signal + and are released because of their importance. +* **Direct support for a library that falls under one of the above** - When we + want access to a smaller library as an implementation detail for a + higher-priority library we plan to release, we may release it, as we did + with portions of `absl/meta/type_traits.h`. One consequence of this is that + the presence of a library in Abseil does not necessarily mean that other + similar libraries would be a high priority. + +### API Freeze Consequences + +Via the +[Abseil Compatibility Guidelines](https://abseil.io/about/compatibility), we +have promised a large degree of API stability. In particular, we will not make +backward-incompatible changes to released APIs without also shipping a tool or +process that can upgrade our users' code. We are not yet at the point of easily +releasing such tools. Therefore, at this time, shipping a library establishes an +API contract which is borderline unchangeable. (We can add new functionality, +but we cannot easily change existing behavior.) This constraint forces us to +very carefully review all APIs that we ship. + + ## Coding Style To keep the source consistent, readable, diffable and easy to merge, we use a
diff --git a/README.md b/README.md index 8eed575..e9362be 100644 --- a/README.md +++ b/README.md
@@ -63,10 +63,14 @@ <br /> The `algorithm` library contains additions to the C++ `<algorithm>` library and container-based versions of such algorithms. * [`container`](absl/container/) - <br /> The `container` library contains additional STL-style containers. + <br /> The `container` library contains additional STL-style containers, + including Abseil's unordered "Swiss table" containers. * [`debugging`](absl/debugging/) <br /> The `debugging` library contains code useful for enabling leak - checks. Future updates will add stacktrace and symbolization utilities. + checks, and stacktrace and symbolization utilities. +* [`hash`](absl/hash/) + <br /> The `hash` library contains the hashing framework and default hash + functor implementations for hashable types in Abseil. * [`memory`](absl/memory/) <br /> The `memory` library contains C++11-compatible versions of `std::make_unique()` and related memory management facilities. @@ -90,6 +94,8 @@ * [`types`](absl/types/) <br /> The `types` library contains non-container utility types, like a C++11-compatible version of the C++17 `std::optional` type. +* [`utility`](absl/utility/) + <br /> The `utility` library contains utility and helper code. ## License
diff --git a/absl/algorithm/BUILD.bazel b/absl/algorithm/BUILD.bazel index d04dc71..4314ee8 100644 --- a/absl/algorithm/BUILD.bazel +++ b/absl/algorithm/BUILD.bazel
@@ -15,7 +15,7 @@ # load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", )
diff --git a/absl/algorithm/CMakeLists.txt b/absl/algorithm/CMakeLists.txt index fdf45c5..87a165c 100644 --- a/absl/algorithm/CMakeLists.txt +++ b/absl/algorithm/CMakeLists.txt
@@ -14,50 +14,50 @@ # limitations under the License. # -list(APPEND ALGORITHM_PUBLIC_HEADERS - "algorithm.h" - "container.h" -) - - -# -## TESTS -# - -# test algorithm_test -list(APPEND ALGORITHM_TEST_SRC - "algorithm_test.cc" - ${ALGORITHM_PUBLIC_HEADERS} - ${ALGORITHM_INTERNAL_HEADERS} -) - -absl_header_library( - TARGET - absl_algorithm - EXPORT_NAME +absl_cc_library( + NAME algorithm + HDRS + "algorithm.h" + COPTS + ${ABSL_DEFAULT_COPTS} + PUBLIC ) -absl_test( - TARGET +absl_cc_test( + NAME algorithm_test - SOURCES - ${ALGORITHM_TEST_SRC} - PUBLIC_LIBRARIES + SRCS + "algorithm_test.cc" + DEPS absl::algorithm + gmock_main ) - - - -# test container_test -set(CONTAINER_TEST_SRC "container_test.cc") - -absl_test( - TARGET - container_test - SOURCES - ${CONTAINER_TEST_SRC} - PUBLIC_LIBRARIES +absl_cc_library( + NAME + algorithm_container + HDRS + "container.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS absl::algorithm + absl::core_headers + absl::meta + PUBLIC +) + +absl_cc_test( + NAME + container_test + SRCS + "container_test.cc" + DEPS + absl::algorithm_container + absl::base + absl::core_headers + absl::memory + absl::span + gmock_main )
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h index 53ab156..6d5f663 100644 --- a/absl/algorithm/container.h +++ b/absl/algorithm/container.h
@@ -46,6 +46,8 @@ #include <iterator> #include <numeric> #include <type_traits> +#include <unordered_map> +#include <unordered_set> #include <utility> #include <vector> @@ -54,7 +56,6 @@ #include "absl/meta/type_traits.h" namespace absl { - namespace container_algorithm_internal { // NOTE: it is important to defer to ADL lookup for building with C++ modules, @@ -101,6 +102,17 @@ template <typename C> ContainerIter<C> c_end(C& c) { return end(c); } +template <typename T> +struct IsUnorderedContainer : std::false_type {}; + +template <class Key, class T, class Hash, class KeyEqual, class Allocator> +struct IsUnorderedContainer< + std::unordered_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type {}; + +template <class Key, class Hash, class KeyEqual, class Allocator> +struct IsUnorderedContainer<std::unordered_set<Key, Hash, KeyEqual, Allocator>> + : std::true_type {}; + } // namespace container_algorithm_internal // PUBLIC API @@ -1154,7 +1166,13 @@ // Container-based version of the <algorithm> `std::set_union()` function // to return an iterator containing the union of two containers; duplicate // values are not copied into the output. -template <typename C1, typename C2, typename OutputIterator> +template <typename C1, typename C2, typename OutputIterator, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C1>::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C2>::value, + void>::type> OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output) { return std::set_union(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), @@ -1164,7 +1182,13 @@ // Overload of c_set_union() for performing a merge using a `comp` other than // `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename Compare> +template <typename C1, typename C2, typename OutputIterator, typename Compare, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C1>::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C2>::value, + void>::type> OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output, Compare&& comp) { return std::set_union(container_algorithm_internal::c_begin(c1), @@ -1178,7 +1202,13 @@ // // Container-based version of the <algorithm> `std::set_intersection()` function // to return an iterator containing the intersection of two containers. -template <typename C1, typename C2, typename OutputIterator> +template <typename C1, typename C2, typename OutputIterator, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C1>::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C2>::value, + void>::type> OutputIterator c_set_intersection(const C1& c1, const C2& c2, OutputIterator output) { return std::set_intersection(container_algorithm_internal::c_begin(c1), @@ -1189,7 +1219,13 @@ // Overload of c_set_intersection() for performing a merge using a `comp` other // than `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename Compare> +template <typename C1, typename C2, typename OutputIterator, typename Compare, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C1>::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C2>::value, + void>::type> OutputIterator c_set_intersection(const C1& c1, const C2& c2, OutputIterator output, Compare&& comp) { return std::set_intersection(container_algorithm_internal::c_begin(c1), @@ -1204,7 +1240,13 @@ // Container-based version of the <algorithm> `std::set_difference()` function // to return an iterator containing elements present in the first container but // not in the second. -template <typename C1, typename C2, typename OutputIterator> +template <typename C1, typename C2, typename OutputIterator, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C1>::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C2>::value, + void>::type> OutputIterator c_set_difference(const C1& c1, const C2& c2, OutputIterator output) { return std::set_difference(container_algorithm_internal::c_begin(c1), @@ -1215,7 +1257,13 @@ // Overload of c_set_difference() for performing a merge using a `comp` other // than `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename Compare> +template <typename C1, typename C2, typename OutputIterator, typename Compare, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C1>::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C2>::value, + void>::type> OutputIterator c_set_difference(const C1& c1, const C2& c2, OutputIterator output, Compare&& comp) { return std::set_difference(container_algorithm_internal::c_begin(c1), @@ -1230,7 +1278,13 @@ // Container-based version of the <algorithm> `std::set_symmetric_difference()` // function to return an iterator containing elements present in either one // container or the other, but not both. -template <typename C1, typename C2, typename OutputIterator> +template <typename C1, typename C2, typename OutputIterator, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C1>::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C2>::value, + void>::type> OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, OutputIterator output) { return std::set_symmetric_difference( @@ -1242,7 +1296,13 @@ // Overload of c_set_symmetric_difference() for performing a merge using a // `comp` other than `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename Compare> +template <typename C1, typename C2, typename OutputIterator, typename Compare, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C1>::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer<C2>::value, + void>::type> OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, OutputIterator output, Compare&& comp) {
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index f7d8101..1c31211 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel
@@ -15,7 +15,7 @@ # load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", "ABSL_EXCEPTIONS_FLAG", @@ -75,7 +75,6 @@ copts = ABSL_DEFAULT_COPTS, deps = [ ":config", - ":dynamic_annotations", ], ) @@ -108,6 +107,7 @@ "internal/identity.h", "internal/inline_variable.h", "internal/invoke.h", + "internal/scheduling_mode.h", ], copts = ABSL_DEFAULT_COPTS, visibility = [ @@ -188,7 +188,6 @@ deps = [ ":base", ":config", - ":core_headers", ], ) @@ -231,13 +230,12 @@ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, deps = [ - ":base", ":config", ":pretty_function", "//absl/memory", "//absl/meta:type_traits", "//absl/strings", - "//absl/types:optional", + "//absl/utility", "@com_google_googletest//:gtest", ], ) @@ -316,6 +314,33 @@ ) cc_library( + name = "spinlock_benchmark_common", + testonly = 1, + srcs = ["internal/spinlock_benchmark.cc"], + copts = ABSL_DEFAULT_COPTS, + visibility = [ + "//absl/base:__pkg__", + ], + deps = [ + ":base", + ":base_internal", + "//absl/synchronization", + "@com_github_google_benchmark//:benchmark_main", + ], + alwayslink = 1, +) + +cc_binary( + name = "spinlock_benchmark", + testonly = 1, + copts = ABSL_DEFAULT_COPTS, + visibility = ["//visibility:private"], + deps = [ + ":spinlock_benchmark_common", + ], +) + +cc_library( name = "endian", hdrs = [ "internal/endian.h",
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 04a6eb3..212dd08 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt
@@ -14,374 +14,401 @@ # limitations under the License. # -list(APPEND BASE_PUBLIC_HEADERS - "attributes.h" - "call_once.h" - "casts.h" - "config.h" - "dynamic_annotations.h" - "log_severity.h" - "macros.h" - "optimization.h" - "policy_checks.h" - "port.h" - "thread_annotations.h" +absl_cc_library( + NAME + spinlock_wait + HDRS + "internal/scheduling_mode.h" + "internal/spinlock_wait.h" + SRCS + "internal/spinlock_akaros.inc" + "internal/spinlock_linux.inc" + "internal/spinlock_posix.inc" + "internal/spinlock_wait.cc" + "internal/spinlock_win32.inc" + DEPS + absl::core_headers ) - -list(APPEND BASE_INTERNAL_HEADERS - "internal/atomic_hook.h" - "internal/bits.h" - "internal/cycleclock.h" - "internal/direct_mmap.h" - "internal/endian.h" - "internal/exception_testing.h" - "internal/exception_safety_testing.h" - "internal/hide_ptr.h" - "internal/identity.h" - "internal/invoke.h" - "internal/inline_variable.h" - "internal/low_level_alloc.h" - "internal/low_level_scheduling.h" - "internal/per_thread_tls.h" - "internal/pretty_function.h" - "internal/raw_logging.h" - "internal/scheduling_mode.h" - "internal/spinlock.h" - "internal/spinlock_wait.h" - "internal/sysinfo.h" - "internal/thread_identity.h" - "internal/throw_delegate.h" - "internal/tsan_mutex_interface.h" - "internal/unaligned_access.h" - "internal/unscaledcycleclock.h" +absl_cc_library( + NAME + config + HDRS + "config.h" + "policy_checks.h" + COPTS + ${ABSL_DEFAULT_COPTS} + PUBLIC ) - -# absl_base main library -list(APPEND BASE_SRC - "internal/cycleclock.cc" - "internal/raw_logging.cc" - "internal/spinlock.cc" - "internal/sysinfo.cc" - "internal/thread_identity.cc" - "internal/unscaledcycleclock.cc" - "internal/low_level_alloc.cc" - ${BASE_PUBLIC_HEADERS} - ${BASE_INTERNAL_HEADERS} +absl_cc_library( + NAME + dynamic_annotations + HDRS + "dynamic_annotations.h" + SRCS + "dynamic_annotations.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEFINES + "__CLANG_SUPPORT_DYN_ANNOTATION__" + PUBLIC ) -absl_library( - TARGET - absl_base - SOURCES - ${BASE_SRC} - PUBLIC_LIBRARIES - absl_dynamic_annotations - absl_spinlock_wait - EXPORT_NAME - base +absl_cc_library( + NAME + core_headers + HDRS + "attributes.h" + "macros.h" + "optimization.h" + "port.h" + "thread_annotations.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::config + PUBLIC ) -# throw delegate library -set(THROW_DELEGATE_SRC "internal/throw_delegate.cc") - -absl_library( - TARGET - absl_throw_delegate - SOURCES - ${THROW_DELEGATE_SRC} - PUBLIC_LIBRARIES - ${THROW_DELEGATE_PUBLIC_LIBRARIES} - PRIVATE_COMPILE_FLAGS - ${ABSL_EXCEPTIONS_FLAG} - EXPORT_NAME - throw_delegate -) - -if(BUILD_TESTING) - # exception-safety testing library - set(EXCEPTION_SAFETY_TESTING_SRC - "internal/exception_safety_testing.h" - "internal/exception_safety_testing.cc" - ) - set(EXCEPTION_SAFETY_TESTING_PUBLIC_LIBRARIES - ${ABSL_TEST_COMMON_LIBRARIES} +absl_cc_library( + NAME + malloc_internal + HDRS + "internal/direct_mmap.h" + "internal/low_level_alloc.h" + SRCS + "internal/low_level_alloc.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS absl::base + absl::config + absl::core_headers + absl::dynamic_annotations + absl::spinlock_wait +) + +absl_cc_library( + NAME + base_internal + HDRS + "internal/hide_ptr.h" + "internal/identity.h" + "internal/inline_variable.h" + "internal/invoke.h" + COPTS + ${ABSL_DEFAULT_COPTS} +) + +absl_cc_library( + NAME + base + HDRS + "call_once.h" + "casts.h" + "internal/atomic_hook.h" + "internal/cycleclock.h" + "internal/low_level_scheduling.h" + "internal/per_thread_tls.h" + "internal/raw_logging.h" + "internal/spinlock.h" + "internal/sysinfo.h" + "internal/thread_identity.h" + "internal/tsan_mutex_interface.h" + "internal/unscaledcycleclock.h" + "log_severity.h" + SRCS + "internal/cycleclock.cc" + "internal/raw_logging.cc" + "internal/spinlock.cc" + "internal/sysinfo.cc" + "internal/thread_identity.cc" + "internal/unscaledcycleclock.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::base_internal + absl::config + absl::core_headers + absl::dynamic_annotations + absl::spinlock_wait + PUBLIC +) + +absl_cc_library( + NAME + throw_delegate + HDRS + "internal/throw_delegate.h" + SRCS + "internal/throw_delegate.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + ${ABSL_EXCEPTIONS_FLAG} + DEPS + absl::base +) + +absl_cc_library( + NAME + exception_testing + HDRS + "internal/exception_testing.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::config + gtest + TESTONLY +) + +absl_cc_library( + NAME + pretty_function + HDRS + "internal/pretty_function.h" + COPTS + ${ABSL_DEFAULT_COPTS} +) + +absl_cc_library( + NAME + exception_safety_testing + HDRS + "internal/exception_safety_testing.h" + SRCS + "internal/exception_safety_testing.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + ${ABSL_EXCEPTIONS_FLAG} + DEPS + absl::base + absl::config + absl::pretty_function absl::memory absl::meta absl::strings - absl::optional + absl::utility gtest - ) - -absl_library( - TARGET - absl_base_internal_exception_safety_testing - SOURCES - ${EXCEPTION_SAFETY_TESTING_SRC} - PUBLIC_LIBRARIES - ${EXCEPTION_SAFETY_TESTING_PUBLIC_LIBRARIES} - PRIVATE_COMPILE_FLAGS - ${ABSL_EXCEPTIONS_FLAG} -) -endif() - - -# dynamic_annotations library -set(DYNAMIC_ANNOTATIONS_SRC "dynamic_annotations.cc") - -absl_library( - TARGET - absl_dynamic_annotations - SOURCES - ${DYNAMIC_ANNOTATIONS_SRC} + TESTONLY ) - -# spinlock_wait library -set(SPINLOCK_WAIT_SRC "internal/spinlock_wait.cc") - -absl_library( - TARGET - absl_spinlock_wait - SOURCES - ${SPINLOCK_WAIT_SRC} -) - - -# malloc_internal library -list(APPEND MALLOC_INTERNAL_SRC - "internal/low_level_alloc.cc" -) - -absl_library( - TARGET - absl_malloc_internal - SOURCES - ${MALLOC_INTERNAL_SRC} - PUBLIC_LIBRARIES - absl_dynamic_annotations -) - - - -# -## TESTS -# - -# call once test -set(ATOMIC_HOOK_TEST_SRC "internal/atomic_hook_test.cc") -set(ATOMIC_HOOK_TEST_PUBLIC_LIBRARIES absl::base) - -absl_test( - TARGET - atomic_hook_test - SOURCES - ${ATOMIC_HOOK_TEST_SRC} - PUBLIC_LIBRARIES - ${ATOMIC_HOOK_TEST_PUBLIC_LIBRARIES} -) - - -# call once test -set(CALL_ONCE_TEST_SRC "call_once_test.cc") -set(CALL_ONCE_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET - call_once_test - SOURCES - ${CALL_ONCE_TEST_SRC} - PUBLIC_LIBRARIES - ${CALL_ONCE_TEST_PUBLIC_LIBRARIES} -) - - -# test bit_cast_test -set(BIT_CAST_TEST_SRC "bit_cast_test.cc") - -absl_test( - TARGET - bit_cast_test - SOURCES - ${BIT_CAST_TEST_SRC} -) - - -# test absl_throw_delegate_test -set(THROW_DELEGATE_TEST_SRC "throw_delegate_test.cc") -set(THROW_DELEGATE_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate) - -absl_test( - TARGET - throw_delegate_test - SOURCES - ${THROW_DELEGATE_TEST_SRC} - PUBLIC_LIBRARIES - ${THROW_DELEGATE_TEST_PUBLIC_LIBRARIES} -) - - -# test invoke_test -set(INVOKE_TEST_SRC "invoke_test.cc") -set(INVOKE_TEST_PUBLIC_LIBRARIES absl::strings) - -absl_test( - TARGET - invoke_test - SOURCES - ${INVOKE_TEST_SRC} - PUBLIC_LIBRARIES - ${INVOKE_TEST_PUBLIC_LIBRARIES} -) - - -# test inline_variable_test -list(APPEND INLINE_VARIABLE_TEST_SRC - "internal/inline_variable_testing.h" - "inline_variable_test.cc" - "inline_variable_test_a.cc" - "inline_variable_test_b.cc" -) - -set(INLINE_VARIABLE_TEST_PUBLIC_LIBRARIES absl::base) - -absl_test( - TARGET - inline_variable_test - SOURCES - ${INLINE_VARIABLE_TEST_SRC} - PUBLIC_LIBRARIES - ${INLINE_VARIABLE_TEST_PUBLIC_LIBRARIES} -) - - -# test spinlock_test_common -set(SPINLOCK_TEST_COMMON_SRC "spinlock_test_common.cc") -set(SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET - spinlock_test_common - SOURCES - ${SPINLOCK_TEST_COMMON_SRC} - PUBLIC_LIBRARIES - ${SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES} -) - - -# test spinlock_test -set(SPINLOCK_TEST_SRC "spinlock_test_common.cc") -set(SPINLOCK_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET - spinlock_test - SOURCES - ${SPINLOCK_TEST_SRC} - PUBLIC_LIBRARIES - ${SPINLOCK_TEST_PUBLIC_LIBRARIES} -) - - -# test endian_test -set(ENDIAN_TEST_SRC "internal/endian_test.cc") - -absl_test( - TARGET - endian_test - SOURCES - ${ENDIAN_TEST_SRC} -) - - -# test config_test -set(CONFIG_TEST_SRC "config_test.cc") -set(CONFIG_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) -absl_test( - TARGET - config_test - SOURCES - ${CONFIG_TEST_SRC} - PUBLIC_LIBRARIES - ${CONFIG_TEST_PUBLIC_LIBRARIES} -) - - -# test raw_logging_test -set(RAW_LOGGING_TEST_SRC "raw_logging_test.cc") -set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base absl::strings) - -absl_test( - TARGET - raw_logging_test - SOURCES - ${RAW_LOGGING_TEST_SRC} - PUBLIC_LIBRARIES - ${RAW_LOGGING_TEST_PUBLIC_LIBRARIES} -) - - -# test sysinfo_test -set(SYSINFO_TEST_SRC "internal/sysinfo_test.cc") -set(SYSINFO_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET - sysinfo_test - SOURCES - ${SYSINFO_TEST_SRC} - PUBLIC_LIBRARIES - ${SYSINFO_TEST_PUBLIC_LIBRARIES} -) - - -# test low_level_alloc_test -set(LOW_LEVEL_ALLOC_TEST_SRC "internal/low_level_alloc_test.cc") -set(LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES absl::base) - -absl_test( - TARGET - low_level_alloc_test - SOURCES - ${LOW_LEVEL_ALLOC_TEST_SRC} - PUBLIC_LIBRARIES - ${LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES} -) - - -# test thread_identity_test -set(THREAD_IDENTITY_TEST_SRC "internal/thread_identity_test.cc") -set(THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET - thread_identity_test - SOURCES - ${THREAD_IDENTITY_TEST_SRC} - PUBLIC_LIBRARIES - ${THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES} -) - -#test exceptions_safety_testing_test -set(EXCEPTION_SAFETY_TESTING_TEST_SRC "exception_safety_testing_test.cc") -set(EXCEPTION_SAFETY_TESTING_TEST_PUBLIC_LIBRARIES - absl::base - absl_base_internal_exception_safety_testing - absl::memory - absl::meta - absl::strings - absl::optional -) - -absl_test( - TARGET +absl_cc_test( + NAME absl_exception_safety_testing_test - SOURCES - ${EXCEPTION_SAFETY_TESTING_TEST_SRC} - PUBLIC_LIBRARIES - ${EXCEPTION_SAFETY_TESTING_TEST_PUBLIC_LIBRARIES} - PRIVATE_COMPILE_FLAGS + SRCS + "exception_safety_testing_test.cc" + COPTS ${ABSL_EXCEPTIONS_FLAG} + LINKOPTS + ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} + DEPS + absl::exception_safety_testing + absl::memory + gtest_main +) + +absl_cc_test( + NAME + atomic_hook_test + SRCS + "internal/atomic_hook_test.cc" + DEPS + absl::base + absl::core_headers + gtest_main +) + +absl_cc_test( + NAME + bit_cast_test + SRCS + "bit_cast_test.cc" + DEPS + absl::base + absl::core_headers + gtest_main +) + +absl_cc_test( + NAME + throw_delegate_test + SRCS + "throw_delegate_test.cc" + DEPS + absl::base + absl_internal_throw_delegate + gtest_main +) + +absl_cc_test( + NAME + inline_variable_test + SRCS + "internal/inline_variable_testing.h" + "inline_variable_test.cc" + "inline_variable_test_a.cc" + "inline_variable_test_b.cc" + DEPS + absl::base_internal + gtest_main +) + +absl_cc_test( + NAME + invoke_test + SRCS + "invoke_test.cc" + DEPS + absl::base_internal + absl::memory + absl::strings + gmock + gtest_main +) + +absl_cc_library( + NAME + spinlock_test_common + SRCS + "spinlock_test_common.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::base + absl::core_headers + absl::spinlock_wait + absl::synchronization + gtest + TESTONLY +) + +# On bazel BUILD this target use "alwayslink = 1" which is not implemented here +absl_cc_test( + NAME + spinlock_test + SRCS + "spinlock_test_common.cc" + DEPS + absl::base + absl::core_headers + absl::spinlock_wait + absl::synchronization + gtest_main +) + +absl_cc_library( + NAME + endian + HDRS + "internal/endian.h" + "internal/unaligned_access.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::config + absl::core_headers + PUBLIC +) + +absl_cc_test( + NAME + endian_test + SRCS + "internal/endian_test.cc" + DEPS + absl::base + absl::config + absl::endian + gtest_main +) + +absl_cc_test( + NAME + config_test + SRCS + "config_test.cc" + DEPS + absl::config + absl::synchronization + gtest_main +) + +absl_cc_test( + NAME + call_once_test + SRCS + "call_once_test.cc" + DEPS + absl::base + absl::core_headers + absl::synchronization + gtest_main +) + +absl_cc_test( + NAME + raw_logging_test + SRCS + "raw_logging_test.cc" + DEPS + absl::base + absl::strings + gtest_main +) + +absl_cc_test( + NAME + sysinfo_test + SRCS + "internal/sysinfo_test.cc" + DEPS + absl::base + absl::synchronization + gtest_main +) + +absl_cc_test( + NAME + low_level_alloc_test + SRCS + "internal/low_level_alloc_test.cc" + DEPS + absl::malloc_internal + Threads::Threads +) + +absl_cc_test( + NAME + thread_identity_test + SRCS + "internal/thread_identity_test.cc" + DEPS + absl::base + absl::core_headers + absl::synchronization + Threads::Threads + gtest_main +) + +absl_cc_library( + NAME + bits + HDRS + "internal/bits.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::core_headers +) + +absl_cc_test( + NAME + bits_test + SRCS + "internal/bits_test.cc" + DEPS + absl::bits + gtest_main )
diff --git a/absl/base/attributes.h b/absl/base/attributes.h index e850022..291ad89 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h
@@ -155,7 +155,12 @@ // ABSL_ATTRIBUTE_WEAK // // Tags a function as weak for the purposes of compilation and linking. -#if ABSL_HAVE_ATTRIBUTE(weak) || (defined(__GNUC__) && !defined(__clang__)) +// Weak attributes currently do not work properly in LLVM's Windows backend, +// so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598 +// for futher information. +#if (ABSL_HAVE_ATTRIBUTE(weak) || \ + (defined(__GNUC__) && !defined(__clang__))) && \ + !(defined(__llvm__) && defined(_WIN32)) #undef ABSL_ATTRIBUTE_WEAK #define ABSL_ATTRIBUTE_WEAK __attribute__((weak)) #define ABSL_HAVE_ATTRIBUTE_WEAK 1 @@ -296,13 +301,13 @@ // ABSL_HAVE_ATTRIBUTE_SECTION // -// Indicates whether labeled sections are supported. Labeled sections are not -// supported on Darwin/iOS. +// Indicates whether labeled sections are supported. Weak symbol support is +// a prerequisite. Labeled sections are not supported on Darwin/iOS. #ifdef ABSL_HAVE_ATTRIBUTE_SECTION #error ABSL_HAVE_ATTRIBUTE_SECTION cannot be directly set #elif (ABSL_HAVE_ATTRIBUTE(section) || \ (defined(__GNUC__) && !defined(__clang__))) && \ - !defined(__APPLE__) + !defined(__APPLE__) && ABSL_HAVE_ATTRIBUTE_WEAK #define ABSL_HAVE_ATTRIBUTE_SECTION 1 // ABSL_ATTRIBUTE_SECTION @@ -397,17 +402,28 @@ // ABSL_MUST_USE_RESULT // -// Tells the compiler to warn about unused return values for functions declared -// with this macro. The macro must appear as the very first part of a function -// declaration or definition: +// Tells the compiler to warn about unused results. // -// Example: +// When annotating a function, it must appear as the first part of the +// declaration or definition. The compiler will warn if the return value from +// such a function is unused: // // ABSL_MUST_USE_RESULT Sprocket* AllocateSprocket(); +// AllocateSprocket(); // Triggers a warning. // -// This placement has the broadest compatibility with GCC, Clang, and MSVC, with -// both defs and decls, and with GCC-style attributes, MSVC declspec, C++11 -// and C++17 attributes. +// When annotating a class, it is equivalent to annotating every function which +// returns an instance. +// +// class ABSL_MUST_USE_RESULT Sprocket {}; +// Sprocket(); // Triggers a warning. +// +// Sprocket MakeSprocket(); +// MakeSprocket(); // Triggers a warning. +// +// Note that references and pointers are not instances: +// +// Sprocket* SprocketPointer(); +// SprocketPointer(); // Does *not* trigger a warning. // // ABSL_MUST_USE_RESULT allows using cast-to-void to suppress the unused result // warning. For that, warn_unused_result is used only for clang but not for gcc.
diff --git a/absl/base/call_once.h b/absl/base/call_once.h index 532ee2e..f6c8ebb 100644 --- a/absl/base/call_once.h +++ b/absl/base/call_once.h
@@ -150,12 +150,8 @@ old_control != kOnceRunning && old_control != kOnceWaiter && old_control != kOnceDone) { - ABSL_RAW_LOG( - FATAL, - "Unexpected value for control word: %lx. Either the control word " - "has non-static storage duration (where GoogleOnceDynamic might " - "be appropriate), or there's been a memory corruption.", - static_cast<unsigned long>(old_control)); // NOLINT + ABSL_RAW_LOG(FATAL, "Unexpected value for control word: 0x%lx", + static_cast<unsigned long>(old_control)); // NOLINT } } #endif // NDEBUG
diff --git a/absl/base/call_once_test.cc b/absl/base/call_once_test.cc index cd58ee1..aa7eb95 100644 --- a/absl/base/call_once_test.cc +++ b/absl/base/call_once_test.cc
@@ -18,6 +18,7 @@ #include <vector> #include "gtest/gtest.h" +#include "absl/base/attributes.h" #include "absl/base/thread_annotations.h" #include "absl/synchronization/mutex.h"
diff --git a/absl/base/casts.h b/absl/base/casts.h index 20fd34d..1eef6a6 100644 --- a/absl/base/casts.h +++ b/absl/base/casts.h
@@ -105,7 +105,7 @@ // // Such implicit cast chaining may be useful within template logic. template <typename To> -inline To implicit_cast(typename absl::internal::identity_t<To> to) { +constexpr To implicit_cast(typename absl::internal::identity_t<To> to) { return to; }
diff --git a/absl/base/config.h b/absl/base/config.h index d4eb7d0..db4c453 100644 --- a/absl/base/config.h +++ b/absl/base/config.h
@@ -139,12 +139,18 @@ #ifdef ABSL_HAVE_THREAD_LOCAL #error ABSL_HAVE_THREAD_LOCAL cannot be directly set #elif defined(__APPLE__) -// Notes: Xcode's clang did not support `thread_local` until version -// 8, and even then not for all iOS < 9.0. Also, Xcode 9.3 started disallowing -// `thread_local` for 32-bit iOS simulator targeting iOS 9.x. -// `__has_feature` is only supported by Clang so it has be inside +// Notes: +// * Xcode's clang did not support `thread_local` until version 8, and +// even then not for all iOS < 9.0. +// * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator +// targeting iOS 9.x. +// * Xcode 10 moves the deployment target check for iOS < 9.0 to link time +// making __has_feature unreliable there. +// +// Otherwise, `__has_feature` is only supported by Clang so it has be inside // `defined(__APPLE__)` check. -#if __has_feature(cxx_thread_local) +#if __has_feature(cxx_thread_local) && \ + !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0) #define ABSL_HAVE_THREAD_LOCAL 1 #endif #else // !defined(__APPLE__) @@ -268,7 +274,8 @@ #error ABSL_HAVE_MMAP cannot be directly set #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \ - defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) + defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) || \ + defined(__ASYLO__) #define ABSL_HAVE_MMAP 1 #endif @@ -322,6 +329,8 @@ #define ABSL_HAVE_ALARM 1 #elif defined(_MSC_VER) // feature tests for Microsoft's library +#elif defined(__EMSCRIPTEN__) +// emscripten doesn't support signals #elif defined(__native_client__) #else // other standard libraries @@ -356,6 +365,18 @@ #error "absl endian detection needs to be set up for your compiler" #endif +// MacOS 10.13 doesn't let you use <any>, <optional>, or <variant> even though +// the headers exist and are publicly noted to work. See +// https://github.com/abseil/abseil-cpp/issues/207 and +// https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes +#if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \ + defined(__MAC_OS_X_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 +#define ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES 1 +#else +#define ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES 0 +#endif + // ABSL_HAVE_STD_ANY // // Checks whether C++17 std::any is available by checking whether <any> exists. @@ -364,7 +385,8 @@ #endif #ifdef __has_include -#if __has_include(<any>) && __cplusplus >= 201703L +#if __has_include(<any>) && __cplusplus >= 201703L && \ + ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES #define ABSL_HAVE_STD_ANY 1 #endif #endif @@ -377,7 +399,8 @@ #endif #ifdef __has_include -#if __has_include(<optional>) && __cplusplus >= 201703L +#if __has_include(<optional>) && __cplusplus >= 201703L && \ + ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES #define ABSL_HAVE_STD_OPTIONAL 1 #endif #endif @@ -390,7 +413,8 @@ #endif #ifdef __has_include -#if __has_include(<variant>) && __cplusplus >= 201703L +#if __has_include(<variant>) && __cplusplus >= 201703L && \ + ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES #define ABSL_HAVE_STD_VARIANT 1 #endif #endif @@ -423,4 +447,12 @@ #define ABSL_HAVE_STD_STRING_VIEW 1 #endif +// In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION +// SEH exception from emplace for variant<SomeStruct> when constructing the +// struct can throw. This defeats some of variant_test and +// variant_exception_safety_test. +#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_DEBUG) +#define ABSL_INTERNAL_MSVC_2017_DBG_MODE +#endif + #endif // ABSL_BASE_CONFIG_H_
diff --git a/absl/base/exception_safety_testing_test.cc b/absl/base/exception_safety_testing_test.cc index 106bc34..7518264 100644 --- a/absl/base/exception_safety_testing_test.cc +++ b/absl/base/exception_safety_testing_test.cc
@@ -770,6 +770,18 @@ .Test(invoker)); } +TEST(ExceptionSafetyTesterTest, ResetsCountdown) { + auto test = + testing::MakeExceptionSafetyTester() + .WithInitialValue(ThrowingValue<>()) + .WithContracts([](ThrowingValue<>*) { return AssertionSuccess(); }) + .WithOperation([](ThrowingValue<>*) {}); + ASSERT_TRUE(test.Test()); + // If the countdown isn't reset because there were no exceptions thrown, then + // this will fail with a termination from an unhandled exception + EXPECT_TRUE(test.Test()); +} + struct NonCopyable : public NonNegative { NonCopyable(const NonCopyable&) = delete; NonCopyable() : NonNegative{0} {}
diff --git a/absl/base/internal/direct_mmap.h b/absl/base/internal/direct_mmap.h index 0426e11..654a600 100644 --- a/absl/base/internal/direct_mmap.h +++ b/absl/base/internal/direct_mmap.h
@@ -75,7 +75,11 @@ // On these architectures, implement mmap with mmap2. static int pagesize = 0; if (pagesize == 0) { +#if defined(__wasm__) || defined(__asmjs__) pagesize = getpagesize(); +#else + pagesize = sysconf(_SC_PAGESIZE); +#endif } if (offset < 0 || offset % pagesize != 0) { errno = EINVAL;
diff --git a/absl/base/internal/endian.h b/absl/base/internal/endian.h index edc10f1..d5dc51a 100644 --- a/absl/base/internal/endian.h +++ b/absl/base/internal/endian.h
@@ -82,14 +82,14 @@ #elif defined(__GLIBC__) return bswap_64(host_int); #else - return (((x & uint64_t{(0xFF}) << 56) | - ((x & uint64_t{(0xFF00}) << 40) | - ((x & uint64_t{(0xFF0000}) << 24) | - ((x & uint64_t{(0xFF000000}) << 8) | - ((x & uint64_t{(0xFF00000000}) >> 8) | - ((x & uint64_t{(0xFF0000000000}) >> 24) | - ((x & uint64_t{(0xFF000000000000}) >> 40) | - ((x & uint64_t{(0xFF00000000000000}) >> 56)); + return (((host_int & uint64_t{0xFF}) << 56) | + ((host_int & uint64_t{0xFF00}) << 40) | + ((host_int & uint64_t{0xFF0000}) << 24) | + ((host_int & uint64_t{0xFF000000}) << 8) | + ((host_int & uint64_t{0xFF00000000}) >> 8) | + ((host_int & uint64_t{0xFF0000000000}) >> 24) | + ((host_int & uint64_t{0xFF000000000000}) >> 40) | + ((host_int & uint64_t{0xFF00000000000000}) >> 56)); #endif // bswap_64 } @@ -97,8 +97,10 @@ #if defined(__GLIBC__) return bswap_32(host_int); #else - return (((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | - ((x & 0xFF000000) >> 24)); + return (((host_int & uint32_t{0xFF}) << 24) | + ((host_int & uint32_t{0xFF00}) << 8) | + ((host_int & uint32_t{0xFF0000}) >> 8) | + ((host_int & uint32_t{0xFF000000}) >> 24)); #endif } @@ -106,7 +108,8 @@ #if defined(__GLIBC__) return bswap_16(host_int); #else - return uint16_t{((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)}; + return (((host_int & uint16_t{0xFF}) << 8) | + ((host_int & uint16_t{0xFF00}) >> 8)); #endif }
diff --git a/absl/base/internal/exception_safety_testing.cc b/absl/base/internal/exception_safety_testing.cc index f1d081f..8207b7d 100644 --- a/absl/base/internal/exception_safety_testing.cc +++ b/absl/base/internal/exception_safety_testing.cc
@@ -23,6 +23,10 @@ exceptions_internal::StrongGuaranteeTagType strong_guarantee; +exceptions_internal::ExceptionSafetyTestBuilder<> MakeExceptionSafetyTester() { + return {}; +} + namespace exceptions_internal { int countdown = -1;
diff --git a/absl/base/internal/exception_safety_testing.h b/absl/base/internal/exception_safety_testing.h index 5665a1b..d4d41a8 100644 --- a/absl/base/internal/exception_safety_testing.h +++ b/absl/base/internal/exception_safety_testing.h
@@ -33,7 +33,7 @@ #include "absl/meta/type_traits.h" #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" -#include "absl/types/optional.h" +#include "absl/utility/utility.h" namespace testing { @@ -127,10 +127,8 @@ void* address = it.first; TrackedAddress& tracked_address = it.second; if (tracked_address.is_alive) { - ADD_FAILURE() << "Object at address " << address - << " with countdown of " << countdown_ - << " was not destroyed [" << tracked_address.description - << "]"; + ADD_FAILURE() << ErrorMessage(address, tracked_address.description, + countdown_, "Object was not destroyed."); } } } @@ -141,11 +139,11 @@ TrackedAddress& tracked_address = current_tracker_instance_->address_map_[address]; if (tracked_address.is_alive) { - ADD_FAILURE() << "Object at address " << address << " with countdown of " - << current_tracker_instance_->countdown_ - << " was re-constructed. Previously: [" - << tracked_address.description << "] Now: [" << description - << "]"; + ADD_FAILURE() << ErrorMessage( + address, tracked_address.description, + current_tracker_instance_->countdown_, + "Object was re-constructed. Current object was constructed by " + + description); } tracked_address = {true, std::move(description)}; } @@ -159,10 +157,9 @@ TrackedAddress& tracked_address = it->second; if (!tracked_address.is_alive) { - ADD_FAILURE() << "Object at address " << address << " with countdown of " - << current_tracker_instance_->countdown_ - << " was re-destroyed or created prior to construction " - << "tracking [" << tracked_address.description << "]"; + ADD_FAILURE() << ErrorMessage(address, tracked_address.description, + current_tracker_instance_->countdown_, + "Object was re-destroyed."); } tracked_address.is_alive = false; } @@ -172,6 +169,16 @@ return current_tracker_instance_ != nullptr; } + static std::string ErrorMessage(void* address, const std::string& address_description, + int countdown, const std::string& error_description) { + return absl::Substitute( + "With coundtown at $0:\n" + " $1\n" + " Object originally constructed by $2\n" + " Object address: $3\n", + countdown, error_description, address_description, address); + } + std::unordered_map<void*, TrackedAddress> address_map_; int countdown_; @@ -190,70 +197,6 @@ ~TrackedObject() noexcept { ConstructorTracker::ObjectDestructed(this); } }; - -template <typename Factory, typename Operation, typename Contract> -absl::optional<testing::AssertionResult> TestSingleContractAtCountdownImpl( - const Factory& factory, const Operation& operation, int count, - const Contract& contract) { - auto t_ptr = factory(); - absl::optional<testing::AssertionResult> current_res; - SetCountdown(count); - try { - operation(t_ptr.get()); - } catch (const exceptions_internal::TestException& e) { - current_res.emplace(contract(t_ptr.get())); - if (!current_res.value()) { - *current_res << e.what() << " failed contract check"; - } - } - UnsetCountdown(); - return current_res; -} - -template <typename Factory, typename Operation> -absl::optional<testing::AssertionResult> TestSingleContractAtCountdownImpl( - const Factory& factory, const Operation& operation, int count, - StrongGuaranteeTagType) { - using TPtr = typename decltype(factory())::pointer; - auto t_is_strong = [&](TPtr t) { return *t == *factory(); }; - return TestSingleContractAtCountdownImpl(factory, operation, count, - t_is_strong); -} - -template <typename Factory, typename Operation, typename Contract> -int TestSingleContractAtCountdown( - const Factory& factory, const Operation& operation, int count, - const Contract& contract, - absl::optional<testing::AssertionResult>* reduced_res) { - // If reduced_res is empty, it means the current call to - // TestSingleContractAtCountdown(...) is the first test being run so we do - // want to run it. Alternatively, if it's not empty (meaning a previous test - // has run) we want to check if it passed. If the previous test did pass, we - // want to contine running tests so we do want to run the current one. If it - // failed, we want to short circuit so as not to overwrite the AssertionResult - // output. If that's the case, we do not run the current test and instead we - // simply return. - if (!reduced_res->has_value() || reduced_res->value()) { - *reduced_res = - TestSingleContractAtCountdownImpl(factory, operation, count, contract); - } - return 0; -} - -template <typename Factory, typename Operation, typename... Contracts> -inline absl::optional<testing::AssertionResult> TestAllContractsAtCountdown( - const Factory& factory, const Operation& operation, int count, - const Contracts&... contracts) { - absl::optional<testing::AssertionResult> reduced_res; - - // Run each checker, short circuiting after the first failure - int dummy[] = { - 0, (TestSingleContractAtCountdown(factory, operation, count, contracts, - &reduced_res))...}; - static_cast<void>(dummy); - return reduced_res; -} - } // namespace exceptions_internal extern exceptions_internal::NoThrowTag nothrow_ctor; @@ -773,7 +716,7 @@ } size_type max_size() const noexcept { - return std::numeric_limits<difference_type>::max() / sizeof(value_type); + return (std::numeric_limits<difference_type>::max)() / sizeof(value_type); } ThrowingAllocator select_on_container_copy_construction() noexcept( @@ -871,7 +814,7 @@ namespace exceptions_internal { -// Dummy struct for ExceptionSafetyTester<> partial state. +// Dummy struct for ExceptionSafetyTestBuilder<> partial state. struct UninitializedT {}; template <typename T> @@ -893,20 +836,97 @@ template <typename Factory = UninitializedT, typename Operation = UninitializedT, typename... Contracts> -class ExceptionSafetyTester; +class ExceptionSafetyTestBuilder; } // namespace exceptions_internal -exceptions_internal::ExceptionSafetyTester<> MakeExceptionSafetyTester(); +/* + * Constructs an empty ExceptionSafetyTestBuilder. All + * ExceptionSafetyTestBuilder objects are immutable and all With[thing] mutation + * methods return new instances of ExceptionSafetyTestBuilder. + * + * In order to test a T for exception safety, a factory for that T, a testable + * operation, and at least one contract callback returning an assertion + * result must be applied using the respective methods. + */ +exceptions_internal::ExceptionSafetyTestBuilder<> MakeExceptionSafetyTester(); namespace exceptions_internal { +template <typename T> +struct IsUniquePtr : std::false_type {}; + +template <typename T, typename D> +struct IsUniquePtr<std::unique_ptr<T, D>> : std::true_type {}; + +template <typename Factory> +struct FactoryPtrTypeHelper { + using type = decltype(std::declval<const Factory&>()()); + + static_assert(IsUniquePtr<type>::value, "Factories must return a unique_ptr"); +}; + +template <typename Factory> +using FactoryPtrType = typename FactoryPtrTypeHelper<Factory>::type; + +template <typename Factory> +using FactoryElementType = typename FactoryPtrType<Factory>::element_type; + +template <typename T> +class ExceptionSafetyTest { + using Factory = std::function<std::unique_ptr<T>()>; + using Operation = std::function<void(T*)>; + using Contract = std::function<AssertionResult(T*)>; + + public: + template <typename... Contracts> + explicit ExceptionSafetyTest(const Factory& f, const Operation& op, + const Contracts&... contracts) + : factory_(f), operation_(op), contracts_{WrapContract(contracts)...} {} + + AssertionResult Test() const { + for (int count = 0;; ++count) { + exceptions_internal::ConstructorTracker ct(count); + + for (const auto& contract : contracts_) { + auto t_ptr = factory_(); + try { + SetCountdown(count); + operation_(t_ptr.get()); + // Unset for the case that the operation throws no exceptions, which + // would leave the countdown set and break the *next* exception safety + // test after this one. + UnsetCountdown(); + return AssertionSuccess(); + } catch (const exceptions_internal::TestException& e) { + if (!contract(t_ptr.get())) { + return AssertionFailure() << e.what() << " failed contract check"; + } + } + } + } + } + + private: + template <typename ContractFn> + Contract WrapContract(const ContractFn& contract) { + return [contract](T* t_ptr) { return AssertionResult(contract(t_ptr)); }; + } + + Contract WrapContract(StrongGuaranteeTagType) { + return [this](T* t_ptr) { return AssertionResult(*factory_() == *t_ptr); }; + } + + Factory factory_; + Operation operation_; + std::vector<Contract> contracts_; +}; /* * Builds a tester object that tests if performing a operation on a T follows * exception safety guarantees. Verification is done via contract assertion * callbacks applied to T instances post-throw. * - * Template parameters for ExceptionSafetyTester: + * Template parameters for ExceptionSafetyTestBuilder: * * - Factory: The factory object (passed in via tester.WithFactory(...) or * tester.WithInitialValue(...)) must be invocable with the signature @@ -933,13 +953,13 @@ * please. */ template <typename Factory, typename Operation, typename... Contracts> -class ExceptionSafetyTester { +class ExceptionSafetyTestBuilder { public: /* - * Returns a new ExceptionSafetyTester with an included T factory based on the - * provided T instance. The existing factory will not be included in the newly - * created tester instance. The created factory returns a new T instance by - * copy-constructing the provided const T& t. + * Returns a new ExceptionSafetyTestBuilder with an included T factory based + * on the provided T instance. The existing factory will not be included in + * the newly created tester instance. The created factory returns a new T + * instance by copy-constructing the provided const T& t. * * Preconditions for tester.WithInitialValue(const T& t): * @@ -948,41 +968,41 @@ * tester.WithFactory(...). */ template <typename T> - ExceptionSafetyTester<DefaultFactory<T>, Operation, Contracts...> + ExceptionSafetyTestBuilder<DefaultFactory<T>, Operation, Contracts...> WithInitialValue(const T& t) const { return WithFactory(DefaultFactory<T>(t)); } /* - * Returns a new ExceptionSafetyTester with the provided T factory included. - * The existing factory will not be included in the newly-created tester - * instance. This method is intended for use with types lacking a copy + * Returns a new ExceptionSafetyTestBuilder with the provided T factory + * included. The existing factory will not be included in the newly-created + * tester instance. This method is intended for use with types lacking a copy * constructor. Types that can be copy-constructed should instead use the * method tester.WithInitialValue(...). */ template <typename NewFactory> - ExceptionSafetyTester<absl::decay_t<NewFactory>, Operation, Contracts...> + ExceptionSafetyTestBuilder<absl::decay_t<NewFactory>, Operation, Contracts...> WithFactory(const NewFactory& new_factory) const { return {new_factory, operation_, contracts_}; } /* - * Returns a new ExceptionSafetyTester with the provided testable operation - * included. The existing operation will not be included in the newly created - * tester. + * Returns a new ExceptionSafetyTestBuilder with the provided testable + * operation included. The existing operation will not be included in the + * newly created tester. */ template <typename NewOperation> - ExceptionSafetyTester<Factory, absl::decay_t<NewOperation>, Contracts...> + ExceptionSafetyTestBuilder<Factory, absl::decay_t<NewOperation>, Contracts...> WithOperation(const NewOperation& new_operation) const { return {factory_, new_operation, contracts_}; } /* - * Returns a new ExceptionSafetyTester with the provided MoreContracts... + * Returns a new ExceptionSafetyTestBuilder with the provided MoreContracts... * combined with the Contracts... that were already included in the instance * on which the method was called. Contracts... cannot be removed or replaced - * once added to an ExceptionSafetyTester instance. A fresh object must be - * created in order to get an empty Contracts... list. + * once added to an ExceptionSafetyTestBuilder instance. A fresh object must + * be created in order to get an empty Contracts... list. * * In addition to passing in custom contract assertion callbacks, this method * accepts `testing::strong_guarantee` as an argument which checks T instances @@ -991,8 +1011,8 @@ * properly rolled back. */ template <typename... MoreContracts> - ExceptionSafetyTester<Factory, Operation, Contracts..., - absl::decay_t<MoreContracts>...> + ExceptionSafetyTestBuilder<Factory, Operation, Contracts..., + absl::decay_t<MoreContracts>...> WithContracts(const MoreContracts&... more_contracts) const { return { factory_, operation_, @@ -1039,48 +1059,27 @@ typename LazyOperation = Operation, typename = EnableIfTestable<sizeof...(Contracts), Factory, LazyOperation>> testing::AssertionResult Test() const { - return TestImpl(operation_, absl::index_sequence_for<Contracts...>()); + return Test(operation_); } private: template <typename, typename, typename...> - friend class ExceptionSafetyTester; + friend class ExceptionSafetyTestBuilder; - friend ExceptionSafetyTester<> testing::MakeExceptionSafetyTester(); + friend ExceptionSafetyTestBuilder<> testing::MakeExceptionSafetyTester(); - ExceptionSafetyTester() {} + ExceptionSafetyTestBuilder() {} - ExceptionSafetyTester(const Factory& f, const Operation& o, - const std::tuple<Contracts...>& i) + ExceptionSafetyTestBuilder(const Factory& f, const Operation& o, + const std::tuple<Contracts...>& i) : factory_(f), operation_(o), contracts_(i) {} template <typename SelectedOperation, size_t... Indices> - testing::AssertionResult TestImpl(const SelectedOperation& selected_operation, + testing::AssertionResult TestImpl(SelectedOperation selected_operation, absl::index_sequence<Indices...>) const { - // Starting from 0 and counting upwards until one of the exit conditions is - // hit... - for (int count = 0;; ++count) { - exceptions_internal::ConstructorTracker ct(count); - - // Run the full exception safety test algorithm for the current countdown - auto reduced_res = - TestAllContractsAtCountdown(factory_, selected_operation, count, - std::get<Indices>(contracts_)...); - // If there is no value in the optional, no contracts were run because no - // exception was thrown. This means that the test is complete and the loop - // can exit successfully. - if (!reduced_res.has_value()) { - return testing::AssertionSuccess(); - } - // If the optional is not empty and the value is falsy, an contract check - // failed so the test must exit to propegate the failure. - if (!reduced_res.value()) { - return reduced_res.value(); - } - // If the optional is not empty and the value is not falsy, it means - // exceptions were thrown but the contracts passed so the test must - // continue to run. - } + return ExceptionSafetyTest<FactoryElementType<Factory>>( + factory_, selected_operation, std::get<Indices>(contracts_)...) + .Test(); } Factory factory_; @@ -1090,20 +1089,6 @@ } // namespace exceptions_internal -/* - * Constructs an empty ExceptionSafetyTester. All ExceptionSafetyTester - * objects are immutable and all With[thing] mutation methods return new - * instances of ExceptionSafetyTester. - * - * In order to test a T for exception safety, a factory for that T, a testable - * operation, and at least one contract callback returning an assertion - * result must be applied using the respective methods. - */ -inline exceptions_internal::ExceptionSafetyTester<> -MakeExceptionSafetyTester() { - return {}; -} - } // namespace testing #endif // ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_
diff --git a/absl/base/internal/low_level_alloc.cc b/absl/base/internal/low_level_alloc.cc index 6e636a0..4af9c05 100644 --- a/absl/base/internal/low_level_alloc.cc +++ b/absl/base/internal/low_level_alloc.cc
@@ -208,7 +208,7 @@ int32_t allocation_count GUARDED_BY(mu); // flags passed to NewArena const uint32_t flags; - // Result of getpagesize() + // Result of sysconf(_SC_PAGESIZE) const size_t pagesize; // Lowest power of two >= max(16, sizeof(AllocList)) const size_t roundup; @@ -324,8 +324,10 @@ SYSTEM_INFO system_info; GetSystemInfo(&system_info); return std::max(system_info.dwPageSize, system_info.dwAllocationGranularity); -#else +#elif defined(__wasm__) || defined(__asmjs__) return getpagesize(); +#else + return sysconf(_SC_PAGESIZE); #endif }
diff --git a/absl/base/internal/spinlock.cc b/absl/base/internal/spinlock.cc index 1b97efb..28ba1af 100644 --- a/absl/base/internal/spinlock.cc +++ b/absl/base/internal/spinlock.cc
@@ -95,13 +95,9 @@ } // Monitor the lock to see if its value changes within some time period -// (adaptive_spin_count loop iterations). A timestamp indicating -// when the thread initially started waiting for the lock is passed in via -// the initial_wait_timestamp value. The total wait time in cycles for the -// lock is returned in the wait_cycles parameter. The last value read -// from the lock is returned from the method. -uint32_t SpinLock::SpinLoop(int64_t initial_wait_timestamp, - uint32_t *wait_cycles) { +// (adaptive_spin_count loop iterations). The last value read from the lock +// is returned from the method. +uint32_t SpinLock::SpinLoop() { // We are already in the slow path of SpinLock, initialize the // adaptive_spin_count here. ABSL_CONST_INIT static absl::once_flag init_adaptive_spin_count; @@ -115,22 +111,21 @@ do { lock_value = lockword_.load(std::memory_order_relaxed); } while ((lock_value & kSpinLockHeld) != 0 && --c > 0); - uint32_t spin_loop_wait_cycles = - EncodeWaitCycles(initial_wait_timestamp, CycleClock::Now()); - *wait_cycles = spin_loop_wait_cycles; - - return TryLockInternal(lock_value, spin_loop_wait_cycles); + return lock_value; } void SpinLock::SlowLock() { + uint32_t lock_value = SpinLoop(); + lock_value = TryLockInternal(lock_value, 0); + if ((lock_value & kSpinLockHeld) == 0) { + return; + } // The lock was not obtained initially, so this thread needs to wait for // it. Record the current timestamp in the local variable wait_start_time // so the total wait time can be stored in the lockword once this thread // obtains the lock. int64_t wait_start_time = CycleClock::Now(); - uint32_t wait_cycles; - uint32_t lock_value = SpinLoop(wait_start_time, &wait_cycles); - + uint32_t wait_cycles = 0; int lock_wait_call_count = 0; while ((lock_value & kSpinLockHeld) != 0) { // If the lock is currently held, but not marked as having a sleeper, mark @@ -141,7 +136,7 @@ // owner to think it experienced contention. if (lockword_.compare_exchange_strong( lock_value, lock_value | kSpinLockSleeper, - std::memory_order_acquire, std::memory_order_relaxed)) { + std::memory_order_relaxed, std::memory_order_relaxed)) { // Successfully transitioned to kSpinLockSleeper. Pass // kSpinLockSleeper to the SpinLockWait routine to properly indicate // the last lock_value observed. @@ -170,7 +165,9 @@ ABSL_TSAN_MUTEX_POST_DIVERT(this, 0); // Spin again after returning from the wait routine to give this thread // some chance of obtaining the lock. - lock_value = SpinLoop(wait_start_time, &wait_cycles); + lock_value = SpinLoop(); + wait_cycles = EncodeWaitCycles(wait_start_time, CycleClock::Now()); + lock_value = TryLockInternal(lock_value, wait_cycles); } } @@ -206,14 +203,20 @@ (wait_end_time - wait_start_time) >> PROFILE_TIMESTAMP_SHIFT; // Return a representation of the time spent waiting that can be stored in - // the lock word's upper bits. bit_cast is required as Atomic32 is signed. - const uint32_t clamped = static_cast<uint32_t>( + // the lock word's upper bits. + uint32_t clamped = static_cast<uint32_t>( std::min(scaled_wait_time, kMaxWaitTime) << LOCKWORD_RESERVED_SHIFT); - // bump up value if necessary to avoid returning kSpinLockSleeper. - const uint32_t after_spinlock_sleeper = - kSpinLockSleeper + (1 << LOCKWORD_RESERVED_SHIFT); - return clamped == kSpinLockSleeper ? after_spinlock_sleeper : clamped; + if (clamped == 0) { + return kSpinLockSleeper; // Just wake waiters, but don't record contention. + } + // Bump up value if necessary to avoid returning kSpinLockSleeper. + const uint32_t kMinWaitTime = + kSpinLockSleeper + (1 << LOCKWORD_RESERVED_SHIFT); + if (clamped == kSpinLockSleeper) { + return kMinWaitTime; + } + return clamped; } uint64_t SpinLock::DecodeWaitCycles(uint32_t lock_value) {
diff --git a/absl/base/internal/spinlock.h b/absl/base/internal/spinlock.h index 212abc6..eb3eec9 100644 --- a/absl/base/internal/spinlock.h +++ b/absl/base/internal/spinlock.h
@@ -101,8 +101,8 @@ inline void Unlock() UNLOCK_FUNCTION() { ABSL_TSAN_MUTEX_PRE_UNLOCK(this, 0); uint32_t lock_value = lockword_.load(std::memory_order_relaxed); - lockword_.store(lock_value & kSpinLockCooperative, - std::memory_order_release); + lock_value = lockword_.exchange(lock_value & kSpinLockCooperative, + std::memory_order_release); if ((lock_value & kSpinLockDisabledScheduling) != 0) { base_internal::SchedulingGuard::EnableRescheduling(true); @@ -161,7 +161,7 @@ void InitLinkerInitializedAndCooperative(); void SlowLock() ABSL_ATTRIBUTE_COLD; void SlowUnlock(uint32_t lock_value) ABSL_ATTRIBUTE_COLD; - uint32_t SpinLoop(int64_t initial_wait_timestamp, uint32_t* wait_cycles); + uint32_t SpinLoop(); inline bool TryLockImpl() { uint32_t lock_value = lockword_.load(std::memory_order_relaxed);
diff --git a/absl/base/internal/spinlock_benchmark.cc b/absl/base/internal/spinlock_benchmark.cc new file mode 100644 index 0000000..907d3e2 --- /dev/null +++ b/absl/base/internal/spinlock_benchmark.cc
@@ -0,0 +1,52 @@ +// 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. + +// See also //absl/synchronization:mutex_benchmark for a comparison of SpinLock +// and Mutex performance under varying levels of contention. + +#include "absl/base/internal/raw_logging.h" +#include "absl/base/internal/scheduling_mode.h" +#include "absl/base/internal/spinlock.h" +#include "absl/synchronization/internal/create_thread_identity.h" +#include "benchmark/benchmark.h" + +namespace { + +template <absl::base_internal::SchedulingMode scheduling_mode> +static void BM_SpinLock(benchmark::State& state) { + // Ensure a ThreadIdentity is installed. + ABSL_INTERNAL_CHECK( + absl::synchronization_internal::GetOrCreateCurrentThreadIdentity() != + nullptr, + "GetOrCreateCurrentThreadIdentity() failed"); + + static auto* spinlock = new absl::base_internal::SpinLock(scheduling_mode); + for (auto _ : state) { + absl::base_internal::SpinLockHolder holder(spinlock); + } +} + +BENCHMARK_TEMPLATE(BM_SpinLock, + absl::base_internal::SCHEDULE_KERNEL_ONLY) + ->UseRealTime() + ->Threads(1) + ->ThreadPerCpu(); + +BENCHMARK_TEMPLATE(BM_SpinLock, + absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL) + ->UseRealTime() + ->Threads(1) + ->ThreadPerCpu(); + +} // namespace
diff --git a/absl/base/internal/spinlock_wait.cc b/absl/base/internal/spinlock_wait.cc index 0fde9c0..365a793 100644 --- a/absl/base/internal/spinlock_wait.cc +++ b/absl/base/internal/spinlock_wait.cc
@@ -38,14 +38,15 @@ uint32_t SpinLockWait(std::atomic<uint32_t> *w, int n, const SpinLockWaitTransition trans[], base_internal::SchedulingMode scheduling_mode) { - for (int loop = 0; ; loop++) { + int loop = 0; + for (;;) { uint32_t v = w->load(std::memory_order_acquire); int i; for (i = 0; i != n && v != trans[i].from; i++) { } if (i == n) { - SpinLockDelay(w, v, loop, scheduling_mode); // no matching transition - } else if (trans[i].to == v || // null transition + SpinLockDelay(w, v, ++loop, scheduling_mode); // no matching transition + } else if (trans[i].to == v || // null transition w->compare_exchange_strong(v, trans[i].to, std::memory_order_acquire, std::memory_order_relaxed)) {
diff --git a/absl/base/internal/throw_delegate.cc b/absl/base/internal/throw_delegate.cc index 46dc573..1c40efc 100644 --- a/absl/base/internal/throw_delegate.cc +++ b/absl/base/internal/throw_delegate.cc
@@ -30,8 +30,8 @@ #ifdef ABSL_HAVE_EXCEPTIONS throw error; #else - ABSL_RAW_LOG(ERROR, "%s", error.what()); - abort(); + ABSL_RAW_LOG(FATAL, "%s", error.what()); + std::abort(); #endif } } // namespace
diff --git a/absl/base/macros.h b/absl/base/macros.h index ca3d5ed..9e7ab37 100644 --- a/absl/base/macros.h +++ b/absl/base/macros.h
@@ -199,4 +199,14 @@ : [] { assert(false && #expr); }()) // NOLINT #endif +#ifdef ABSL_HAVE_EXCEPTIONS +#define ABSL_INTERNAL_TRY try +#define ABSL_INTERNAL_CATCH_ANY catch (...) +#define ABSL_INTERNAL_RETHROW do { throw; } while (false) +#else // ABSL_HAVE_EXCEPTIONS +#define ABSL_INTERNAL_TRY if (true) +#define ABSL_INTERNAL_CATCH_ANY else if (false) +#define ABSL_INTERNAL_RETHROW do {} while (false) +#endif // ABSL_HAVE_EXCEPTIONS + #endif // ABSL_BASE_MACROS_H_
diff --git a/absl/base/spinlock_test_common.cc b/absl/base/spinlock_test_common.cc index 1b50884..1917081 100644 --- a/absl/base/spinlock_test_common.cc +++ b/absl/base/spinlock_test_common.cc
@@ -155,7 +155,8 @@ // Test corner cases int64_t start_time = time_distribution(generator); - EXPECT_EQ(0, SpinLockTest::EncodeWaitCycles(start_time, start_time)); + EXPECT_EQ(kSpinLockSleeper, + SpinLockTest::EncodeWaitCycles(start_time, start_time)); EXPECT_EQ(0, SpinLockTest::DecodeWaitCycles(0)); EXPECT_EQ(0, SpinLockTest::DecodeWaitCycles(kLockwordReservedMask)); EXPECT_EQ(kMaxCycles & ~kProfileTimestampMask,
diff --git a/absl/base/thread_annotations.h b/absl/base/thread_annotations.h index fbb2797..2241ace 100644 --- a/absl/base/thread_annotations.h +++ b/absl/base/thread_annotations.h
@@ -108,13 +108,23 @@ // The mutex is expected to be held both on entry to, and exit from, the // function. // +// An exclusive lock allows read-write access to the guarded data member(s), and +// only one thread can acquire a lock exclusively at any one time. A shared lock +// allows read-only access, and any number of threads can acquire a shared lock +// concurrently. +// +// Generally, non-const methods should be annotated with +// EXCLUSIVE_LOCKS_REQUIRED, while const methods should be annotated with +// SHARED_LOCKS_REQUIRED. +// // Example: // // Mutex mu1, mu2; // int a GUARDED_BY(mu1); // int b GUARDED_BY(mu2); // -// void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... }; +// void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... } +// void bar() const SHARED_LOCKS_REQUIRED(mu1, mu2) { ... } #define EXCLUSIVE_LOCKS_REQUIRED(...) \ THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index f2210e3..d078992 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel
@@ -15,7 +15,7 @@ # load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", "ABSL_EXCEPTIONS_FLAG", @@ -212,6 +212,7 @@ ":container_memory", ":hash_function_defaults", ":raw_hash_map", + "//absl/algorithm:container", "//absl/memory", ], ) @@ -240,6 +241,7 @@ ":container_memory", ":hash_function_defaults", ":raw_hash_set", + "//absl/algorithm:container", "//absl/base:core_headers", "//absl/memory", ], @@ -271,6 +273,7 @@ ":hash_function_defaults", ":node_hash_policy", ":raw_hash_map", + "//absl/algorithm:container", "//absl/memory", ], ) @@ -296,10 +299,10 @@ hdrs = ["node_hash_set.h"], copts = ABSL_DEFAULT_COPTS, deps = [ - ":container_memory", ":hash_function_defaults", ":node_hash_policy", ":raw_hash_set", + "//absl/algorithm:container", "//absl/memory", ], )
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 9e40690..8605fac 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt
@@ -14,163 +14,674 @@ # limitations under the License. # - -list(APPEND CONTAINER_PUBLIC_HEADERS - "fixed_array.h" - "flat_hash_map.h" - "flat_hash_set.h" - "inlined_vector.h" - "node_hash_map.h" - "node_hash_set.h" -) - - -list(APPEND CONTAINER_INTERNAL_HEADERS - "internal/compressed_tuple.h" - "internal/container_memory.h" - "internal/hash_function_defaults.h" - "internal/hash_generator_testing.h" - "internal/hash_policy_testing.h" - "internal/hash_policy_traits.h" - "internal/hashtable_debug.h" - "internal/layout.h" - "internal/node_hash_policy.h" - "internal/raw_hash_map.h" - "internal/raw_hash_set.h" - "internal/test_instance_tracker.h" - "internal/tracked.h" - "internal/unordered_map_constructor_test.h" - "internal/unordered_map_lookup_test.h" - "internal/unordered_map_modifiers_test.h" - "internal/unordered_set_constructor_test.h" - "internal/unordered_set_lookup_test.h" - "internal/unordered_set_modifiers_test.h" -) - - -absl_library( - TARGET - absl_container - SOURCES - "internal/raw_hash_set.cc" - EXPORT_NAME +# This is deprecated and will be removed in the future. It also doesn't do +# anything anyways. Prefer to use the library associated with the API you are +# using. +absl_cc_library( + NAME container + SRCS + "internal/raw_hash_set.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + PUBLIC ) - -# -## TESTS -# - -list(APPEND TEST_INSTANCE_TRACKER_LIB_SRC - "internal/test_instance_tracker.cc" - ${CONTAINER_PUBLIC_HEADERS} - ${CONTAINER_INTERNAL_HEADERS} +absl_cc_library( + NAME + compressed_tuple + HDRS + "internal/compressed_tuple.h" + DEPS + absl::utility + PUBLIC ) - -absl_library( - TARGET - test_instance_tracker_lib - SOURCES - ${TEST_INSTANCE_TRACKER_LIB_SRC} - PUBLIC_LIBRARIES - absl::container +absl_cc_test( + NAME + compressed_tuple_test + SRCS + "internal/compressed_tuple_test.cc" + DEPS + absl::compressed_tuple + gmock_main ) +absl_cc_library( + NAME + fixed_array + HDRS + "fixed_array.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::compressed_tuple + absl::algorithm + absl::core_headers + absl::dynamic_annotations + absl::throw_delegate + absl::memory + PUBLIC +) - -# test fixed_array_test -set(FIXED_ARRAY_TEST_SRC "fixed_array_test.cc") -set(FIXED_ARRAY_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate test_instance_tracker_lib) - -absl_test( - TARGET +absl_cc_test( + NAME fixed_array_test - SOURCES - ${FIXED_ARRAY_TEST_SRC} - PUBLIC_LIBRARIES - ${FIXED_ARRAY_TEST_PUBLIC_LIBRARIES} - PRIVATE_COMPILE_FLAGS + SRCS + "fixed_array_test.cc" + COPTS ${ABSL_EXCEPTIONS_FLAG} + LINKOPTS + ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} + DEPS + absl::fixed_array + absl::exception_testing + absl::hash_testing + absl::memory + gmock_main ) - - -absl_test( - TARGET +absl_cc_test( + NAME fixed_array_test_noexceptions - SOURCES - ${FIXED_ARRAY_TEST_SRC} - PUBLIC_LIBRARIES - ${FIXED_ARRAY_TEST_PUBLIC_LIBRARIES} + SRCS + "fixed_array_test.cc" + DEPS + absl::fixed_array + absl::exception_testing + absl::hash_testing + absl::memory + gmock_main ) - -# test fixed_array_exception_safety_test -set(FIXED_ARRAY_EXCEPTION_SAFETY_TEST_SRC "fixed_array_exception_safety_test.cc") -set(FIXED_ARRAY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES - absl::container - absl_base_internal_exception_safety_testing -) - -absl_test( - TARGET +absl_cc_test( + NAME fixed_array_exception_safety_test - SOURCES - ${FIXED_ARRAY_EXCEPTION_SAFETY_TEST_SRC} - PUBLIC_LIBRARIES - ${FIXED_ARRAY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES} - PRIVATE_COMPILE_FLAGS + SRCS + "fixed_array_exception_safety_test.cc" + COPTS ${ABSL_EXCEPTIONS_FLAG} + LINKOPTS + ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} + DEPS + absl::fixed_array + absl::exception_safety_testing + gmock_main ) +absl_cc_library( + NAME + inlined_vector + HDRS + "inlined_vector.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::algorithm + absl::core_headers + absl::throw_delegate + absl::memory + PUBLIC +) -# test inlined_vector_test -set(INLINED_VECTOR_TEST_SRC "inlined_vector_test.cc") -set(INLINED_VECTOR_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate test_instance_tracker_lib) - -absl_test( - TARGET +absl_cc_test( + NAME inlined_vector_test - SOURCES - ${INLINED_VECTOR_TEST_SRC} - PUBLIC_LIBRARIES - ${INLINED_VECTOR_TEST_PUBLIC_LIBRARIES} + SRCS + "inlined_vector_test.cc" + COPTS + ${ABSL_EXCEPTIONS_FLAG} + LINKOPTS + ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} + DEPS + absl::inlined_vector + absl::test_instance_tracker + absl::base + absl::core_headers + absl::exception_testing + absl::hash_testing + absl::memory + absl::strings + gmock_main ) -absl_test( - TARGET +absl_cc_test( + NAME inlined_vector_test_noexceptions - SOURCES - ${INLINED_VECTOR_TEST_SRC} - PUBLIC_LIBRARIES - ${INLINED_VECTOR_TEST_PUBLIC_LIBRARIES} - PRIVATE_COMPILE_FLAGS - ${ABSL_NOEXCEPTION_CXXFLAGS} + SRCS + "inlined_vector_test.cc" + DEPS + absl::inlined_vector + absl::test_instance_tracker + absl::base + absl::core_headers + absl::exception_testing + absl::hash_testing + absl::memory + absl::strings + gmock_main ) +absl_cc_library( + NAME + test_instance_tracker + HDRS + "internal/test_instance_tracker.h" + SRCS + "internal/test_instance_tracker.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + TESTONLY +) -# test test_instance_tracker_test -set(TEST_INSTANCE_TRACKER_TEST_SRC "internal/test_instance_tracker_test.cc") -set(TEST_INSTANCE_TRACKER_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate test_instance_tracker_lib) - - -absl_test( - TARGET +absl_cc_test( + NAME test_instance_tracker_test - SOURCES - ${TEST_INSTANCE_TRACKER_TEST_SRC} - PUBLIC_LIBRARIES - ${TEST_INSTANCE_TRACKER_TEST_PUBLIC_LIBRARIES} + SRCS + "internal/test_instance_tracker_test.cc" + DEPS + absl::test_instance_tracker + gmock_main ) +absl_cc_library( + NAME + flat_hash_map + HDRS + "flat_hash_map.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::container_memory + absl::hash_function_defaults + absl::raw_hash_map + absl::algorithm_container + absl::memory + PUBLIC +) -absl_test( - TARGET +absl_cc_test( + NAME + flat_hash_map_test + SRCS + "flat_hash_map_test.cc" + COPTS + "-DUNORDERED_MAP_CXX17" + DEPS + absl::flat_hash_map + absl::hash_generator_testing + absl::unordered_map_constructor_test + absl::unordered_map_lookup_test + absl::unordered_map_modifiers_test + absl::any + gmock_main +) + +absl_cc_library( + NAME + flat_hash_set + HDRS + "flat_hash_set.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::container_memory + absl::hash_function_defaults + absl::raw_hash_set + absl::algorithm_container + absl::core_headers + absl::memory + PUBLIC +) + +absl_cc_test( + NAME + flat_hash_set_test + SRCS + "flat_hash_set_test.cc" + COPTS + "-DUNORDERED_SET_CXX17" + DEPS + absl::flat_hash_set + absl::hash_generator_testing + absl::unordered_set_constructor_test + absl::unordered_set_lookup_test + absl::unordered_set_modifiers_test + absl::memory + absl::strings + gmock_main +) + +absl_cc_library( + NAME + node_hash_map + HDRS + "node_hash_map.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::container_memory + absl::hash_function_defaults + absl::node_hash_policy + absl::raw_hash_map + absl::algorithm_container + absl::memory + PUBLIC +) + +absl_cc_test( + NAME + node_hash_map_test + SRCS + "node_hash_map_test.cc" + COPTS + "-DUNORDERED_MAP_CXX17" + DEPS + absl::hash_generator_testing + absl::node_hash_map + absl::tracked + absl::unordered_map_constructor_test + absl::unordered_map_lookup_test + absl::unordered_map_modifiers_test + gmock_main +) + +absl_cc_library( + NAME + node_hash_set + HDRS + "node_hash_set.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::hash_function_defaults + absl::node_hash_policy + absl::raw_hash_set + absl::algorithm_container + absl::memory + PUBLIC +) + +absl_cc_test( + NAME + node_hash_set_test + SRCS + "node_hash_set_test.cc" + COPTS + "-DUNORDERED_SET_CXX17" + DEPS + absl::hash_generator_testing + absl::node_hash_set + absl::unordered_set_constructor_test + absl::unordered_set_lookup_test + absl::unordered_set_modifiers_test + gmock_main +) + +absl_cc_library( + NAME + container_memory + HDRS + "internal/container_memory.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::memory + absl::utility + PUBLIC +) + +absl_cc_test( + NAME + container_memory_test + SRCS + "internal/container_memory_test.cc" + DEPS + absl::container_memory + absl::strings + gmock_main +) + +absl_cc_library( + NAME + hash_function_defaults + HDRS + "internal/hash_function_defaults.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::config + absl::hash + absl::strings + PUBLIC +) + +absl_cc_test( + NAME + hash_function_defaults_test + SRCS + "internal/hash_function_defaults_test.cc" + DEPS + absl::hash_function_defaults + absl::hash + absl::strings + gmock_main +) + +absl_cc_library( + NAME + hash_generator_testing + HDRS + "internal/hash_generator_testing.h" + SRCS + "internal/hash_generator_testing.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::hash_policy_testing + absl::meta + absl::strings + TESTONLY +) + +absl_cc_library( + NAME + hash_policy_testing + HDRS + "internal/hash_policy_testing.h" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::hash + absl::strings + TESTONLY +) + +absl_cc_test( + NAME + hash_policy_testing_test + SRCS + "internal/hash_policy_testing_test.cc" + DEPS + absl::hash_policy_testing + gmock_main +) + +absl_cc_library( + NAME + hash_policy_traits + HDRS + "internal/hash_policy_traits.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::meta + PUBLIC +) + +absl_cc_test( + NAME + hash_policy_traits_test + SRCS + "internal/hash_policy_traits_test.cc" + DEPS + absl::hash_policy_traits + gmock_main +) + +absl_cc_library( + NAME + hashtable_debug + HDRS + "internal/hashtable_debug.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::hashtable_debug_hooks +) + +absl_cc_library( + NAME + hashtable_debug_hooks + HDRS + "internal/hashtable_debug_hooks.h" + COPTS + ${ABSL_DEFAULT_COPTS} + PUBLIC +) + +absl_cc_library( + NAME + node_hash_policy + HDRS + "internal/node_hash_policy.h" + COPTS + ${ABSL_DEFAULT_COPTS} + PUBLIC +) + +absl_cc_test( + NAME + node_hash_policy_test + SRCS + "internal/node_hash_policy_test.cc" + DEPS + absl::hash_policy_traits + absl::node_hash_policy + gmock_main +) + +absl_cc_library( + NAME + raw_hash_map + HDRS + "internal/raw_hash_map.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::container_memory + absl::raw_hash_set + PUBLIC +) + +absl_cc_library( + NAME + raw_hash_set + HDRS + "internal/raw_hash_set.h" + SRCS + "internal/raw_hash_set.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::compressed_tuple + absl::container_memory + absl::hash_policy_traits + absl::hashtable_debug_hooks + absl::layout + absl::bits + absl::config + absl::core_headers + absl::endian + absl::memory + absl::meta + absl::optional + absl::utility + PUBLIC +) + +absl_cc_test( + NAME raw_hash_set_test - SOURCES + SRCS "internal/raw_hash_set_test.cc" - PUBLIC_LIBRARIES - absl::base absl::hash absl_throw_delegate test_instance_tracker_lib + DEPS + absl::container_memory + absl::hash_function_defaults + absl::hash_policy_testing + absl::hashtable_debug + absl::raw_hash_set + absl::base + absl::core_headers + absl::strings + gmock_main +) + +absl_cc_test( + NAME + raw_hash_set_allocator_test + SRCS + "internal/raw_hash_set_allocator_test.cc" + DEPS + absl::raw_hash_set + absl::tracked + absl::core_headers + gmock_main +) + +absl_cc_library( + NAME + layout + HDRS + "internal/layout.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::core_headers + absl::meta + absl::strings + absl::span + absl::utility + PUBLIC +) + +absl_cc_test( + NAME + layout_test + SRCS + "internal/layout_test.cc" + DEPS + absl::layout + absl::base + absl::core_headers + absl::span + gmock_main +) + +absl_cc_library( + NAME + tracked + HDRS + "internal/tracked.h" + COPTS + ${ABSL_TEST_COPTS} + TESTONLY +) + +absl_cc_library( + NAME + unordered_map_constructor_test + HDRS + "internal/unordered_map_constructor_test.h" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::hash_generator_testing + absl::hash_policy_testing + gmock + TESTONLY +) + +absl_cc_library( + NAME + unordered_map_lookup_test + HDRS + "internal/unordered_map_lookup_test.h" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::hash_generator_testing + absl::hash_policy_testing + gmock + TESTONLY +) + +absl_cc_library( + NAME + unordered_map_modifiers_test + HDRS + "internal/unordered_map_modifiers_test.h" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::hash_generator_testing + absl::hash_policy_testing + gmock + TESTONLY +) + +absl_cc_library( + NAME + unordered_set_constructor_test + HDRS + "internal/unordered_set_constructor_test.h" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::hash_generator_testing + absl::hash_policy_testing + gmock + TESTONLY +) + +absl_cc_library( + NAME + unordered_set_lookup_test + HDRS + "internal/unordered_set_lookup_test.h" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::hash_generator_testing + absl::hash_policy_testing + gmock + TESTONLY +) + +absl_cc_library( + NAME + unordered_set_modifiers_test + HDRS + "internal/unordered_set_modifiers_test.h" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::hash_generator_testing + absl::hash_policy_testing + gmock + TESTONLY +) + +absl_cc_test( + NAME + unordered_set_test + SRCS + "internal/unordered_set_test.cc" + DEPS + absl::unordered_set_constructor_test + absl::unordered_set_lookup_test + absl::unordered_set_modifiers_test + gmock_main +) + +absl_cc_test( + NAME + unordered_map_test + SRCS + "internal/unordered_map_test.cc" + DEPS + absl::unordered_map_constructor_test + absl::unordered_map_lookup_test + absl::unordered_map_modifiers_test + gmock_main )
diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h index fe67dce..6da8441 100644 --- a/absl/container/fixed_array.h +++ b/absl/container/fixed_array.h
@@ -188,7 +188,7 @@ // `FixedArray<T>`. This is equivalent to the most possible addressable bytes // over the number of bytes taken by T. constexpr size_type max_size() const { - return std::numeric_limits<difference_type>::max() / sizeof(value_type); + return (std::numeric_limits<difference_type>::max)() / sizeof(value_type); } // FixedArray::empty()
diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h index e5570d1..cc3d8b6 100644 --- a/absl/container/flat_hash_map.h +++ b/absl/container/flat_hash_map.h
@@ -35,6 +35,7 @@ #include <type_traits> #include <utility> +#include "absl/algorithm/container.h" #include "absl/container/internal/container_memory.h" #include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/raw_hash_map.h" // IWYU pragma: export @@ -69,7 +70,7 @@ // By default, `flat_hash_map` uses the `absl::Hash` hashing framework. // All fundamental and Abseil types that support the `absl::Hash` framework have // a compatible equality operator for comparing insertions into `flat_hash_map`. -// If your type is not yet supported by the `asbl::Hash` framework, see +// If your type is not yet supported by the `absl::Hash` framework, see // absl/hash/hash.h for information on extending Abseil hashing to user-defined // types. // @@ -109,6 +110,46 @@ using Base = typename flat_hash_map::raw_hash_map; public: + // Constructors and Assignment Operators + // + // A flat_hash_map supports the same overload set as `std::unordered_map` + // for construction and assignment: + // + // * Default constructor + // + // // No allocation for the table's elements is made. + // absl::flat_hash_map<int, std::string> map1; + // + // * Initializer List constructor + // + // absl::flat_hash_map<int, std::string> map2 = + // {{1, "huey"}, {2, "dewey"}, {3, "louie"},}; + // + // * Copy constructor + // + // absl::flat_hash_map<int, std::string> map3(map2); + // + // * Copy assignment operator + // + // // Hash functor and Comparator are copied as well + // absl::flat_hash_map<int, std::string> map4; + // map4 = map3; + // + // * Move constructor + // + // // Move is guaranteed efficient + // absl::flat_hash_map<int, std::string> map5(std::move(map4)); + // + // * Move assignment operator + // + // // May be efficient if allocators are compatible + // absl::flat_hash_map<int, std::string> map6; + // map6 = std::move(map5); + // + // * Range constructor + // + // std::vector<std::pair<int, std::string>> v = {{1, "a"}, {2, "b"}}; + // absl::flat_hash_map<int, std::string> map7(v.begin(), v.end()); flat_hash_map() {} using Base::Base; @@ -524,5 +565,16 @@ }; } // namespace container_internal + +namespace container_algorithm_internal { + +// Specialization of trait in absl/algorithm/container.h +template <class Key, class T, class Hash, class KeyEqual, class Allocator> +struct IsUnorderedContainer< + absl::flat_hash_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type {}; + +} // namespace container_algorithm_internal + } // namespace absl + #endif // ABSL_CONTAINER_FLAT_HASH_MAP_H_
diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc index 10a781f..2c6f251 100644 --- a/absl/container/flat_hash_map_test.cc +++ b/absl/container/flat_hash_map_test.cc
@@ -94,7 +94,7 @@ } } -// Demonstration of the "Lazy Key" pattern. This uses heterogenous insert to +// Demonstration of the "Lazy Key" pattern. This uses heterogeneous insert to // avoid creating expensive key elements when the item is already present in the // map. struct LazyInt {
diff --git a/absl/container/flat_hash_set.h b/absl/container/flat_hash_set.h index 98aead1..84984cc 100644 --- a/absl/container/flat_hash_set.h +++ b/absl/container/flat_hash_set.h
@@ -32,6 +32,7 @@ #include <type_traits> #include <utility> +#include "absl/algorithm/container.h" #include "absl/base/macros.h" #include "absl/container/internal/container_memory.h" #include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export @@ -66,7 +67,7 @@ // By default, `flat_hash_set` uses the `absl::Hash` hashing framework. All // fundamental and Abseil types that support the `absl::Hash` framework have a // compatible equality operator for comparing insertions into `flat_hash_map`. -// If your type is not yet supported by the `asbl::Hash` framework, see +// If your type is not yet supported by the `absl::Hash` framework, see // absl/hash/hash.h for information on extending Abseil hashing to user-defined // types. // @@ -84,7 +85,7 @@ // {"huey", "dewey", "louie"}; // // // Insert a new element into the flat hash set -// ducks.insert("donald"}; +// ducks.insert("donald"); // // // Force a rehash of the flat hash set // ducks.rehash(0); @@ -102,6 +103,46 @@ using Base = typename flat_hash_set::raw_hash_set; public: + // Constructors and Assignment Operators + // + // A flat_hash_set supports the same overload set as `std::unordered_map` + // for construction and assignment: + // + // * Default constructor + // + // // No allocation for the table's elements is made. + // absl::flat_hash_set<std::string> set1; + // + // * Initializer List constructor + // + // absl::flat_hash_set<std::string> set2 = + // {{"huey"}, {"dewey"}, {"louie"},}; + // + // * Copy constructor + // + // absl::flat_hash_set<std::string> set3(set2); + // + // * Copy assignment operator + // + // // Hash functor and Comparator are copied as well + // absl::flat_hash_set<std::string> set4; + // set4 = set3; + // + // * Move constructor + // + // // Move is guaranteed efficient + // absl::flat_hash_set<std::string> set5(std::move(set4)); + // + // * Move assignment operator + // + // // May be efficient if allocators are compatible + // absl::flat_hash_set<std::string> set6; + // set6 = std::move(set5); + // + // * Range constructor + // + // std::vector<std::string> v = {"a", "b"}; + // absl::flat_hash_set<std::string> set7(v.begin(), v.end()); flat_hash_set() {} using Base::Base; @@ -238,8 +279,7 @@ // // The element may be constructed even if there already is an element with the // key in the container, in which case the newly constructed element will be - // destroyed immediately. Prefer `try_emplace()` unless your key is not - // copyable or moveable. + // destroyed immediately. // // If rehashing occurs due to the insertion, all iterators are invalidated. using Base::emplace; @@ -253,8 +293,7 @@ // // The element may be constructed even if there already is an element with the // key in the container, in which case the newly constructed element will be - // destroyed immediately. Prefer `try_emplace()` unless your key is not - // copyable or moveable. + // destroyed immediately. // // If rehashing occurs due to the insertion, all iterators are invalidated. using Base::emplace_hint; @@ -435,5 +474,16 @@ static size_t space_used(const T*) { return 0; } }; } // namespace container_internal + +namespace container_algorithm_internal { + +// Specialization of trait in absl/algorithm/container.h +template <class Key, class Hash, class KeyEqual, class Allocator> +struct IsUnorderedContainer<absl::flat_hash_set<Key, Hash, KeyEqual, Allocator>> + : std::true_type {}; + +} // namespace container_algorithm_internal + } // namespace absl + #endif // ABSL_CONTAINER_FLAT_HASH_SET_H_
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index 12756bb..0f10036 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h
@@ -1,4 +1,4 @@ -// Copyright 2017 The Abseil Authors. +// 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. @@ -20,17 +20,17 @@ // vector" which behaves in an equivalent fashion to a `std::vector`, except // that storage for small sequences of the vector are provided inline without // requiring any heap allocation. - -// An `absl::InlinedVector<T,N>` specifies the size N at which to inline as one -// of its template parameters. Vectors of length <= N are provided inline. -// Typically N is very small (e.g., 4) so that sequences that are expected to be -// short do not require allocations. - -// An `absl::InlinedVector` does not usually require a specific allocator; if +// +// An `absl::InlinedVector<T, N>` specifies the default capacity `N` as one of +// its template parameters. Instances where `size() <= N` hold contained +// elements in inline space. Typically `N` is very small so that sequences that +// are expected to be short do not require allocations. +// +// An `absl::InlinedVector` does not usually require a specific allocator. If // the inlined vector grows beyond its initial constraints, it will need to -// allocate (as any normal `std::vector` would) and it will generally use the -// default allocator in that case; optionally, a custom allocator may be -// specified using an `absl::InlinedVector<T,N,A>` construction. +// allocate (as any normal `std::vector` would). This is usually performed with +// the default allocator (defined as `std::allocator<T>`). Optionally, a custom +// allocator type may be specified as `A` in `absl::InlinedVector<T, N, A>`. #ifndef ABSL_CONTAINER_INLINED_VECTOR_H_ #define ABSL_CONTAINER_INLINED_VECTOR_H_ @@ -61,12 +61,30 @@ // An `absl::InlinedVector` is designed to be a drop-in replacement for // `std::vector` for use cases where the vector's size is sufficiently small // that it can be inlined. If the inlined vector does grow beyond its estimated -// size, it will trigger an initial allocation on the heap, and will behave as a -// `std:vector`. The API of the `absl::InlinedVector` within this file is +// capacity, it will trigger an initial allocation on the heap, and will behave +// as a `std:vector`. The API of the `absl::InlinedVector` within this file is // designed to cover the same API footprint as covered by `std::vector`. -template <typename T, size_t N, typename A = std::allocator<T> > +template <typename T, size_t N, typename A = std::allocator<T>> class InlinedVector { - using AllocatorTraits = std::allocator_traits<A>; + static_assert(N > 0, "InlinedVector requires inline capacity greater than 0"); + constexpr static typename A::size_type inlined_capacity() { + return static_cast<typename A::size_type>(N); + } + + template <typename Iterator> + using DisableIfIntegral = + absl::enable_if_t<!std::is_integral<Iterator>::value>; + + template <typename Iterator> + using EnableIfInputIterator = absl::enable_if_t<std::is_convertible< + typename std::iterator_traits<Iterator>::iterator_category, + std::input_iterator_tag>::value>; + + template <typename Iterator> + using IteratorCategory = + typename std::iterator_traits<Iterator>::iterator_category; + + using rvalue_reference = typename A::value_type&&; public: using allocator_type = A; @@ -82,294 +100,539 @@ using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; + // --------------------------------------------------------------------------- + // InlinedVector Constructors and Destructor + // --------------------------------------------------------------------------- + + // Creates an empty inlined vector with a default initialized allocator. InlinedVector() noexcept(noexcept(allocator_type())) : allocator_and_tag_(allocator_type()) {} + // Creates an empty inlined vector with a specified allocator. explicit InlinedVector(const allocator_type& alloc) noexcept : allocator_and_tag_(alloc) {} - // Create a vector with n copies of value_type(). + // Creates an inlined vector with `n` copies of `value_type()`. explicit InlinedVector(size_type n, const allocator_type& alloc = allocator_type()) : allocator_and_tag_(alloc) { InitAssign(n); } - // Create a vector with n copies of elem - InlinedVector(size_type n, const value_type& elem, + // Creates an inlined vector with `n` copies of `v`. + InlinedVector(size_type n, const_reference v, const allocator_type& alloc = allocator_type()) : allocator_and_tag_(alloc) { - InitAssign(n, elem); + InitAssign(n, v); } - // Create and initialize with the elements [first .. last). - // The unused enable_if argument restricts this constructor so that it is - // elided when value_type is an integral type. This prevents ambiguous - // interpretation between a call to this constructor with two integral - // arguments and a call to the preceding (n, elem) constructor. - template <typename InputIterator> - InlinedVector( - InputIterator first, InputIterator last, - const allocator_type& alloc = allocator_type(), - typename std::enable_if<!std::is_integral<InputIterator>::value>::type* = - nullptr) - : allocator_and_tag_(alloc) { - AppendRange(first, last); - } - - InlinedVector(std::initializer_list<value_type> init, + // Creates an inlined vector of copies of the values in `init_list`. + InlinedVector(std::initializer_list<value_type> init_list, const allocator_type& alloc = allocator_type()) : allocator_and_tag_(alloc) { - AppendRange(init.begin(), init.end()); + AppendRange(init_list.begin(), init_list.end(), + IteratorCategory<decltype(init_list.begin())>{}); } - InlinedVector(const InlinedVector& v); - InlinedVector(const InlinedVector& v, const allocator_type& alloc); + // Creates an inlined vector with elements constructed from the provided + // Iterator range [`first`, `last`). + // + // NOTE: The `enable_if` prevents ambiguous interpretation between a call to + // this constructor with two integral arguments and a call to the above + // `InlinedVector(size_type, const_reference)` constructor. + template <typename InputIterator, DisableIfIntegral<InputIterator>* = nullptr> + InlinedVector(InputIterator first, InputIterator last, + const allocator_type& alloc = allocator_type()) + : allocator_and_tag_(alloc) { + AppendRange(first, last, IteratorCategory<InputIterator>{}); + } - // This move constructor does not allocate and only moves the underlying + // Creates a copy of `other` using `other`'s allocator. + InlinedVector(const InlinedVector& other) + : InlinedVector(other, other.allocator()) {} + + // Creates a copy of `other` but with a specified allocator. + InlinedVector(const InlinedVector& other, const allocator_type& alloc) + : allocator_and_tag_(alloc) { + reserve(other.size()); + if (allocated()) { + UninitializedCopy(other.begin(), other.end(), allocated_space()); + tag().set_allocated_size(other.size()); + } else { + UninitializedCopy(other.begin(), other.end(), inlined_space()); + tag().set_inline_size(other.size()); + } + } + + // Creates an inlined vector by moving in the contents of `other`. + // + // NOTE: This move constructor does not allocate and only moves the underlying // objects, so its `noexcept` specification depends on whether moving the - // underlying objects can throw or not. We assume + // underlying objects can throw or not. We assume: // a) move constructors should only throw due to allocation failure and // b) if `value_type`'s move constructor allocates, it uses the same // allocation function as the `InlinedVector`'s allocator, so the move // constructor is non-throwing if the allocator is non-throwing or // `value_type`'s move constructor is specified as `noexcept`. - InlinedVector(InlinedVector&& v) noexcept( + InlinedVector(InlinedVector&& other) noexcept( absl::allocator_is_nothrow<allocator_type>::value || - std::is_nothrow_move_constructible<value_type>::value); + std::is_nothrow_move_constructible<value_type>::value) + : allocator_and_tag_(other.allocator_and_tag_) { + if (other.allocated()) { + // We can just steal the underlying buffer from the source. + // That leaves the source empty, so we clear its size. + init_allocation(other.allocation()); + other.tag() = Tag(); + } else { + UninitializedCopy( + std::make_move_iterator(other.inlined_space()), + std::make_move_iterator(other.inlined_space() + other.size()), + inlined_space()); + } + } - // This move constructor allocates and also moves the underlying objects, so - // its `noexcept` specification depends on whether the allocation can throw - // and whether moving the underlying objects can throw. Based on the same - // assumptions above, the `noexcept` specification is dominated by whether the - // allocation can throw regardless of whether `value_type`'s move constructor - // is specified as `noexcept`. - InlinedVector(InlinedVector&& v, const allocator_type& alloc) noexcept( - absl::allocator_is_nothrow<allocator_type>::value); + // Creates an inlined vector by moving in the contents of `other`. + // + // NOTE: This move constructor allocates and subsequently moves the underlying + // objects, so its `noexcept` specification depends on whether the allocation + // can throw and whether moving the underlying objects can throw. Based on the + // same assumptions as above, the `noexcept` specification is dominated by + // whether the allocation can throw regardless of whether `value_type`'s move + // constructor is specified as `noexcept`. + InlinedVector(InlinedVector&& other, const allocator_type& alloc) noexcept( + absl::allocator_is_nothrow<allocator_type>::value) + : allocator_and_tag_(alloc) { + if (other.allocated()) { + if (alloc == other.allocator()) { + // We can just steal the allocation from the source. + tag() = other.tag(); + init_allocation(other.allocation()); + other.tag() = Tag(); + } else { + // We need to use our own allocator + reserve(other.size()); + UninitializedCopy(std::make_move_iterator(other.begin()), + std::make_move_iterator(other.end()), + allocated_space()); + tag().set_allocated_size(other.size()); + } + } else { + UninitializedCopy( + std::make_move_iterator(other.inlined_space()), + std::make_move_iterator(other.inlined_space() + other.size()), + inlined_space()); + tag().set_inline_size(other.size()); + } + } ~InlinedVector() { clear(); } - InlinedVector& operator=(const InlinedVector& v) { - if (this == &v) { - return *this; + // --------------------------------------------------------------------------- + // InlinedVector Member Accessors + // --------------------------------------------------------------------------- + + // `InlinedVector::empty()` + // + // Checks if the inlined vector has no elements. + bool empty() const noexcept { return !size(); } + + // `InlinedVector::size()` + // + // Returns the number of elements in the inlined vector. + size_type size() const noexcept { return tag().size(); } + + // `InlinedVector::max_size()` + // + // Returns the maximum number of elements the vector can hold. + size_type max_size() const noexcept { + // One bit of the size storage is used to indicate whether the inlined + // vector is allocated. As a result, the maximum size of the container that + // we can express is half of the max for `size_type`. + return (std::numeric_limits<size_type>::max)() / 2; + } + + // `InlinedVector::capacity()` + // + // Returns the number of elements that can be stored in the inlined vector + // without requiring a reallocation of underlying memory. + // + // NOTE: For most inlined vectors, `capacity()` should equal + // `inlined_capacity()`. For inlined vectors which exceed this capacity, they + // will no longer be inlined and `capacity()` will equal its capacity on the + // allocated heap. + size_type capacity() const noexcept { + return allocated() ? allocation().capacity() : inlined_capacity(); + } + + // `InlinedVector::data()` + // + // Returns a `pointer` to elements of the inlined vector. This pointer can be + // used to access and modify the contained elements. + // Only results within the range [`0`, `size()`) are defined. + pointer data() noexcept { + return allocated() ? allocated_space() : inlined_space(); + } + + // Overload of `InlinedVector::data()` to return a `const_pointer` to elements + // of the inlined vector. This pointer can be used to access (but not modify) + // the contained elements. + const_pointer data() const noexcept { + return allocated() ? allocated_space() : inlined_space(); + } + + // `InlinedVector::operator[]()` + // + // Returns a `reference` to the `i`th element of the inlined vector using the + // array operator. + reference operator[](size_type i) { + assert(i < size()); + return data()[i]; + } + + // Overload of `InlinedVector::operator[]()` to return a `const_reference` to + // the `i`th element of the inlined vector. + const_reference operator[](size_type i) const { + assert(i < size()); + return data()[i]; + } + + // `InlinedVector::at()` + // + // Returns a `reference` to the `i`th element of the inlined vector. + reference at(size_type i) { + if (ABSL_PREDICT_FALSE(i >= size())) { + base_internal::ThrowStdOutOfRange( + "`InlinedVector::at(size_type)` failed bounds check"); } + return data()[i]; + } + + // Overload of `InlinedVector::at()` to return a `const_reference` to the + // `i`th element of the inlined vector. + const_reference at(size_type i) const { + if (ABSL_PREDICT_FALSE(i >= size())) { + base_internal::ThrowStdOutOfRange( + "`InlinedVector::at(size_type) const` failed bounds check"); + } + return data()[i]; + } + + // `InlinedVector::front()` + // + // Returns a `reference` to the first element of the inlined vector. + reference front() { + assert(!empty()); + return at(0); + } + + // Overload of `InlinedVector::front()` returns a `const_reference` to the + // first element of the inlined vector. + const_reference front() const { + assert(!empty()); + return at(0); + } + + // `InlinedVector::back()` + // + // Returns a `reference` to the last element of the inlined vector. + reference back() { + assert(!empty()); + return at(size() - 1); + } + + // Overload of `InlinedVector::back()` to return a `const_reference` to the + // last element of the inlined vector. + const_reference back() const { + assert(!empty()); + return at(size() - 1); + } + + // `InlinedVector::begin()` + // + // Returns an `iterator` to the beginning of the inlined vector. + iterator begin() noexcept { return data(); } + + // Overload of `InlinedVector::begin()` to return a `const_iterator` to + // the beginning of the inlined vector. + const_iterator begin() const noexcept { return data(); } + + // `InlinedVector::end()` + // + // Returns an `iterator` to the end of the inlined vector. + iterator end() noexcept { return data() + size(); } + + // Overload of `InlinedVector::end()` to return a `const_iterator` to the + // end of the inlined vector. + const_iterator end() const noexcept { return data() + size(); } + + // `InlinedVector::cbegin()` + // + // Returns a `const_iterator` to the beginning of the inlined vector. + const_iterator cbegin() const noexcept { return begin(); } + + // `InlinedVector::cend()` + // + // Returns a `const_iterator` to the end of the inlined vector. + const_iterator cend() const noexcept { return end(); } + + // `InlinedVector::rbegin()` + // + // Returns a `reverse_iterator` from the end of the inlined vector. + reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } + + // Overload of `InlinedVector::rbegin()` to return a + // `const_reverse_iterator` from the end of the inlined vector. + const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator(end()); + } + + // `InlinedVector::rend()` + // + // Returns a `reverse_iterator` from the beginning of the inlined vector. + reverse_iterator rend() noexcept { return reverse_iterator(begin()); } + + // Overload of `InlinedVector::rend()` to return a `const_reverse_iterator` + // from the beginning of the inlined vector. + const_reverse_iterator rend() const noexcept { + return const_reverse_iterator(begin()); + } + + // `InlinedVector::crbegin()` + // + // Returns a `const_reverse_iterator` from the end of the inlined vector. + const_reverse_iterator crbegin() const noexcept { return rbegin(); } + + // `InlinedVector::crend()` + // + // Returns a `const_reverse_iterator` from the beginning of the inlined + // vector. + const_reverse_iterator crend() const noexcept { return rend(); } + + // `InlinedVector::get_allocator()` + // + // Returns a copy of the allocator of the inlined vector. + allocator_type get_allocator() const { return allocator(); } + + // --------------------------------------------------------------------------- + // InlinedVector Member Mutators + // --------------------------------------------------------------------------- + + // `InlinedVector::operator=()` + // + // Replaces the contents of the inlined vector with copies of the elements in + // the provided `std::initializer_list`. + InlinedVector& operator=(std::initializer_list<value_type> init_list) { + AssignRange(init_list.begin(), init_list.end(), + IteratorCategory<decltype(init_list.begin())>{}); + return *this; + } + + // Overload of `InlinedVector::operator=()` to replace the contents of the + // inlined vector with the contents of `other`. + InlinedVector& operator=(const InlinedVector& other) { + if (ABSL_PREDICT_FALSE(this == &other)) return *this; + // Optimized to avoid reallocation. // Prefer reassignment to copy construction for elements. - if (size() < v.size()) { // grow - reserve(v.size()); - std::copy(v.begin(), v.begin() + size(), begin()); - std::copy(v.begin() + size(), v.end(), std::back_inserter(*this)); + if (size() < other.size()) { // grow + reserve(other.size()); + std::copy(other.begin(), other.begin() + size(), begin()); + std::copy(other.begin() + size(), other.end(), std::back_inserter(*this)); } else { // maybe shrink - erase(begin() + v.size(), end()); - std::copy(v.begin(), v.end(), begin()); + erase(begin() + other.size(), end()); + std::copy(other.begin(), other.end(), begin()); } return *this; } - InlinedVector& operator=(InlinedVector&& v) { - if (this == &v) { - return *this; - } - if (v.allocated()) { + // Overload of `InlinedVector::operator=()` to replace the contents of the + // inlined vector with the contents of `other`. + // + // NOTE: As a result of calling this overload, `other` may be empty or it's + // contents may be left in a moved-from state. + InlinedVector& operator=(InlinedVector&& other) { + if (ABSL_PREDICT_FALSE(this == &other)) return *this; + + if (other.allocated()) { clear(); - tag().set_allocated_size(v.size()); - init_allocation(v.allocation()); - v.tag() = Tag(); + tag().set_allocated_size(other.size()); + init_allocation(other.allocation()); + other.tag() = Tag(); } else { if (allocated()) clear(); // Both are inlined now. - if (size() < v.size()) { - auto mid = std::make_move_iterator(v.begin() + size()); - std::copy(std::make_move_iterator(v.begin()), mid, begin()); - UninitializedCopy(mid, std::make_move_iterator(v.end()), end()); + if (size() < other.size()) { + auto mid = std::make_move_iterator(other.begin() + size()); + std::copy(std::make_move_iterator(other.begin()), mid, begin()); + UninitializedCopy(mid, std::make_move_iterator(other.end()), end()); } else { - auto new_end = std::copy(std::make_move_iterator(v.begin()), - std::make_move_iterator(v.end()), begin()); + auto new_end = std::copy(std::make_move_iterator(other.begin()), + std::make_move_iterator(other.end()), begin()); Destroy(new_end, end()); } - tag().set_inline_size(v.size()); + tag().set_inline_size(other.size()); } return *this; } - InlinedVector& operator=(std::initializer_list<value_type> init) { - AssignRange(init.begin(), init.end()); - return *this; - } - - // InlinedVector::assign() + // `InlinedVector::assign()` // - // Replaces the contents of the inlined vector with copies of those in the - // iterator range [first, last). - template <typename InputIterator> - void assign( - InputIterator first, InputIterator last, - typename std::enable_if<!std::is_integral<InputIterator>::value>::type* = - nullptr) { - AssignRange(first, last); - } - - // Overload of `InlinedVector::assign()` to take values from elements of an - // initializer list - void assign(std::initializer_list<value_type> init) { - AssignRange(init.begin(), init.end()); - } - - // Overload of `InlinedVector::assign()` to replace the first `n` elements of - // the inlined vector with `elem` values. - void assign(size_type n, const value_type& elem) { + // Replaces the contents of the inlined vector with `n` copies of `v`. + void assign(size_type n, const_reference v) { if (n <= size()) { // Possibly shrink - std::fill_n(begin(), n, elem); + std::fill_n(begin(), n, v); erase(begin() + n, end()); return; } // Grow reserve(n); - std::fill_n(begin(), size(), elem); + std::fill_n(begin(), size(), v); if (allocated()) { - UninitializedFill(allocated_space() + size(), allocated_space() + n, - elem); + UninitializedFill(allocated_space() + size(), allocated_space() + n, v); tag().set_allocated_size(n); } else { - UninitializedFill(inlined_space() + size(), inlined_space() + n, elem); + UninitializedFill(inlined_space() + size(), inlined_space() + n, v); tag().set_inline_size(n); } } - // InlinedVector::size() - // - // Returns the number of elements in the inlined vector. - size_type size() const noexcept { return tag().size(); } - - // InlinedVector::empty() - // - // Checks if the inlined vector has no elements. - bool empty() const noexcept { return (size() == 0); } - - // InlinedVector::capacity() - // - // Returns the number of elements that can be stored in an inlined vector - // without requiring a reallocation of underlying memory. Note that for - // most inlined vectors, `capacity()` should equal its initial size `N`; for - // inlined vectors which exceed this capacity, they will no longer be inlined, - // and `capacity()` will equal its capacity on the allocated heap. - size_type capacity() const noexcept { - return allocated() ? allocation().capacity() : N; + // Overload of `InlinedVector::assign()` to replace the contents of the + // inlined vector with copies of the values in the provided + // `std::initializer_list`. + void assign(std::initializer_list<value_type> init_list) { + AssignRange(init_list.begin(), init_list.end(), + IteratorCategory<decltype(init_list.begin())>{}); } - // InlinedVector::max_size() - // - // Returns the maximum number of elements the vector can hold. - size_type max_size() const noexcept { - // One bit of the size storage is used to indicate whether the inlined - // vector is allocated; as a result, the maximum size of the container that - // we can express is half of the max for our size type. - return std::numeric_limits<size_type>::max() / 2; + // Overload of `InlinedVector::assign()` to replace the contents of the + // inlined vector with values constructed from the range [`first`, `last`). + template <typename InputIterator, DisableIfIntegral<InputIterator>* = nullptr> + void assign(InputIterator first, InputIterator last) { + AssignRange(first, last, IteratorCategory<InputIterator>{}); } - // InlinedVector::data() + // `InlinedVector::resize()` // - // Returns a const T* pointer to elements of the inlined vector. This pointer - // can be used to access (but not modify) the contained elements. - // Only results within the range `[0,size())` are defined. - const_pointer data() const noexcept { - return allocated() ? allocated_space() : inlined_space(); - } - - // Overload of InlinedVector::data() to return a T* pointer to elements of the - // inlined vector. This pointer can be used to access and modify the contained - // elements. - pointer data() noexcept { - return allocated() ? allocated_space() : inlined_space(); - } - - // InlinedVector::clear() - // - // Removes all elements from the inlined vector. - void clear() noexcept { + // Resizes the inlined vector to contain `n` elements. If `n` is smaller than + // the inlined vector's current size, extra elements are destroyed. If `n` is + // larger than the initial size, new elements are value-initialized. + void resize(size_type n) { size_type s = size(); + if (n < s) { + erase(begin() + n, end()); + return; + } + reserve(n); + assert(capacity() >= n); + + // Fill new space with elements constructed in-place. if (allocated()) { - Destroy(allocated_space(), allocated_space() + s); - allocation().Dealloc(allocator()); - } else if (s != 0) { // do nothing for empty vectors - Destroy(inlined_space(), inlined_space() + s); + UninitializedFill(allocated_space() + s, allocated_space() + n); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space() + s, inlined_space() + n); + tag().set_inline_size(n); } - tag() = Tag(); } - // InlinedVector::at() - // - // Returns the ith element of an inlined vector. - const value_type& at(size_type i) const { - if (ABSL_PREDICT_FALSE(i >= size())) { - base_internal::ThrowStdOutOfRange( - "InlinedVector::at failed bounds check"); + // Overload of `InlinedVector::resize()` to resize the inlined vector to + // contain `n` elements where, if `n` is larger than `size()`, the new values + // will be copy-constructed from `v`. + void resize(size_type n, const_reference v) { + size_type s = size(); + if (n < s) { + erase(begin() + n, end()); + return; } - return data()[i]; - } + reserve(n); + assert(capacity() >= n); - // InlinedVector::operator[] - // - // Returns the ith element of an inlined vector using the array operator. - const value_type& operator[](size_type i) const { - assert(i < size()); - return data()[i]; - } - - // Overload of InlinedVector::at() to return the ith element of an inlined - // vector. - value_type& at(size_type i) { - if (i >= size()) { - base_internal::ThrowStdOutOfRange( - "InlinedVector::at failed bounds check"); + // Fill new space with copies of `v`. + if (allocated()) { + UninitializedFill(allocated_space() + s, allocated_space() + n, v); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space() + s, inlined_space() + n, v); + tag().set_inline_size(n); } - return data()[i]; } - // Overload of InlinedVector::operator[] to return the ith element of an - // inlined vector. - value_type& operator[](size_type i) { - assert(i < size()); - return data()[i]; - } - - // InlinedVector::back() + // `InlinedVector::insert()` // - // Returns a reference to the last element of an inlined vector. - value_type& back() { - assert(!empty()); - return at(size() - 1); + // Copies `v` into `position`, returning an `iterator` pointing to the newly + // inserted element. + iterator insert(const_iterator position, const_reference v) { + return emplace(position, v); } - // Overload of InlinedVector::back() returns a reference to the last element - // of an inlined vector of const values. - const value_type& back() const { - assert(!empty()); - return at(size() - 1); + // Overload of `InlinedVector::insert()` for moving `v` into `position`, + // returning an iterator pointing to the newly inserted element. + iterator insert(const_iterator position, rvalue_reference v) { + return emplace(position, std::move(v)); } - // InlinedVector::front() + // Overload of `InlinedVector::insert()` for inserting `n` contiguous copies + // of `v` starting at `position`. Returns an `iterator` pointing to the first + // of the newly inserted elements. + iterator insert(const_iterator position, size_type n, const_reference v) { + return InsertWithCount(position, n, v); + } + + // Overload of `InlinedVector::insert()` for copying the contents of the + // `std::initializer_list` into the vector starting at `position`. Returns an + // `iterator` pointing to the first of the newly inserted elements. + iterator insert(const_iterator position, + std::initializer_list<value_type> init_list) { + return insert(position, init_list.begin(), init_list.end()); + } + + // Overload of `InlinedVector::insert()` for inserting elements constructed + // from the range [`first`, `last`). Returns an `iterator` pointing to the + // first of the newly inserted elements. // - // Returns a reference to the first element of an inlined vector. - value_type& front() { - assert(!empty()); - return at(0); + // NOTE: The `enable_if` is intended to disambiguate the two three-argument + // overloads of `insert()`. + template <typename InputIterator, + typename = EnableIfInputIterator<InputIterator>> + iterator insert(const_iterator position, InputIterator first, + InputIterator last) { + return InsertWithRange(position, first, last, + IteratorCategory<InputIterator>()); } - // Overload of InlinedVector::front() returns a reference to the first element - // of an inlined vector of const values. - const value_type& front() const { - assert(!empty()); - return at(0); - } - - // InlinedVector::emplace_back() + // `InlinedVector::emplace()` // - // Constructs and appends an object to the inlined vector. - // - // Returns a reference to the inserted element. + // Constructs and inserts an object in the inlined vector at the given + // `position`, returning an `iterator` pointing to the newly emplaced element. template <typename... Args> - value_type& emplace_back(Args&&... args) { + iterator emplace(const_iterator position, Args&&... args) { + assert(position >= begin()); + assert(position <= end()); + if (ABSL_PREDICT_FALSE(position == end())) { + emplace_back(std::forward<Args>(args)...); + return end() - 1; + } + + T new_t = T(std::forward<Args>(args)...); + + auto range = ShiftRight(position, 1); + if (range.first == range.second) { + // constructing into uninitialized memory + Construct(range.first, std::move(new_t)); + } else { + // assigning into moved-from object + *range.first = T(std::move(new_t)); + } + + return range.first; + } + + // `InlinedVector::emplace_back()` + // + // Constructs and appends a new element to the end of the inlined vector, + // returning a `reference` to the emplaced element. + template <typename... Args> + reference emplace_back(Args&&... args) { size_type s = size(); assert(s <= capacity()); if (ABSL_PREDICT_FALSE(s == capacity())) { @@ -377,7 +640,7 @@ } assert(s < capacity()); - value_type* space; + pointer space; if (allocated()) { tag().set_allocated_size(s + 1); space = allocated_space(); @@ -388,19 +651,22 @@ return Construct(space + s, std::forward<Args>(args)...); } - // InlinedVector::push_back() + // `InlinedVector::push_back()` // - // Appends a const element to the inlined vector. - void push_back(const value_type& t) { emplace_back(t); } + // Appends a copy of `v` to the end of the inlined vector. + void push_back(const_reference v) { static_cast<void>(emplace_back(v)); } - // Overload of InlinedVector::push_back() to append a move-only element to the - // inlined vector. - void push_back(value_type&& t) { emplace_back(std::move(t)); } + // Overload of `InlinedVector::push_back()` for moving `v` into a newly + // appended element. + void push_back(rvalue_reference v) { + static_cast<void>(emplace_back(std::move(v))); + } - // InlinedVector::pop_back() + // `InlinedVector::pop_back()` // - // Removes the last element (which is destroyed) in the inlined vector. - void pop_back() { + // Destroys the element at the end of the inlined vector and shrinks the size + // by `1` (unless the inlined vector is empty, in which case this is a no-op). + void pop_back() noexcept { assert(!empty()); size_type s = size(); if (allocated()) { @@ -412,134 +678,12 @@ } } - // InlinedVector::resize() - // - // Resizes the inlined vector to contain `n` elements. If `n` is smaller than - // the inlined vector's current size, extra elements are destroyed. If `n` is - // larger than the initial size, new elements are value-initialized. - void resize(size_type n); - - // Overload of InlinedVector::resize() to resize the inlined vector to contain - // `n` elements. If `n` is larger than the current size, enough copies of - // `elem` are appended to increase its size to `n`. - void resize(size_type n, const value_type& elem); - - // InlinedVector::begin() - // - // Returns an iterator to the beginning of the inlined vector. - iterator begin() noexcept { return data(); } - - // Overload of InlinedVector::begin() for returning a const iterator to the - // beginning of the inlined vector. - const_iterator begin() const noexcept { return data(); } - - // InlinedVector::cbegin() - // - // Returns a const iterator to the beginning of the inlined vector. - const_iterator cbegin() const noexcept { return begin(); } - - // InlinedVector::end() - // - // Returns an iterator to the end of the inlined vector. - iterator end() noexcept { return data() + size(); } - - // Overload of InlinedVector::end() for returning a const iterator to the end - // of the inlined vector. - const_iterator end() const noexcept { return data() + size(); } - - // InlinedVector::cend() - // - // Returns a const iterator to the end of the inlined vector. - const_iterator cend() const noexcept { return end(); } - - // InlinedVector::rbegin() - // - // Returns a reverse iterator from the end of the inlined vector. - reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } - - // Overload of InlinedVector::rbegin() for returning a const reverse iterator - // from the end of the inlined vector. - const_reverse_iterator rbegin() const noexcept { - return const_reverse_iterator(end()); - } - - // InlinedVector::crbegin() - // - // Returns a const reverse iterator from the end of the inlined vector. - const_reverse_iterator crbegin() const noexcept { return rbegin(); } - - // InlinedVector::rend() - // - // Returns a reverse iterator from the beginning of the inlined vector. - reverse_iterator rend() noexcept { return reverse_iterator(begin()); } - - // Overload of InlinedVector::rend() for returning a const reverse iterator - // from the beginning of the inlined vector. - const_reverse_iterator rend() const noexcept { - return const_reverse_iterator(begin()); - } - - // InlinedVector::crend() - // - // Returns a reverse iterator from the beginning of the inlined vector. - const_reverse_iterator crend() const noexcept { return rend(); } - - // InlinedVector::emplace() - // - // Constructs and inserts an object to the inlined vector at the given - // `position`, returning an iterator pointing to the newly emplaced element. - template <typename... Args> - iterator emplace(const_iterator position, Args&&... args); - - // InlinedVector::insert() - // - // Inserts an element of the specified value at `position`, returning an - // iterator pointing to the newly inserted element. - iterator insert(const_iterator position, const value_type& v) { - return emplace(position, v); - } - - // Overload of InlinedVector::insert() for inserting an element of the - // specified rvalue, returning an iterator pointing to the newly inserted - // element. - iterator insert(const_iterator position, value_type&& v) { - return emplace(position, std::move(v)); - } - - // Overload of InlinedVector::insert() for inserting `n` elements of the - // specified value at `position`, returning an iterator pointing to the first - // of the newly inserted elements. - iterator insert(const_iterator position, size_type n, const value_type& v) { - return InsertWithCount(position, n, v); - } - - // Overload of `InlinedVector::insert()` to disambiguate the two - // three-argument overloads of `insert()`, returning an iterator pointing to - // the first of the newly inserted elements. - template <typename InputIterator, - typename = typename std::enable_if<std::is_convertible< - typename std::iterator_traits<InputIterator>::iterator_category, - std::input_iterator_tag>::value>::type> - iterator insert(const_iterator position, InputIterator first, - InputIterator last) { - using IterType = - typename std::iterator_traits<InputIterator>::iterator_category; - return InsertWithRange(position, first, last, IterType()); - } - - // Overload of InlinedVector::insert() for inserting a list of elements at - // `position`, returning an iterator pointing to the first of the newly - // inserted elements. - iterator insert(const_iterator position, - std::initializer_list<value_type> init) { - return insert(position, init.begin(), init.end()); - } - - // InlinedVector::erase() + // `InlinedVector::erase()` // // Erases the element at `position` of the inlined vector, returning an - // iterator pointing to the following element or the container's end if the - // last element was erased. + // `iterator` pointing to the first element following the erased element. + // + // NOTE: May return the end iterator, which is not dereferencable. iterator erase(const_iterator position) { assert(position >= begin()); assert(position < end()); @@ -550,23 +694,59 @@ return pos; } - // Overload of InlinedVector::erase() for erasing all elements in the - // iterator range [first, last) in the inlined vector, returning an iterator - // pointing to the first element following the range erased, or the - // container's end if range included the container's last element. - iterator erase(const_iterator first, const_iterator last); + // Overload of `InlinedVector::erase()` for erasing all elements in the + // range [`from`, `to`) in the inlined vector. Returns an `iterator` pointing + // to the first element following the range erased or the end iterator if `to` + // was the end iterator. + iterator erase(const_iterator from, const_iterator to) { + assert(begin() <= from); + assert(from <= to); + assert(to <= end()); - // InlinedVector::reserve() + iterator range_start = const_cast<iterator>(from); + iterator range_end = const_cast<iterator>(to); + + size_type s = size(); + ptrdiff_t erase_gap = std::distance(range_start, range_end); + if (erase_gap > 0) { + pointer space; + if (allocated()) { + space = allocated_space(); + tag().set_allocated_size(s - erase_gap); + } else { + space = inlined_space(); + tag().set_inline_size(s - erase_gap); + } + std::move(range_end, space + s, range_start); + Destroy(space + s - erase_gap, space + s); + } + return range_start; + } + + // `InlinedVector::clear()` + // + // Destroys all elements in the inlined vector, sets the size of `0` and + // deallocates the heap allocation if the inlined vector was allocated. + void clear() noexcept { + size_type s = size(); + if (allocated()) { + Destroy(allocated_space(), allocated_space() + s); + allocation().Dealloc(allocator()); + } else if (s != 0) { // do nothing for empty vectors + Destroy(inlined_space(), inlined_space() + s); + } + tag() = Tag(); + } + + // `InlinedVector::reserve()` // // Enlarges the underlying representation of the inlined vector so it can hold // at least `n` elements. This method does not change `size()` or the actual // contents of the vector. // - // Note that if `n` does not exceed the inlined vector's initial size `N`, - // `reserve()` will have no effect; if it does exceed its initial size, - // `reserve()` will trigger an initial allocation and move the inlined vector - // onto the heap. If the vector already exists on the heap and the requested - // size exceeds it, a reallocation will be performed. + // NOTE: If `n` does not exceed `capacity()`, `reserve()` will have no + // effects. Otherwise, `reserve()` will reallocate, performing an n-time + // element-wise move of everything contained. void reserve(size_type n) { if (n > capacity()) { // Make room for new elements @@ -574,26 +754,25 @@ } } - // InlinedVector::shrink_to_fit() + // `InlinedVector::shrink_to_fit()` // - // Reduces memory usage by freeing unused memory. - // After this call `capacity()` will be equal to `max(N, size())`. + // Reduces memory usage by freeing unused memory. After this call, calls to + // `capacity()` will be equal to `(std::max)(inlined_capacity(), size())`. // - // If `size() <= N` and the elements are currently stored on the heap, they - // will be moved to the inlined storage and the heap memory deallocated. - // If `size() > N` and `size() < capacity()` the elements will be moved to - // a reallocated storage on heap. + // If `size() <= inlined_capacity()` and the elements are currently stored on + // the heap, they will be moved to the inlined storage and the heap memory + // will be deallocated. + // + // If `size() > inlined_capacity()` and `size() < capacity()` the elements + // will be moved to a smaller heap allocation. void shrink_to_fit() { const auto s = size(); - if (!allocated() || s == capacity()) { - // There's nothing to deallocate. - return; - } + if (ABSL_PREDICT_FALSE(!allocated() || s == capacity())) return; - if (s <= N) { + if (s <= inlined_capacity()) { // Move the elements to the inlined storage. - // We have to do this using a temporary, because inlined_storage and - // allocation_storage are in a union field. + // We have to do this using a temporary, because `inlined_storage` and + // `allocation_storage` are in a union field. auto temp = std::move(*this); assign(std::make_move_iterator(temp.begin()), std::make_move_iterator(temp.end())); @@ -601,8 +780,8 @@ } // Reallocate storage and move elements. - // We can't simply use the same approach as above, because assign() would - // call into reserve() internally and reserve larger capacity than we need. + // We can't simply use the same approach as above, because `assign()` would + // call into `reserve()` internally and reserve larger capacity than we need Allocation new_allocation(allocator(), s); UninitializedCopy(std::make_move_iterator(allocated_space()), std::make_move_iterator(allocated_space() + s), @@ -610,32 +789,94 @@ ResetAllocation(new_allocation, s); } - // InlinedVector::swap() + // `InlinedVector::swap()` // // Swaps the contents of this inlined vector with the contents of `other`. - void swap(InlinedVector& other); + void swap(InlinedVector& other) { + using std::swap; // Augment ADL with `std::swap`. + if (ABSL_PREDICT_FALSE(this == &other)) return; - // InlinedVector::get_allocator() - // - // Returns the allocator of this inlined vector. - allocator_type get_allocator() const { return allocator(); } + if (allocated() && other.allocated()) { + // Both out of line, so just swap the tag, allocation, and allocator. + swap(tag(), other.tag()); + swap(allocation(), other.allocation()); + swap(allocator(), other.allocator()); + return; + } + if (!allocated() && !other.allocated()) { + // Both inlined: swap up to smaller size, then move remaining elements. + InlinedVector* a = this; + InlinedVector* b = &other; + if (size() < other.size()) { + swap(a, b); + } - template <typename H> - friend H AbslHashValue(H h, const InlinedVector& v) { - return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()), - v.size()); + const size_type a_size = a->size(); + const size_type b_size = b->size(); + assert(a_size >= b_size); + // `a` is larger. Swap the elements up to the smaller array size. + std::swap_ranges(a->inlined_space(), a->inlined_space() + b_size, + b->inlined_space()); + + // Move the remaining elements: + // [`b_size`, `a_size`) from `a` -> [`b_size`, `a_size`) from `b` + b->UninitializedCopy(a->inlined_space() + b_size, + a->inlined_space() + a_size, + b->inlined_space() + b_size); + a->Destroy(a->inlined_space() + b_size, a->inlined_space() + a_size); + + swap(a->tag(), b->tag()); + swap(a->allocator(), b->allocator()); + assert(b->size() == a_size); + assert(a->size() == b_size); + return; + } + + // One is out of line, one is inline. + // We first move the elements from the inlined vector into the + // inlined space in the other vector. We then put the other vector's + // pointer/capacity into the originally inlined vector and swap + // the tags. + InlinedVector* a = this; + InlinedVector* b = &other; + if (a->allocated()) { + swap(a, b); + } + assert(!a->allocated()); + assert(b->allocated()); + const size_type a_size = a->size(); + const size_type b_size = b->size(); + // In an optimized build, `b_size` would be unused. + static_cast<void>(b_size); + + // Made Local copies of `size()`, don't need `tag()` accurate anymore + swap(a->tag(), b->tag()); + + // Copy `b_allocation` out before `b`'s union gets clobbered by + // `inline_space` + Allocation b_allocation = b->allocation(); + + b->UninitializedCopy(a->inlined_space(), a->inlined_space() + a_size, + b->inlined_space()); + a->Destroy(a->inlined_space(), a->inlined_space() + a_size); + + a->allocation() = b_allocation; + + if (a->allocator() != b->allocator()) { + swap(a->allocator(), b->allocator()); + } + + assert(b->size() == a_size); + assert(a->size() == b_size); } private: - static_assert(N > 0, "inlined vector with nonpositive size"); + template <typename Hash, typename OtherT, size_t OtherN, typename OtherA> + friend Hash AbslHashValue(Hash, const InlinedVector<OtherT, OtherN, OtherA>&); - // It holds whether the vector is allocated or not in the lowest bit. - // The size is held in the high bits: - // size_ = (size << 1) | is_allocated; - // - // Maintainer's Note: size_type is user defined. The contract is limited to - // arithmetic operators to avoid depending on compliant overloaded bitwise - // operators. + // Holds whether the vector is allocated or not in the lowest bit and the size + // in the high bits: + // `size_ = (size << 1) | is_allocated;` class Tag { public: Tag() : size_(0) {} @@ -649,14 +890,15 @@ size_type size_; }; - // Derives from allocator_type to use the empty base class optimization. - // If the allocator_type is stateless, we can 'store' - // our instance of it for free. + // Derives from `allocator_type` to use the empty base class optimization. + // If the `allocator_type` is stateless, we can store our instance for free. class AllocatorAndTag : private allocator_type { public: explicit AllocatorAndTag(const allocator_type& a) : allocator_type(a) {} + Tag& tag() { return tag_; } const Tag& tag() const { return tag_; } + allocator_type& allocator() { return *this; } const allocator_type& allocator() const { return *this; } @@ -666,73 +908,68 @@ class Allocation { public: - Allocation(allocator_type& a, // NOLINT(runtime/references) - size_type capacity) - : capacity_(capacity), - buffer_(AllocatorTraits::allocate(a, capacity_)) {} + Allocation(allocator_type& a, size_type capacity) + : capacity_(capacity), buffer_(Create(a, capacity)) {} - void Dealloc(allocator_type& a) { // NOLINT(runtime/references) - AllocatorTraits::deallocate(a, buffer(), capacity()); + void Dealloc(allocator_type& a) { + std::allocator_traits<allocator_type>::deallocate(a, buffer_, capacity_); } size_type capacity() const { return capacity_; } - const value_type* buffer() const { return buffer_; } - value_type* buffer() { return buffer_; } + + const_pointer buffer() const { return buffer_; } + + pointer buffer() { return buffer_; } private: + static pointer Create(allocator_type& a, size_type n) { + return std::allocator_traits<allocator_type>::allocate(a, n); + } + size_type capacity_; - value_type* buffer_; + pointer buffer_; }; const Tag& tag() const { return allocator_and_tag_.tag(); } + Tag& tag() { return allocator_and_tag_.tag(); } Allocation& allocation() { return reinterpret_cast<Allocation&>(rep_.allocation_storage.allocation); } + const Allocation& allocation() const { return reinterpret_cast<const Allocation&>( rep_.allocation_storage.allocation); } + void init_allocation(const Allocation& allocation) { new (&rep_.allocation_storage.allocation) Allocation(allocation); } // TODO(absl-team): investigate whether the reinterpret_cast is appropriate. - value_type* inlined_space() { - return reinterpret_cast<value_type*>( - std::addressof(rep_.inlined_storage.inlined[0])); - } - const value_type* inlined_space() const { - return reinterpret_cast<const value_type*>( + pointer inlined_space() { + return reinterpret_cast<pointer>( std::addressof(rep_.inlined_storage.inlined[0])); } - value_type* allocated_space() { return allocation().buffer(); } - const value_type* allocated_space() const { return allocation().buffer(); } + const_pointer inlined_space() const { + return reinterpret_cast<const_pointer>( + std::addressof(rep_.inlined_storage.inlined[0])); + } + + pointer allocated_space() { return allocation().buffer(); } + + const_pointer allocated_space() const { return allocation().buffer(); } const allocator_type& allocator() const { return allocator_and_tag_.allocator(); } + allocator_type& allocator() { return allocator_and_tag_.allocator(); } bool allocated() const { return tag().allocated(); } - // Enlarge the underlying representation so we can store size_ + delta elems. - // The size is not changed, and any newly added memory is not initialized. - void EnlargeBy(size_type delta); - - // Shift all elements from position to end() n places to the right. - // If the vector needs to be enlarged, memory will be allocated. - // Returns iterators pointing to the start of the previously-initialized - // portion and the start of the uninitialized portion of the created gap. - // The number of initialized spots is pair.second - pair.first; - // the number of raw spots is n - (pair.second - pair.first). - // - // Updates the size of the InlinedVector internally. - std::pair<iterator, iterator> ShiftRight(const_iterator position, - size_type n); - void ResetAllocation(Allocation new_allocation, size_type new_size) { if (allocated()) { Destroy(allocated_space(), allocated_space() + size()); @@ -747,13 +984,137 @@ } template <typename... Args> - value_type& GrowAndEmplaceBack(Args&&... args) { + reference Construct(pointer p, Args&&... args) { + std::allocator_traits<allocator_type>::construct( + allocator(), p, std::forward<Args>(args)...); + return *p; + } + + template <typename Iterator> + void UninitializedCopy(Iterator src, Iterator src_last, pointer dst) { + for (; src != src_last; ++dst, ++src) Construct(dst, *src); + } + + template <typename... Args> + void UninitializedFill(pointer dst, pointer dst_last, const Args&... args) { + for (; dst != dst_last; ++dst) Construct(dst, args...); + } + + // Destroy [`from`, `to`) in place. + void Destroy(pointer from, pointer to) { + for (pointer cur = from; cur != to; ++cur) { + std::allocator_traits<allocator_type>::destroy(allocator(), cur); + } +#if !defined(NDEBUG) + // Overwrite unused memory with `0xab` so we can catch uninitialized usage. + // Cast to `void*` to tell the compiler that we don't care that we might be + // scribbling on a vtable pointer. + if (from != to) { + auto len = sizeof(value_type) * std::distance(from, to); + std::memset(reinterpret_cast<void*>(from), 0xab, len); + } +#endif // !defined(NDEBUG) + } + + // Enlarge the underlying representation so we can store `size_ + delta` elems + // in allocated space. The size is not changed, and any newly added memory is + // not initialized. + void EnlargeBy(size_type delta) { + const size_type s = size(); + assert(s <= capacity()); + + size_type target = (std::max)(inlined_capacity(), s + delta); + + // Compute new capacity by repeatedly doubling current capacity + // TODO(psrc): Check and avoid overflow? + size_type new_capacity = capacity(); + while (new_capacity < target) { + new_capacity <<= 1; + } + + Allocation new_allocation(allocator(), new_capacity); + + UninitializedCopy(std::make_move_iterator(data()), + std::make_move_iterator(data() + s), + new_allocation.buffer()); + + ResetAllocation(new_allocation, s); + } + + // Shift all elements from `position` to `end()` by `n` places to the right. + // If the vector needs to be enlarged, memory will be allocated. + // Returns `iterator`s pointing to the start of the previously-initialized + // portion and the start of the uninitialized portion of the created gap. + // The number of initialized spots is `pair.second - pair.first`. The number + // of raw spots is `n - (pair.second - pair.first)`. + // + // Updates the size of the InlinedVector internally. + std::pair<iterator, iterator> ShiftRight(const_iterator position, + size_type n) { + iterator start_used = const_cast<iterator>(position); + iterator start_raw = const_cast<iterator>(position); + size_type s = size(); + size_type required_size = s + n; + + if (required_size > capacity()) { + // Compute new capacity by repeatedly doubling current capacity + size_type new_capacity = capacity(); + while (new_capacity < required_size) { + new_capacity <<= 1; + } + // Move everyone into the new allocation, leaving a gap of `n` for the + // requested shift. + Allocation new_allocation(allocator(), new_capacity); + size_type index = position - begin(); + UninitializedCopy(std::make_move_iterator(data()), + std::make_move_iterator(data() + index), + new_allocation.buffer()); + UninitializedCopy(std::make_move_iterator(data() + index), + std::make_move_iterator(data() + s), + new_allocation.buffer() + index + n); + ResetAllocation(new_allocation, s); + + // New allocation means our iterator is invalid, so we'll recalculate. + // Since the entire gap is in new space, there's no used space to reuse. + start_raw = begin() + index; + start_used = start_raw; + } else { + // If we had enough space, it's a two-part move. Elements going into + // previously-unoccupied space need an `UninitializedCopy()`. Elements + // going into a previously-occupied space are just a `std::move()`. + iterator pos = const_cast<iterator>(position); + iterator raw_space = end(); + size_type slots_in_used_space = raw_space - pos; + size_type new_elements_in_used_space = (std::min)(n, slots_in_used_space); + size_type new_elements_in_raw_space = n - new_elements_in_used_space; + size_type old_elements_in_used_space = + slots_in_used_space - new_elements_in_used_space; + + UninitializedCopy( + std::make_move_iterator(pos + old_elements_in_used_space), + std::make_move_iterator(raw_space), + raw_space + new_elements_in_raw_space); + std::move_backward(pos, pos + old_elements_in_used_space, raw_space); + + // If the gap is entirely in raw space, the used space starts where the + // raw space starts, leaving no elements in used space. If the gap is + // entirely in used space, the raw space starts at the end of the gap, + // leaving all elements accounted for within the used space. + start_used = pos; + start_raw = pos + new_elements_in_used_space; + } + tag().add_size(n); + return std::make_pair(start_used, start_raw); + } + + template <typename... Args> + reference GrowAndEmplaceBack(Args&&... args) { assert(size() == capacity()); const size_type s = size(); Allocation new_allocation(allocator(), 2 * capacity()); - value_type& new_element = + reference new_element = Construct(new_allocation.buffer() + s, std::forward<Args>(args)...); UninitializedCopy(std::make_move_iterator(data()), std::make_move_iterator(data() + s), @@ -764,99 +1125,158 @@ return new_element; } - void InitAssign(size_type n); - void InitAssign(size_type n, const value_type& t); - - template <typename... Args> - value_type& Construct(pointer p, Args&&... args) { - AllocatorTraits::construct(allocator(), p, std::forward<Args>(args)...); - return *p; + void InitAssign(size_type n) { + if (n > inlined_capacity()) { + Allocation new_allocation(allocator(), n); + init_allocation(new_allocation); + UninitializedFill(allocated_space(), allocated_space() + n); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space(), inlined_space() + n); + tag().set_inline_size(n); + } } - template <typename Iter> - void UninitializedCopy(Iter src, Iter src_last, value_type* dst) { - for (; src != src_last; ++dst, ++src) Construct(dst, *src); + void InitAssign(size_type n, const_reference v) { + if (n > inlined_capacity()) { + Allocation new_allocation(allocator(), n); + init_allocation(new_allocation); + UninitializedFill(allocated_space(), allocated_space() + n, v); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space(), inlined_space() + n, v); + tag().set_inline_size(n); + } } - template <typename... Args> - void UninitializedFill(value_type* dst, value_type* dst_last, - const Args&... args) { - for (; dst != dst_last; ++dst) Construct(dst, args...); + template <typename Iterator> + void AssignRange(Iterator first, Iterator last, std::forward_iterator_tag) { + auto length = std::distance(first, last); + // Prefer reassignment to copy construction for elements. + if (static_cast<size_type>(length) <= size()) { + erase(std::copy(first, last, begin()), end()); + return; + } + reserve(length); + iterator out = begin(); + for (; out != end(); ++first, ++out) *out = *first; + if (allocated()) { + UninitializedCopy(first, last, out); + tag().set_allocated_size(length); + } else { + UninitializedCopy(first, last, out); + tag().set_inline_size(length); + } } - // Destroy [ptr, ptr_last) in place. - void Destroy(value_type* ptr, value_type* ptr_last); - - template <typename Iter> - void AppendRange(Iter first, Iter last, std::input_iterator_tag) { + template <typename Iterator> + void AssignRange(Iterator first, Iterator last, std::input_iterator_tag) { + // Optimized to avoid reallocation. + // Prefer reassignment to copy construction for elements. + iterator out = begin(); + for (; first != last && out != end(); ++first, ++out) { + *out = *first; + } + erase(out, end()); std::copy(first, last, std::back_inserter(*this)); } - // Faster path for forward iterators. - template <typename Iter> - void AppendRange(Iter first, Iter last, std::forward_iterator_tag); - - template <typename Iter> - void AppendRange(Iter first, Iter last) { - using IterTag = typename std::iterator_traits<Iter>::iterator_category; - AppendRange(first, last, IterTag()); + template <typename Iterator> + void AppendRange(Iterator first, Iterator last, std::forward_iterator_tag) { + auto length = std::distance(first, last); + reserve(size() + length); + if (allocated()) { + UninitializedCopy(first, last, allocated_space() + size()); + tag().set_allocated_size(size() + length); + } else { + UninitializedCopy(first, last, inlined_space() + size()); + tag().set_inline_size(size() + length); + } } - template <typename Iter> - void AssignRange(Iter first, Iter last, std::input_iterator_tag); - - // Faster path for forward iterators. - template <typename Iter> - void AssignRange(Iter first, Iter last, std::forward_iterator_tag); - - template <typename Iter> - void AssignRange(Iter first, Iter last) { - using IterTag = typename std::iterator_traits<Iter>::iterator_category; - AssignRange(first, last, IterTag()); + template <typename Iterator> + void AppendRange(Iterator first, Iterator last, std::input_iterator_tag) { + std::copy(first, last, std::back_inserter(*this)); } iterator InsertWithCount(const_iterator position, size_type n, - const value_type& v); + const_reference v) { + assert(position >= begin() && position <= end()); + if (ABSL_PREDICT_FALSE(n == 0)) return const_cast<iterator>(position); - template <typename InputIter> - iterator InsertWithRange(const_iterator position, InputIter first, - InputIter last, std::input_iterator_tag); - template <typename ForwardIter> - iterator InsertWithRange(const_iterator position, ForwardIter first, - ForwardIter last, std::forward_iterator_tag); + value_type copy = v; + std::pair<iterator, iterator> it_pair = ShiftRight(position, n); + std::fill(it_pair.first, it_pair.second, copy); + UninitializedFill(it_pair.second, it_pair.first + n, copy); + + return it_pair.first; + } + + template <typename ForwardIterator> + iterator InsertWithRange(const_iterator position, ForwardIterator first, + ForwardIterator last, std::forward_iterator_tag) { + assert(position >= begin() && position <= end()); + if (ABSL_PREDICT_FALSE(first == last)) + return const_cast<iterator>(position); + + auto n = std::distance(first, last); + std::pair<iterator, iterator> it_pair = ShiftRight(position, n); + size_type used_spots = it_pair.second - it_pair.first; + ForwardIterator open_spot = std::next(first, used_spots); + std::copy(first, open_spot, it_pair.first); + UninitializedCopy(open_spot, last, it_pair.second); + return it_pair.first; + } + + template <typename InputIterator> + iterator InsertWithRange(const_iterator position, InputIterator first, + InputIterator last, std::input_iterator_tag) { + assert(position >= begin() && position <= end()); + size_type index = position - cbegin(); + size_type i = index; + while (first != last) insert(begin() + i++, *first++); + return begin() + index; + } + + // Stores either the inlined or allocated representation + union Rep { + using ValueTypeBuffer = + absl::aligned_storage_t<sizeof(value_type), alignof(value_type)>; + using AllocationBuffer = + absl::aligned_storage_t<sizeof(Allocation), alignof(Allocation)>; + + // Structs wrap the buffers to perform indirection that solves a bizarre + // compilation error on Visual Studio (all known versions). + struct InlinedRep { + ValueTypeBuffer inlined[N]; + }; + struct AllocatedRep { + AllocationBuffer allocation; + }; + + InlinedRep inlined_storage; + AllocatedRep allocation_storage; + }; AllocatorAndTag allocator_and_tag_; - - // Either the inlined or allocated representation - union Rep { - // Use struct to perform indirection that solves a bizarre compilation - // error on Visual Studio (all known versions). - struct { - typename std::aligned_storage<sizeof(value_type), - alignof(value_type)>::type inlined[N]; - } inlined_storage; - struct { - typename std::aligned_storage<sizeof(Allocation), - alignof(Allocation)>::type allocation; - } allocation_storage; - } rep_; + Rep rep_; }; // ----------------------------------------------------------------------------- // InlinedVector Non-Member Functions // ----------------------------------------------------------------------------- -// swap() +// `swap()` // // Swaps the contents of two inlined vectors. This convenience function -// simply calls InlinedVector::swap(other_inlined_vector). +// simply calls `InlinedVector::swap()`. template <typename T, size_t N, typename A> void swap(InlinedVector<T, N, A>& a, InlinedVector<T, N, A>& b) noexcept(noexcept(a.swap(b))) { a.swap(b); } -// operator==() +// `operator==()` // // Tests the equivalency of the contents of two inlined vectors. template <typename T, size_t N, typename A> @@ -865,7 +1285,7 @@ return absl::equal(a.begin(), a.end(), b.begin(), b.end()); } -// operator!=() +// `operator!=()` // // Tests the inequality of the contents of two inlined vectors. template <typename T, size_t N, typename A> @@ -874,7 +1294,7 @@ return !(a == b); } -// operator<() +// `operator<()` // // Tests whether the contents of one inlined vector are less than the contents // of another through a lexicographical comparison operation. @@ -884,7 +1304,7 @@ return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); } -// operator>() +// `operator>()` // // Tests whether the contents of one inlined vector are greater than the // contents of another through a lexicographical comparison operation. @@ -894,7 +1314,7 @@ return b < a; } -// operator<=() +// `operator<=()` // // Tests whether the contents of one inlined vector are less than or equal to // the contents of another through a lexicographical comparison operation. @@ -904,7 +1324,7 @@ return !(b < a); } -// operator>=() +// `operator>=()` // // Tests whether the contents of one inlined vector are greater than or equal to // the contents of another through a lexicographical comparison operation. @@ -914,477 +1334,18 @@ return !(a < b); } +template <typename Hash, typename T, size_t N, typename A> +Hash AbslHashValue(Hash hash, const InlinedVector<T, N, A>& inlined_vector) { + auto p = inlined_vector.data(); + auto n = inlined_vector.size(); + return Hash::combine(Hash::combine_contiguous(std::move(hash), p, n), n); +} + // ----------------------------------------------------------------------------- // Implementation of InlinedVector -// ----------------------------------------------------------------------------- // -// Do not depend on any implementation details below this line. - -template <typename T, size_t N, typename A> -InlinedVector<T, N, A>::InlinedVector(const InlinedVector& v) - : allocator_and_tag_(v.allocator()) { - reserve(v.size()); - if (allocated()) { - UninitializedCopy(v.begin(), v.end(), allocated_space()); - tag().set_allocated_size(v.size()); - } else { - UninitializedCopy(v.begin(), v.end(), inlined_space()); - tag().set_inline_size(v.size()); - } -} - -template <typename T, size_t N, typename A> -InlinedVector<T, N, A>::InlinedVector(const InlinedVector& v, - const allocator_type& alloc) - : allocator_and_tag_(alloc) { - reserve(v.size()); - if (allocated()) { - UninitializedCopy(v.begin(), v.end(), allocated_space()); - tag().set_allocated_size(v.size()); - } else { - UninitializedCopy(v.begin(), v.end(), inlined_space()); - tag().set_inline_size(v.size()); - } -} - -template <typename T, size_t N, typename A> -InlinedVector<T, N, A>::InlinedVector(InlinedVector&& v) noexcept( - absl::allocator_is_nothrow<allocator_type>::value || - std::is_nothrow_move_constructible<value_type>::value) - : allocator_and_tag_(v.allocator_and_tag_) { - if (v.allocated()) { - // We can just steal the underlying buffer from the source. - // That leaves the source empty, so we clear its size. - init_allocation(v.allocation()); - v.tag() = Tag(); - } else { - UninitializedCopy(std::make_move_iterator(v.inlined_space()), - std::make_move_iterator(v.inlined_space() + v.size()), - inlined_space()); - } -} - -template <typename T, size_t N, typename A> -InlinedVector<T, N, A>::InlinedVector( - InlinedVector&& v, - const allocator_type& - alloc) noexcept(absl::allocator_is_nothrow<allocator_type>::value) - : allocator_and_tag_(alloc) { - if (v.allocated()) { - if (alloc == v.allocator()) { - // We can just steal the allocation from the source. - tag() = v.tag(); - init_allocation(v.allocation()); - v.tag() = Tag(); - } else { - // We need to use our own allocator - reserve(v.size()); - UninitializedCopy(std::make_move_iterator(v.begin()), - std::make_move_iterator(v.end()), allocated_space()); - tag().set_allocated_size(v.size()); - } - } else { - UninitializedCopy(std::make_move_iterator(v.inlined_space()), - std::make_move_iterator(v.inlined_space() + v.size()), - inlined_space()); - tag().set_inline_size(v.size()); - } -} - -template <typename T, size_t N, typename A> -void InlinedVector<T, N, A>::InitAssign(size_type n, const value_type& t) { - if (n > static_cast<size_type>(N)) { - Allocation new_allocation(allocator(), n); - init_allocation(new_allocation); - UninitializedFill(allocated_space(), allocated_space() + n, t); - tag().set_allocated_size(n); - } else { - UninitializedFill(inlined_space(), inlined_space() + n, t); - tag().set_inline_size(n); - } -} - -template <typename T, size_t N, typename A> -void InlinedVector<T, N, A>::InitAssign(size_type n) { - if (n > static_cast<size_type>(N)) { - Allocation new_allocation(allocator(), n); - init_allocation(new_allocation); - UninitializedFill(allocated_space(), allocated_space() + n); - tag().set_allocated_size(n); - } else { - UninitializedFill(inlined_space(), inlined_space() + n); - tag().set_inline_size(n); - } -} - -template <typename T, size_t N, typename A> -void InlinedVector<T, N, A>::resize(size_type n) { - size_type s = size(); - if (n < s) { - erase(begin() + n, end()); - return; - } - reserve(n); - assert(capacity() >= n); - - // Fill new space with elements constructed in-place. - if (allocated()) { - UninitializedFill(allocated_space() + s, allocated_space() + n); - tag().set_allocated_size(n); - } else { - UninitializedFill(inlined_space() + s, inlined_space() + n); - tag().set_inline_size(n); - } -} - -template <typename T, size_t N, typename A> -void InlinedVector<T, N, A>::resize(size_type n, const value_type& elem) { - size_type s = size(); - if (n < s) { - erase(begin() + n, end()); - return; - } - reserve(n); - assert(capacity() >= n); - - // Fill new space with copies of 'elem'. - if (allocated()) { - UninitializedFill(allocated_space() + s, allocated_space() + n, elem); - tag().set_allocated_size(n); - } else { - UninitializedFill(inlined_space() + s, inlined_space() + n, elem); - tag().set_inline_size(n); - } -} - -template <typename T, size_t N, typename A> -template <typename... Args> -typename InlinedVector<T, N, A>::iterator InlinedVector<T, N, A>::emplace( - const_iterator position, Args&&... args) { - assert(position >= begin()); - assert(position <= end()); - if (position == end()) { - emplace_back(std::forward<Args>(args)...); - return end() - 1; - } - - T new_t = T(std::forward<Args>(args)...); - - auto range = ShiftRight(position, 1); - if (range.first == range.second) { - // constructing into uninitialized memory - Construct(range.first, std::move(new_t)); - } else { - // assigning into moved-from object - *range.first = T(std::move(new_t)); - } - - return range.first; -} - -template <typename T, size_t N, typename A> -typename InlinedVector<T, N, A>::iterator InlinedVector<T, N, A>::erase( - const_iterator first, const_iterator last) { - assert(begin() <= first); - assert(first <= last); - assert(last <= end()); - - iterator range_start = const_cast<iterator>(first); - iterator range_end = const_cast<iterator>(last); - - size_type s = size(); - ptrdiff_t erase_gap = std::distance(range_start, range_end); - if (erase_gap > 0) { - pointer space; - if (allocated()) { - space = allocated_space(); - tag().set_allocated_size(s - erase_gap); - } else { - space = inlined_space(); - tag().set_inline_size(s - erase_gap); - } - std::move(range_end, space + s, range_start); - Destroy(space + s - erase_gap, space + s); - } - return range_start; -} - -template <typename T, size_t N, typename A> -void InlinedVector<T, N, A>::swap(InlinedVector& other) { - using std::swap; // Augment ADL with std::swap. - if (&other == this) { - return; - } - if (allocated() && other.allocated()) { - // Both out of line, so just swap the tag, allocation, and allocator. - swap(tag(), other.tag()); - swap(allocation(), other.allocation()); - swap(allocator(), other.allocator()); - return; - } - if (!allocated() && !other.allocated()) { - // Both inlined: swap up to smaller size, then move remaining elements. - InlinedVector* a = this; - InlinedVector* b = &other; - if (size() < other.size()) { - swap(a, b); - } - - const size_type a_size = a->size(); - const size_type b_size = b->size(); - assert(a_size >= b_size); - // 'a' is larger. Swap the elements up to the smaller array size. - std::swap_ranges(a->inlined_space(), a->inlined_space() + b_size, - b->inlined_space()); - - // Move the remaining elements: A[b_size,a_size) -> B[b_size,a_size) - b->UninitializedCopy(a->inlined_space() + b_size, - a->inlined_space() + a_size, - b->inlined_space() + b_size); - a->Destroy(a->inlined_space() + b_size, a->inlined_space() + a_size); - - swap(a->tag(), b->tag()); - swap(a->allocator(), b->allocator()); - assert(b->size() == a_size); - assert(a->size() == b_size); - return; - } - // One is out of line, one is inline. - // We first move the elements from the inlined vector into the - // inlined space in the other vector. We then put the other vector's - // pointer/capacity into the originally inlined vector and swap - // the tags. - InlinedVector* a = this; - InlinedVector* b = &other; - if (a->allocated()) { - swap(a, b); - } - assert(!a->allocated()); - assert(b->allocated()); - const size_type a_size = a->size(); - const size_type b_size = b->size(); - // In an optimized build, b_size would be unused. - (void)b_size; - - // Made Local copies of size(), don't need tag() accurate anymore - swap(a->tag(), b->tag()); - - // Copy b_allocation out before b's union gets clobbered by inline_space. - Allocation b_allocation = b->allocation(); - - b->UninitializedCopy(a->inlined_space(), a->inlined_space() + a_size, - b->inlined_space()); - a->Destroy(a->inlined_space(), a->inlined_space() + a_size); - - a->allocation() = b_allocation; - - if (a->allocator() != b->allocator()) { - swap(a->allocator(), b->allocator()); - } - - assert(b->size() == a_size); - assert(a->size() == b_size); -} - -template <typename T, size_t N, typename A> -void InlinedVector<T, N, A>::EnlargeBy(size_type delta) { - const size_type s = size(); - assert(s <= capacity()); - - size_type target = std::max(static_cast<size_type>(N), s + delta); - - // Compute new capacity by repeatedly doubling current capacity - // TODO(psrc): Check and avoid overflow? - size_type new_capacity = capacity(); - while (new_capacity < target) { - new_capacity <<= 1; - } - - Allocation new_allocation(allocator(), new_capacity); - - UninitializedCopy(std::make_move_iterator(data()), - std::make_move_iterator(data() + s), - new_allocation.buffer()); - - ResetAllocation(new_allocation, s); -} - -template <typename T, size_t N, typename A> -auto InlinedVector<T, N, A>::ShiftRight(const_iterator position, size_type n) - -> std::pair<iterator, iterator> { - iterator start_used = const_cast<iterator>(position); - iterator start_raw = const_cast<iterator>(position); - size_type s = size(); - size_type required_size = s + n; - - if (required_size > capacity()) { - // Compute new capacity by repeatedly doubling current capacity - size_type new_capacity = capacity(); - while (new_capacity < required_size) { - new_capacity <<= 1; - } - // Move everyone into the new allocation, leaving a gap of n for the - // requested shift. - Allocation new_allocation(allocator(), new_capacity); - size_type index = position - begin(); - UninitializedCopy(std::make_move_iterator(data()), - std::make_move_iterator(data() + index), - new_allocation.buffer()); - UninitializedCopy(std::make_move_iterator(data() + index), - std::make_move_iterator(data() + s), - new_allocation.buffer() + index + n); - ResetAllocation(new_allocation, s); - - // New allocation means our iterator is invalid, so we'll recalculate. - // Since the entire gap is in new space, there's no used space to reuse. - start_raw = begin() + index; - start_used = start_raw; - } else { - // If we had enough space, it's a two-part move. Elements going into - // previously-unoccupied space need an UninitializedCopy. Elements - // going into a previously-occupied space are just a move. - iterator pos = const_cast<iterator>(position); - iterator raw_space = end(); - size_type slots_in_used_space = raw_space - pos; - size_type new_elements_in_used_space = std::min(n, slots_in_used_space); - size_type new_elements_in_raw_space = n - new_elements_in_used_space; - size_type old_elements_in_used_space = - slots_in_used_space - new_elements_in_used_space; - - UninitializedCopy(std::make_move_iterator(pos + old_elements_in_used_space), - std::make_move_iterator(raw_space), - raw_space + new_elements_in_raw_space); - std::move_backward(pos, pos + old_elements_in_used_space, raw_space); - - // If the gap is entirely in raw space, the used space starts where the raw - // space starts, leaving no elements in used space. If the gap is entirely - // in used space, the raw space starts at the end of the gap, leaving all - // elements accounted for within the used space. - start_used = pos; - start_raw = pos + new_elements_in_used_space; - } - tag().add_size(n); - return std::make_pair(start_used, start_raw); -} - -template <typename T, size_t N, typename A> -void InlinedVector<T, N, A>::Destroy(value_type* ptr, value_type* ptr_last) { - for (value_type* p = ptr; p != ptr_last; ++p) { - AllocatorTraits::destroy(allocator(), p); - } - - // Overwrite unused memory with 0xab so we can catch uninitialized usage. - // Cast to void* to tell the compiler that we don't care that we might be - // scribbling on a vtable pointer. -#ifndef NDEBUG - if (ptr != ptr_last) { - memset(reinterpret_cast<void*>(ptr), 0xab, sizeof(*ptr) * (ptr_last - ptr)); - } -#endif -} - -template <typename T, size_t N, typename A> -template <typename Iter> -void InlinedVector<T, N, A>::AppendRange(Iter first, Iter last, - std::forward_iterator_tag) { - using Length = typename std::iterator_traits<Iter>::difference_type; - Length length = std::distance(first, last); - reserve(size() + length); - if (allocated()) { - UninitializedCopy(first, last, allocated_space() + size()); - tag().set_allocated_size(size() + length); - } else { - UninitializedCopy(first, last, inlined_space() + size()); - tag().set_inline_size(size() + length); - } -} - -template <typename T, size_t N, typename A> -template <typename Iter> -void InlinedVector<T, N, A>::AssignRange(Iter first, Iter last, - std::input_iterator_tag) { - // Optimized to avoid reallocation. - // Prefer reassignment to copy construction for elements. - iterator out = begin(); - for (; first != last && out != end(); ++first, ++out) { - *out = *first; - } - erase(out, end()); - std::copy(first, last, std::back_inserter(*this)); -} - -template <typename T, size_t N, typename A> -template <typename Iter> -void InlinedVector<T, N, A>::AssignRange(Iter first, Iter last, - std::forward_iterator_tag) { - using Length = typename std::iterator_traits<Iter>::difference_type; - Length length = std::distance(first, last); - // Prefer reassignment to copy construction for elements. - if (static_cast<size_type>(length) <= size()) { - erase(std::copy(first, last, begin()), end()); - return; - } - reserve(length); - iterator out = begin(); - for (; out != end(); ++first, ++out) *out = *first; - if (allocated()) { - UninitializedCopy(first, last, out); - tag().set_allocated_size(length); - } else { - UninitializedCopy(first, last, out); - tag().set_inline_size(length); - } -} - -template <typename T, size_t N, typename A> -auto InlinedVector<T, N, A>::InsertWithCount(const_iterator position, - size_type n, const value_type& v) - -> iterator { - assert(position >= begin() && position <= end()); - if (n == 0) return const_cast<iterator>(position); - - value_type copy = v; - std::pair<iterator, iterator> it_pair = ShiftRight(position, n); - std::fill(it_pair.first, it_pair.second, copy); - UninitializedFill(it_pair.second, it_pair.first + n, copy); - - return it_pair.first; -} - -template <typename T, size_t N, typename A> -template <typename InputIter> -auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position, - InputIter first, InputIter last, - std::input_iterator_tag) - -> iterator { - assert(position >= begin() && position <= end()); - size_type index = position - cbegin(); - size_type i = index; - while (first != last) insert(begin() + i++, *first++); - return begin() + index; -} - -// Overload of InlinedVector::InsertWithRange() -template <typename T, size_t N, typename A> -template <typename ForwardIter> -auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position, - ForwardIter first, - ForwardIter last, - std::forward_iterator_tag) - -> iterator { - assert(position >= begin() && position <= end()); - if (first == last) { - return const_cast<iterator>(position); - } - using Length = typename std::iterator_traits<ForwardIter>::difference_type; - Length n = std::distance(first, last); - std::pair<iterator, iterator> it_pair = ShiftRight(position, n); - size_type used_spots = it_pair.second - it_pair.first; - ForwardIter open_spot = std::next(first, used_spots); - std::copy(first, open_spot, it_pair.first); - UninitializedCopy(open_spot, last, it_pair.second); - return it_pair.first; -} +// Do not depend on any below implementation details! +// ----------------------------------------------------------------------------- } // namespace absl
diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc index 08dcd3e..3a1ea8a 100644 --- a/absl/container/inlined_vector_test.cc +++ b/absl/container/inlined_vector_test.cc
@@ -906,6 +906,8 @@ InstanceTracker tracker; InstanceVec a, b; const size_t inlined_capacity = a.capacity(); + auto min_len = std::min(l1, l2); + auto max_len = std::max(l1, l2); for (int i = 0; i < l1; i++) a.push_back(Instance(i)); for (int i = 0; i < l2; i++) b.push_back(Instance(100+i)); EXPECT_EQ(tracker.instances(), l1 + l2); @@ -919,15 +921,15 @@ EXPECT_EQ(tracker.swaps(), 0); // Allocations are swapped. EXPECT_EQ(tracker.moves(), 0); } else if (a.size() <= inlined_capacity && b.size() <= inlined_capacity) { - EXPECT_EQ(tracker.swaps(), std::min(l1, l2)); - // TODO(bsamwel): This should use moves when the type is movable. - EXPECT_EQ(tracker.copies(), std::max(l1, l2) - std::min(l1, l2)); + EXPECT_EQ(tracker.swaps(), min_len); + EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()), + max_len - min_len); } else { // One is allocated and the other isn't. The allocation is transferred // without copying elements, and the inlined instances are copied/moved. EXPECT_EQ(tracker.swaps(), 0); - // TODO(bsamwel): This should use moves when the type is movable. - EXPECT_EQ(tracker.copies(), std::min(l1, l2)); + EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()), + min_len); } EXPECT_EQ(l1, b.size()); @@ -1726,39 +1728,58 @@ std::scoped_allocator_adaptor<CountingAllocator<StdVector>>; using AllocVec = absl::InlinedVector<StdVector, 4, MyAlloc>; + // MSVC 2017's std::vector allocates different amounts of memory in debug + // versus opt mode. + int64_t test_allocated = 0; + StdVector v(CountingAllocator<int>{&test_allocated}); + // The amount of memory allocated by a default constructed vector<int> + auto default_std_vec_allocated = test_allocated; + v.push_back(1); + // The amound of memory allocated by a copy-constructed vector<int> with one + // element. + int64_t one_element_std_vec_copy_allocated = test_allocated; + int64_t allocated = 0; AllocVec vec(MyAlloc{CountingAllocator<StdVector>{&allocated}}); EXPECT_EQ(allocated, 0); // This default constructs a vector<int>, but the allocator should pass itself - // into the vector<int>. + // into the vector<int>, so check allocation compared to that. // The absl::InlinedVector does not allocate any memory. - // The vector<int> does not allocate any memory. + // The vector<int> may allocate any memory. + auto expected = default_std_vec_allocated; vec.resize(1); - EXPECT_EQ(allocated, 0); + EXPECT_EQ(allocated, expected); // We make vector<int> allocate memory. // It must go through the allocator even though we didn't construct the - // vector directly. + // vector directly. This assumes that vec[0] doesn't need to grow its + // allocation. + expected += sizeof(int); vec[0].push_back(1); - EXPECT_EQ(allocated, sizeof(int) * 1); + EXPECT_EQ(allocated, expected); // Another allocating vector. + expected += one_element_std_vec_copy_allocated; vec.push_back(vec[0]); - EXPECT_EQ(allocated, sizeof(int) * 2); + EXPECT_EQ(allocated, expected); // Overflow the inlined memory. // The absl::InlinedVector will now allocate. + expected += sizeof(StdVector) * 8 + default_std_vec_allocated * 3; vec.resize(5); - EXPECT_EQ(allocated, sizeof(int) * 2 + sizeof(StdVector) * 8); + EXPECT_EQ(allocated, expected); // Adding one more in external mode should also work. + expected += one_element_std_vec_copy_allocated; vec.push_back(vec[0]); - EXPECT_EQ(allocated, sizeof(int) * 3 + sizeof(StdVector) * 8); + EXPECT_EQ(allocated, expected); - // And extending these should still work. + // And extending these should still work. This assumes that vec[0] does not + // need to grow its allocation. + expected += sizeof(int); vec[0].push_back(1); - EXPECT_EQ(allocated, sizeof(int) * 4 + sizeof(StdVector) * 8); + EXPECT_EQ(allocated, expected); vec.clear(); EXPECT_EQ(allocated, 0);
diff --git a/absl/container/internal/hash_generator_testing.cc b/absl/container/internal/hash_generator_testing.cc index 0d6a9df..e0fefbf 100644 --- a/absl/container/internal/hash_generator_testing.cc +++ b/absl/container/internal/hash_generator_testing.cc
@@ -39,9 +39,9 @@ } // namespace -std::mt19937_64* GetThreadLocalRng() { +std::mt19937_64* GetSharedRng() { RandomDeviceSeedSeq seed_seq; - thread_local auto* rng = new std::mt19937_64(seed_seq); + static auto* rng = new std::mt19937_64(seed_seq); return rng; } @@ -51,7 +51,7 @@ std::string res; res.resize(32); std::generate(res.begin(), res.end(), - [&]() { return chars(*GetThreadLocalRng()); }); + [&]() { return chars(*GetSharedRng()); }); return res; } @@ -63,7 +63,7 @@ auto& res = arena->back(); res.resize(32); std::generate(res.begin(), res.end(), - [&]() { return chars(*GetThreadLocalRng()); }); + [&]() { return chars(*GetSharedRng()); }); return res; }
diff --git a/absl/container/internal/hash_generator_testing.h b/absl/container/internal/hash_generator_testing.h index 50d7710..6521efe 100644 --- a/absl/container/internal/hash_generator_testing.h +++ b/absl/container/internal/hash_generator_testing.h
@@ -43,7 +43,7 @@ } // namespace generator_internal -std::mt19937_64* GetThreadLocalRng(); +std::mt19937_64* GetSharedRng(); enum Enum { kEnumEmpty, @@ -66,7 +66,7 @@ struct Generator<T, typename std::enable_if<std::is_integral<T>::value>::type> { T operator()() const { std::uniform_int_distribution<T> dist; - return dist(*GetThreadLocalRng()); + return dist(*GetSharedRng()); } }; @@ -76,7 +76,7 @@ std::uniform_int_distribution<typename std::underlying_type<Enum>::type> dist; while (true) { - auto variate = dist(*GetThreadLocalRng()); + auto variate = dist(*GetSharedRng()); if (variate != kEnumEmpty && variate != kEnumDeleted) return static_cast<Enum>(variate); } @@ -90,7 +90,7 @@ typename std::underlying_type<EnumClass>::type> dist; while (true) { - EnumClass variate = static_cast<EnumClass>(dist(*GetThreadLocalRng())); + EnumClass variate = static_cast<EnumClass>(dist(*GetSharedRng())); if (variate != EnumClass::kEmpty && variate != EnumClass::kDeleted) return static_cast<EnumClass>(variate); }
diff --git a/absl/container/internal/hash_policy_testing.h b/absl/container/internal/hash_policy_testing.h index ffc76ea..7fb819a 100644 --- a/absl/container/internal/hash_policy_testing.h +++ b/absl/container/internal/hash_policy_testing.h
@@ -139,7 +139,7 @@ friend bool operator!=(const Alloc& a, const Alloc& b) { return !(a == b); } private: - size_t id_ = std::numeric_limits<size_t>::max(); + size_t id_ = (std::numeric_limits<size_t>::max)(); }; template <class Map> @@ -169,7 +169,11 @@ // take allocator arguments. This test is defined ad-hoc for the platforms // we care about (notably Crosstool 17) because libstdcxx's useless // versioning scheme precludes a more principled solution. -#if defined(__GLIBCXX__) && __GLIBCXX__ <= 20140425 +// From GCC-4.9 Changelog: (src: https://gcc.gnu.org/gcc-4.9/changes.html) +// "the unordered associative containers in <unordered_map> and <unordered_set> +// meet the allocator-aware container requirements;" +#if (defined(__GLIBCXX__) && __GLIBCXX__ <= 20140425 ) || \ +( __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 9 )) #define ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS 0 #else #define ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS 1
diff --git a/absl/container/internal/hash_policy_traits.h b/absl/container/internal/hash_policy_traits.h index 029e47e..ace50a6 100644 --- a/absl/container/internal/hash_policy_traits.h +++ b/absl/container/internal/hash_policy_traits.h
@@ -84,7 +84,7 @@ } // Transfers the `old_slot` to `new_slot`. Any memory allocated by the - // allocator inside `old_slot` to `new_slot` can be transfered. + // allocator inside `old_slot` to `new_slot` can be transferred. // // OPTIONAL: defaults to: //
diff --git a/absl/container/internal/hashtable_debug.h b/absl/container/internal/hashtable_debug.h index c3bd65c..38050c6 100644 --- a/absl/container/internal/hashtable_debug.h +++ b/absl/container/internal/hashtable_debug.h
@@ -60,7 +60,7 @@ size_t num_probes = GetHashtableDebugNumProbes( container, absl::container_internal::hashtable_debug_internal::GetKey<C>(*it, 0)); - v.resize(std::max(v.size(), num_probes + 1)); + v.resize((std::max)(v.size(), num_probes + 1)); v[num_probes]++; } return v;
diff --git a/absl/container/internal/layout.h b/absl/container/internal/layout.h index 676c7d6..3d21ac9 100644 --- a/absl/container/internal/layout.h +++ b/absl/container/internal/layout.h
@@ -232,13 +232,17 @@ template <class T, size_t N> struct SizeOf<Aligned<T, N>> : std::integral_constant<size_t, sizeof(T)> {}; +// Note: workaround for https://gcc.gnu.org/PR88115 template <class T> -struct AlignOf : NotAligned<T>, std::integral_constant<size_t, alignof(T)> {}; +struct AlignOf : NotAligned<T> { + static constexpr size_t value = alignof(T); +}; template <class T, size_t N> -struct AlignOf<Aligned<T, N>> : std::integral_constant<size_t, N> { +struct AlignOf<Aligned<T, N>> { static_assert(N % alignof(T) == 0, "Custom alignment can't be lower than the type's alignment"); + static constexpr size_t value = N; }; // Does `Ts...` contain `T`? @@ -249,8 +253,10 @@ using CopyConst = typename std::conditional<std::is_const<From>::value, const To, To>::type; +// Note: We're not qualifying this with absl:: because it doesn't compile under +// MSVC. template <class T> -using SliceType = absl::Span<T>; +using SliceType = Span<T>; // This namespace contains no types. It prevents functions defined in it from // being found by ADL. @@ -290,7 +296,7 @@ #ifdef ABSL_INTERNAL_HAS_CXA_DEMANGLE demangled = abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status); #endif - if (status == 0 && demangled != nullptr) { // Demangling succeeeded. + if (status == 0 && demangled != nullptr) { // Demangling succeeded. absl::StrAppend(&out, "<", demangled, ">"); free(demangled); } else { @@ -396,7 +402,7 @@ static_assert(N < NumOffsets, "Index out of bounds"); return adl_barrier::Align( Offset<N - 1>() + SizeOf<ElementType<N - 1>>() * size_[N - 1], - ElementAlignment<N>()); + ElementAlignment<N>::value); } // Offset in bytes of the array with the specified element type. There must @@ -445,7 +451,7 @@ return Size<ElementIndex<T>()>(); } - // The number of elements of all arrays for which they are known. + // The number of elements of all arrays for which they are known. constexpr std::array<size_t, NumSizes> Sizes() const { return {{Size<SizeSeq>()...}}; } @@ -610,7 +616,7 @@ #ifdef ADDRESS_SANITIZER PoisonPadding<Char, N - 1>(p); // The `if` is an optimization. It doesn't affect the observable behaviour. - if (ElementAlignment<N - 1>() % ElementAlignment<N>()) { + if (ElementAlignment<N - 1>::value % ElementAlignment<N>::value) { size_t start = Offset<N - 1>() + SizeOf<ElementType<N - 1>>() * size_[N - 1]; ASAN_POISON_MEMORY_REGION(p + start, Offset<N>() - start); @@ -690,7 +696,7 @@ // // It's allowed to pass fewer array sizes than the number of arrays. E.g., // if all you need is to the offset of the second array, you only need to - // pass one argument -- the number of elements in the first arrays. + // pass one argument -- the number of elements in the first array. // // // int[3] followed by 4 bytes of padding and an unknown number of // // doubles.
diff --git a/absl/container/internal/layout_test.cc b/absl/container/internal/layout_test.cc index f35157a..301e9f7 100644 --- a/absl/container/internal/layout_test.cc +++ b/absl/container/internal/layout_test.cc
@@ -45,7 +45,25 @@ return val; } -using Int128 = int64_t[2]; +// Helper classes to test different size and alignments. +struct alignas(8) Int128 { + uint64_t a, b; + friend bool operator==(Int128 lhs, Int128 rhs) { + return std::tie(lhs.a, lhs.b) == std::tie(rhs.a, rhs.b); + } + + static std::string Name() { + return internal_layout::adl_barrier::TypeName<Int128>(); + } +}; + +// int64_t is *not* 8-byte aligned on all platforms! +struct alignas(8) Int64 { + int64_t a; + friend bool operator==(Int64 lhs, Int64 rhs) { + return lhs.a == rhs.a; + } +}; // Properties of types that this test relies on. static_assert(sizeof(int8_t) == 1, ""); @@ -54,6 +72,8 @@ static_assert(alignof(int16_t) == 2, ""); static_assert(sizeof(int32_t) == 4, ""); static_assert(alignof(int32_t) == 4, ""); +static_assert(sizeof(Int64) == 8, ""); +static_assert(alignof(Int64) == 8, ""); static_assert(sizeof(Int128) == 16, ""); static_assert(alignof(Int128) == 8, ""); @@ -1271,14 +1291,14 @@ TEST(Layout, Alignment) { static_assert(Layout<int8_t>::Alignment() == 1, ""); static_assert(Layout<int32_t>::Alignment() == 4, ""); - static_assert(Layout<int64_t>::Alignment() == 8, ""); + static_assert(Layout<Int64>::Alignment() == 8, ""); static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64, ""); - static_assert(Layout<int8_t, int32_t, int64_t>::Alignment() == 8, ""); - static_assert(Layout<int8_t, int64_t, int32_t>::Alignment() == 8, ""); - static_assert(Layout<int32_t, int8_t, int64_t>::Alignment() == 8, ""); - static_assert(Layout<int32_t, int64_t, int8_t>::Alignment() == 8, ""); - static_assert(Layout<int64_t, int8_t, int32_t>::Alignment() == 8, ""); - static_assert(Layout<int64_t, int32_t, int8_t>::Alignment() == 8, ""); + static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8, ""); + static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8, ""); + static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8, ""); + static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8, ""); + static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8, ""); + static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, ""); } TEST(Layout, ConstexprPartial) { @@ -1313,7 +1333,7 @@ } TEST(Layout, PoisonPadding) { - using L = Layout<int8_t, int64_t, int32_t, Int128>; + using L = Layout<int8_t, Int64, int32_t, Int128>; constexpr size_t n = L::Partial(1, 2, 3, 4).AllocSize(); { @@ -1361,12 +1381,6 @@ } TEST(Layout, DebugString) { - const std::string int64_type = -#ifdef _MSC_VER - "__int64"; -#else // _MSC_VER - std::is_same<int64_t, long long>::value ? "long long" : "long"; // NOLINT -#endif // _MSC_VER { constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(); EXPECT_EQ("@0<signed char>(1)", x.DebugString()); @@ -1384,24 +1398,24 @@ constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3); EXPECT_EQ( "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; " - "@16<" + - int64_type + " [2]>(16)", + "@16" + + Int128::Name() + "(16)", x.DebugString()); } { constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3, 4); EXPECT_EQ( "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; " - "@16<" + - int64_type + " [2]>(16)[4]", + "@16" + + Int128::Name() + "(16)[4]", x.DebugString()); } { constexpr Layout<int8_t, int32_t, int8_t, Int128> x(1, 2, 3, 4); EXPECT_EQ( "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; " - "@16<" + - int64_type + " [2]>(16)[4]", + "@16" + + Int128::Name() + "(16)[4]", x.DebugString()); } } @@ -1528,8 +1542,7 @@ const char* c_str() const { // Equivalent to reinterpret_cast<char*>(p.get() + sizeof(size_t)). // The argument in Partial(1) specifies that we have size_t[1] in front of - // the - // characters. + // the characters. return L::Partial(1).Pointer<char>(p_.get()); }
diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h index 1edc007..05270ef 100644 --- a/absl/container/internal/raw_hash_map.h +++ b/absl/container/internal/raw_hash_map.h
@@ -39,11 +39,14 @@ using MappedConstReference = decltype(P::value( std::addressof(std::declval<typename raw_hash_map::const_reference>()))); + using KeyArgImpl = container_internal::KeyArg<IsTransparent<Eq>::value && + IsTransparent<Hash>::value>; + public: using key_type = typename Policy::key_type; using mapped_type = typename Policy::mapped_type; - template <typename K> - using key_arg = typename raw_hash_map::raw_hash_set::template key_arg<K>; + template <class K> + using key_arg = typename KeyArgImpl::template type<K, key_type>; static_assert(!std::is_reference<key_type>::value, ""); // TODO(alkis): remove this assertion and verify that reference mapped_type is
diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc index 1015312..180d3fe 100644 --- a/absl/container/internal/raw_hash_set.cc +++ b/absl/container/internal/raw_hash_set.cc
@@ -14,6 +14,7 @@ #include "absl/container/internal/raw_hash_set.h" +#include <atomic> #include <cstddef> #include "absl/base/config.h" @@ -29,7 +30,7 @@ static thread_local size_t counter = 0; size_t value = ++counter; #else // ABSL_HAVE_THREAD_LOCAL - static std::atomic<size_t> counter; + static std::atomic<size_t> counter(0); size_t value = counter.fetch_add(1, std::memory_order_relaxed); #endif // ABSL_HAVE_THREAD_LOCAL return value ^ static_cast<size_t>(reinterpret_cast<uintptr_t>(&counter));
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 70da90f..029540d 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h
@@ -92,7 +92,9 @@ #define ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_ #ifndef SWISSTABLE_HAVE_SSE2 -#ifdef __SSE2__ +#if defined(__SSE2__) || \ + (defined(_MSC_VER) && \ + (defined(_M_X64) || (defined(_M_IX86) && _M_IX86_FP >= 2))) #define SWISSTABLE_HAVE_SSE2 1 #else #define SWISSTABLE_HAVE_SSE2 0 @@ -112,7 +114,11 @@ #endif #if SWISSTABLE_HAVE_SSE2 -#include <x86intrin.h> +#include <emmintrin.h> +#endif + +#if SWISSTABLE_HAVE_SSSE3 +#include <tmmintrin.h> #endif #include <algorithm> @@ -202,14 +208,17 @@ template <typename T> int TrailingZeros(T x) { - return sizeof(T) == 8 ? base_internal::CountTrailingZerosNonZero64(x) - : base_internal::CountTrailingZerosNonZero32(x); + return sizeof(T) == 8 ? base_internal::CountTrailingZerosNonZero64( + static_cast<uint64_t>(x)) + : base_internal::CountTrailingZerosNonZero32( + static_cast<uint32_t>(x)); } template <typename T> int LeadingZeros(T x) { - return sizeof(T) == 8 ? base_internal::CountLeadingZeros64(x) - : base_internal::CountLeadingZeros32(x); + return sizeof(T) == 8 + ? base_internal::CountLeadingZeros64(static_cast<uint64_t>(x)) + : base_internal::CountLeadingZeros32(static_cast<uint32_t>(x)); } // An abstraction over a bitmask. It provides an easy way to iterate through the @@ -337,10 +346,27 @@ inline bool IsEmptyOrDeleted(ctrl_t c) { return c < kSentinel; } #if SWISSTABLE_HAVE_SSE2 -struct Group { + +// https://github.com/abseil/abseil-cpp/issues/209 +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87853 +// _mm_cmpgt_epi8 is broken under GCC with -funsigned-char +// Work around this by using the portable implementation of Group +// when using -funsigned-char under GCC. +inline __m128i _mm_cmpgt_epi8_fixed(__m128i a, __m128i b) { +#if defined(__GNUC__) && !defined(__clang__) + if (std::is_unsigned<char>::value) { + const __m128i mask = _mm_set1_epi8(0x80); + const __m128i diff = _mm_subs_epi8(b, a); + return _mm_cmpeq_epi8(_mm_and_si128(diff, mask), mask); + } +#endif + return _mm_cmpgt_epi8(a, b); +} + +struct GroupSse2Impl { static constexpr size_t kWidth = 16; // the number of slots per group - explicit Group(const ctrl_t* pos) { + explicit GroupSse2Impl(const ctrl_t* pos) { ctrl = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pos)); } @@ -366,23 +392,24 @@ BitMask<uint32_t, kWidth> MatchEmptyOrDeleted() const { auto special = _mm_set1_epi8(kSentinel); return BitMask<uint32_t, kWidth>( - _mm_movemask_epi8(_mm_cmpgt_epi8(special, ctrl))); + _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl))); } // Returns the number of trailing empty or deleted elements in the group. uint32_t CountLeadingEmptyOrDeleted() const { auto special = _mm_set1_epi8(kSentinel); - return TrailingZeros(_mm_movemask_epi8(_mm_cmpgt_epi8(special, ctrl)) + 1); + return TrailingZeros( + _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl)) + 1); } void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const { - auto msbs = _mm_set1_epi8(0x80); + auto msbs = _mm_set1_epi8(static_cast<char>(-128)); auto x126 = _mm_set1_epi8(126); #if SWISSTABLE_HAVE_SSSE3 auto res = _mm_or_si128(_mm_shuffle_epi8(x126, ctrl), msbs); #else auto zero = _mm_setzero_si128(); - auto special_mask = _mm_cmpgt_epi8(zero, ctrl); + auto special_mask = _mm_cmpgt_epi8_fixed(zero, ctrl); auto res = _mm_or_si128(msbs, _mm_andnot_si128(special_mask, x126)); #endif _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), res); @@ -390,11 +417,13 @@ __m128i ctrl; }; -#else -struct Group { +#endif // SWISSTABLE_HAVE_SSE2 + +struct GroupPortableImpl { static constexpr size_t kWidth = 8; - explicit Group(const ctrl_t* pos) : ctrl(little_endian::Load64(pos)) {} + explicit GroupPortableImpl(const ctrl_t* pos) + : ctrl(little_endian::Load64(pos)) {} BitMask<uint64_t, kWidth, 3> Match(h2_t hash) const { // For the technique, see: @@ -441,12 +470,16 @@ uint64_t ctrl; }; -#endif // SWISSTABLE_HAVE_SSE2 + +#if SWISSTABLE_HAVE_SSE2 +using Group = GroupSse2Impl; +#else +using Group = GroupPortableImpl; +#endif template <class Policy, class Hash, class Eq, class Alloc> class raw_hash_set; - inline bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n >= Group::kWidth - 1; } @@ -477,7 +510,7 @@ constexpr size_t kMinCapacity = Group::kWidth - 1; return n <= kMinCapacity ? kMinCapacity - : std::numeric_limits<size_t>::max() >> LeadingZeros(n); + : (std::numeric_limits<size_t>::max)() >> LeadingZeros(n); } // The node_handle concept from C++17. @@ -662,7 +695,7 @@ allocator_type>::template rebind_traits<value_type>::const_pointer; // Alias used for heterogeneous lookup functions. - // `key_arg<K>` evaluates to `K` when the functors are tranparent and to + // `key_arg<K>` evaluates to `K` when the functors are transparent and to // `key_type` otherwise. It permits template argument deduction on `K` for the // transparent case. template <class K> @@ -1022,7 +1055,7 @@ bool empty() const { return !size(); } size_t size() const { return size_; } size_t capacity() const { return capacity_; } - size_t max_size() const { return std::numeric_limits<size_t>::max(); } + size_t max_size() const { return (std::numeric_limits<size_t>::max)(); } void clear() { // Iterating over this container is O(bucket_count()). When bucket_count() @@ -1330,7 +1363,7 @@ void rehash(size_t n) { if (n == 0 && capacity_ == 0) return; if (n == 0 && size_ == 0) return destroy_slots(); - auto m = NormalizeCapacity(std::max(n, NumSlotsFast(size()))); + auto m = NormalizeCapacity((std::max)(n, NumSlotsFast(size()))); // n == 0 unconditionally rehashes as per the standard. if (n == 0 || m > capacity_) { resize(m);
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index cd33a3a..5ad4904 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc
@@ -14,7 +14,6 @@ #include "absl/container/internal/raw_hash_set.h" -#include <array> #include <cmath> #include <cstdint> #include <deque> @@ -130,45 +129,50 @@ for (h2_t h = 0; h != 128; ++h) EXPECT_FALSE(Group{EmptyGroup()}.Match(h)); } -#if SWISSTABLE_HAVE_SSE2 TEST(Group, Match) { - ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7, - 7, 5, 3, 1, 1, 1, 1, 1}; - EXPECT_THAT(Group{group}.Match(0), ElementsAre()); - EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 11, 12, 13, 14, 15)); - EXPECT_THAT(Group{group}.Match(3), ElementsAre(3, 10)); - EXPECT_THAT(Group{group}.Match(5), ElementsAre(5, 9)); - EXPECT_THAT(Group{group}.Match(7), ElementsAre(7, 8)); + if (Group::kWidth == 16) { + ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7, + 7, 5, 3, 1, 1, 1, 1, 1}; + EXPECT_THAT(Group{group}.Match(0), ElementsAre()); + EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 11, 12, 13, 14, 15)); + EXPECT_THAT(Group{group}.Match(3), ElementsAre(3, 10)); + EXPECT_THAT(Group{group}.Match(5), ElementsAre(5, 9)); + EXPECT_THAT(Group{group}.Match(7), ElementsAre(7, 8)); + } else if (Group::kWidth == 8) { + ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1}; + EXPECT_THAT(Group{group}.Match(0), ElementsAre()); + EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 5, 7)); + EXPECT_THAT(Group{group}.Match(2), ElementsAre(2, 4)); + } else { + FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth; + } } TEST(Group, MatchEmpty) { - ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7, - 7, 5, 3, 1, 1, 1, 1, 1}; - EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0, 4)); + if (Group::kWidth == 16) { + ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7, + 7, 5, 3, 1, 1, 1, 1, 1}; + EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0, 4)); + } else if (Group::kWidth == 8) { + ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1}; + EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0)); + } else { + FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth; + } } TEST(Group, MatchEmptyOrDeleted) { - ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7, - 7, 5, 3, 1, 1, 1, 1, 1}; - EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 2, 4)); + if (Group::kWidth == 16) { + ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7, + 7, 5, 3, 1, 1, 1, 1, 1}; + EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 2, 4)); + } else if (Group::kWidth == 8) { + ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1}; + EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 3)); + } else { + FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth; + } } -#else -TEST(Group, Match) { - ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1}; - EXPECT_THAT(Group{group}.Match(0), ElementsAre()); - EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 5, 7)); - EXPECT_THAT(Group{group}.Match(2), ElementsAre(2, 4)); -} -TEST(Group, MatchEmpty) { - ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1}; - EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0)); -} - -TEST(Group, MatchEmptyOrDeleted) { - ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1}; - EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 3)); -} -#endif TEST(Batch, DropDeletes) { constexpr size_t kCapacity = 63; @@ -386,7 +390,8 @@ !defined(UNDEFINED_BEHAVIOR_SANITIZER) const auto now = [] { return absl::base_internal::CycleClock::Now(); }; - static constexpr int size = 1000000; + // Make size enough to not fit in L2 cache (16.7 Mb) + static constexpr int size = 1 << 22; for (int i = 0; i < size; ++i) t.insert(i); int64_t no_prefetch = 0, prefetch = 0; @@ -687,7 +692,7 @@ Modulo1000HashTable t; // Adding the same length (and the same hash) strings // to have at least kMinFullGroups groups - // with Group::kWidth collisions. Then feel upto MaxDensitySize; + // with Group::kWidth collisions. Then fill up to MaxDensitySize; const size_t kMinFullGroups = 7; std::vector<int> keys; for (size_t i = 0; i < MaxDensitySize(Group::kWidth * kMinFullGroups); ++i) { @@ -1029,7 +1034,6 @@ {{0.95, 0.1}}, {{0.95, 0}, {0.99, 2}, {0.999, 4}, {0.9999, 10}}}; } - break; case 16: if (kRandomizesInserts) { return {0.1, @@ -1042,10 +1046,8 @@ {{0.95, 0.05}}, {{0.95, 0}, {0.99, 1}, {0.999, 4}, {0.9999, 10}}}; } - break; - default: - ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width"); } + ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width"); return {}; } TEST(Table, DISABLED_EnsureNonQuadraticTopNXorSeedByProbeSeqLength) { @@ -1125,7 +1127,6 @@ {{0.95, 0.3}}, {{0.95, 0}, {0.99, 3}, {0.999, 15}, {0.9999, 25}}}; } - break; case 16: if (kRandomizesInserts) { return {0.1, @@ -1138,10 +1139,8 @@ {{0.95, 0.1}}, {{0.95, 0}, {0.99, 1}, {0.999, 6}, {0.9999, 10}}}; } - break; - default: - ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width"); } + ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width"); return {}; } TEST(Table, DISABLED_EnsureNonQuadraticTopNLinearTransformByProbeSeqLength) { @@ -1783,138 +1782,6 @@ FAIL() << "Iteration order remained the same across many attempts."; } -// Fill the table to 3 different load factors (min, median, max) and evaluate -// the percentage of perfect hits using the debug API. -template <class Table, class AddFn> -std::vector<double> CollectPerfectRatios(Table t, AddFn add) { - using Key = typename Table::key_type; - - // First, fill enough to have a good distribution. - constexpr size_t kMinSize = 10000; - std::vector<Key> keys; - while (t.size() < kMinSize) keys.push_back(add(t)); - // Then, insert until we reach min load factor. - double lf = t.load_factor(); - while (lf <= t.load_factor()) keys.push_back(add(t)); - - // We are now at min load factor. Take a snapshot. - size_t perfect = 0; - auto update_perfect = [&](Key k) { - perfect += GetHashtableDebugNumProbes(t, k) == 0; - }; - for (const auto& k : keys) update_perfect(k); - - std::vector<double> perfect_ratios; - // Keep going until we hit max load factor. - while (t.load_factor() < .6) { - perfect_ratios.push_back(1.0 * perfect / t.size()); - update_perfect(add(t)); - } - while (t.load_factor() > .5) { - perfect_ratios.push_back(1.0 * perfect / t.size()); - update_perfect(add(t)); - } - return perfect_ratios; -} - -std::vector<std::pair<double, double>> StringTablePefectRatios() { - constexpr bool kRandomizesInserts = -#if NDEBUG - false; -#else // NDEBUG - true; -#endif // NDEBUG - - // The effective load factor is larger in non-opt mode because we insert - // elements out of order. - switch (container_internal::Group::kWidth) { - case 8: - if (kRandomizesInserts) { - return {{0.986, 0.02}, {0.95, 0.02}, {0.89, 0.02}}; - } else { - return {{0.995, 0.01}, {0.97, 0.01}, {0.89, 0.02}}; - } - break; - case 16: - if (kRandomizesInserts) { - return {{0.973, 0.01}, {0.965, 0.01}, {0.92, 0.02}}; - } else { - return {{0.995, 0.005}, {0.99, 0.005}, {0.94, 0.01}}; - } - break; - default: - // Ignore anything else. - return {}; - } -} - -// This is almost a change detector, but it allows us to know how we are -// affecting the probe distribution. -TEST(Table, EffectiveLoadFactorStrings) { - std::vector<double> perfect_ratios = - CollectPerfectRatios(StringTable(), [](StringTable& t) { - return t.emplace(std::to_string(t.size()), "").first->first; - }); - - auto ratios = StringTablePefectRatios(); - if (ratios.empty()) return; - - EXPECT_THAT(perfect_ratios.front(), - DoubleNear(ratios[0].first, ratios[0].second)); - EXPECT_THAT(perfect_ratios[perfect_ratios.size() / 2], - DoubleNear(ratios[1].first, ratios[1].second)); - EXPECT_THAT(perfect_ratios.back(), - DoubleNear(ratios[2].first, ratios[2].second)); -} - -std::vector<std::pair<double, double>> IntTablePefectRatios() { - constexpr bool kRandomizesInserts = -#ifdef NDEBUG - false; -#else // NDEBUG - true; -#endif // NDEBUG - - // The effective load factor is larger in non-opt mode because we insert - // elements out of order. - switch (container_internal::Group::kWidth) { - case 8: - if (kRandomizesInserts) { - return {{0.99, 0.02}, {0.985, 0.02}, {0.95, 0.05}}; - } else { - return {{0.99, 0.01}, {0.99, 0.01}, {0.95, 0.02}}; - } - break; - case 16: - if (kRandomizesInserts) { - return {{0.98, 0.02}, {0.978, 0.02}, {0.96, 0.02}}; - } else { - return {{0.998, 0.003}, {0.995, 0.01}, {0.975, 0.02}}; - } - break; - default: - // Ignore anything else. - return {}; - } -} - -// This is almost a change detector, but it allows us to know how we are -// affecting the probe distribution. -TEST(Table, EffectiveLoadFactorInts) { - std::vector<double> perfect_ratios = CollectPerfectRatios( - IntTable(), [](IntTable& t) { return *t.emplace(t.size()).first; }); - - auto ratios = IntTablePefectRatios(); - if (ratios.empty()) return; - - EXPECT_THAT(perfect_ratios.front(), - DoubleNear(ratios[0].first, ratios[0].second)); - EXPECT_THAT(perfect_ratios[perfect_ratios.size() / 2], - DoubleNear(ratios[1].first, ratios[1].second)); - EXPECT_THAT(perfect_ratios.back(), - DoubleNear(ratios[2].first, ratios[2].second)); -} - // Confirm that we assert if we try to erase() end(). TEST(TableDeathTest, EraseOfEndAsserts) { // Use an assert with side-effects to figure out if they are actually enabled.
diff --git a/absl/container/internal/unordered_map_constructor_test.h b/absl/container/internal/unordered_map_constructor_test.h index 2ffb646..87d6c3c 100644 --- a/absl/container/internal/unordered_map_constructor_test.h +++ b/absl/container/internal/unordered_map_constructor_test.h
@@ -401,4 +401,5 @@ } // namespace container_internal } // namespace absl + #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_CONSTRUCTOR_TEST_H_
diff --git a/absl/container/internal/unordered_map_lookup_test.h b/absl/container/internal/unordered_map_lookup_test.h index 1f1b6b4..a3d2159 100644 --- a/absl/container/internal/unordered_map_lookup_test.h +++ b/absl/container/internal/unordered_map_lookup_test.h
@@ -111,4 +111,5 @@ } // namespace container_internal } // namespace absl + #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_LOOKUP_TEST_H_
diff --git a/absl/container/internal/unordered_map_modifiers_test.h b/absl/container/internal/unordered_map_modifiers_test.h index b6c633a..61ae7d6 100644 --- a/absl/container/internal/unordered_map_modifiers_test.h +++ b/absl/container/internal/unordered_map_modifiers_test.h
@@ -269,4 +269,5 @@ } // namespace container_internal } // namespace absl + #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MODIFIERS_TEST_H_
diff --git a/absl/container/internal/unordered_set_constructor_test.h b/absl/container/internal/unordered_set_constructor_test.h index cb59370..9516e5b 100644 --- a/absl/container/internal/unordered_set_constructor_test.h +++ b/absl/container/internal/unordered_set_constructor_test.h
@@ -405,4 +405,5 @@ } // namespace container_internal } // namespace absl + #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_CONSTRUCTOR_TEST_H_
diff --git a/absl/container/internal/unordered_set_lookup_test.h b/absl/container/internal/unordered_set_lookup_test.h index aca9c6a..1421e7b 100644 --- a/absl/container/internal/unordered_set_lookup_test.h +++ b/absl/container/internal/unordered_set_lookup_test.h
@@ -85,4 +85,5 @@ } // namespace container_internal } // namespace absl + #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_LOOKUP_TEST_H_
diff --git a/absl/container/internal/unordered_set_modifiers_test.h b/absl/container/internal/unordered_set_modifiers_test.h index 9beacf3..445dcec 100644 --- a/absl/container/internal/unordered_set_modifiers_test.h +++ b/absl/container/internal/unordered_set_modifiers_test.h
@@ -184,4 +184,5 @@ } // namespace container_internal } // namespace absl + #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MODIFIERS_TEST_H_
diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h index 6369ec3..bd53c59 100644 --- a/absl/container/node_hash_map.h +++ b/absl/container/node_hash_map.h
@@ -40,6 +40,7 @@ #include <type_traits> #include <utility> +#include "absl/algorithm/container.h" #include "absl/container/internal/container_memory.h" #include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/node_hash_policy.h" @@ -71,7 +72,7 @@ // By default, `node_hash_map` uses the `absl::Hash` hashing framework. // All fundamental and Abseil types that support the `absl::Hash` framework have // a compatible equality operator for comparing insertions into `node_hash_map`. -// If your type is not yet supported by the `asbl::Hash` framework, see +// If your type is not yet supported by the `absl::Hash` framework, see // absl/hash/hash.h for information on extending Abseil hashing to user-defined // types. // @@ -91,7 +92,7 @@ // std::string search_key = "b"; // auto result = ducks.find(search_key); // if (result != ducks.end()) { -// std::cout << "Result: " << search_key->second << std::endl; +// std::cout << "Result: " << result->second << std::endl; // } template <class Key, class Value, class Hash = absl::container_internal::hash_default_hash<Key>, @@ -104,6 +105,46 @@ using Base = typename node_hash_map::raw_hash_map; public: + // Constructors and Assignment Operators + // + // A node_hash_map supports the same overload set as `std::unordered_map` + // for construction and assignment: + // + // * Default constructor + // + // // No allocation for the table's elements is made. + // absl::node_hash_map<int, std::string> map1; + // + // * Initializer List constructor + // + // absl::node_hash_map<int, std::string> map2 = + // {{1, "huey"}, {2, "dewey"}, {3, "louie"},}; + // + // * Copy constructor + // + // absl::node_hash_map<int, std::string> map3(map2); + // + // * Copy assignment operator + // + // // Hash functor and Comparator are copied as well + // absl::node_hash_map<int, std::string> map4; + // map4 = map3; + // + // * Move constructor + // + // // Move is guaranteed efficient + // absl::node_hash_map<int, std::string> map5(std::move(map4)); + // + // * Move assignment operator + // + // // May be efficient if allocators are compatible + // absl::node_hash_map<int, std::string> map6; + // map6 = std::move(map5); + // + // * Range constructor + // + // std::vector<std::pair<int, std::string>> v = {{1, "a"}, {2, "b"}}; + // absl::node_hash_map<int, std::string> map7(v.begin(), v.end()); node_hash_map() {} using Base::Base; @@ -526,5 +567,16 @@ static const Value& value(const value_type* elem) { return elem->second; } }; } // namespace container_internal + +namespace container_algorithm_internal { + +// Specialization of trait in absl/algorithm/container.h +template <class Key, class T, class Hash, class KeyEqual, class Allocator> +struct IsUnorderedContainer< + absl::node_hash_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type {}; + +} // namespace container_algorithm_internal + } // namespace absl + #endif // ABSL_CONTAINER_NODE_HASH_MAP_H_
diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h index 90d4ce0..843b11a 100644 --- a/absl/container/node_hash_set.h +++ b/absl/container/node_hash_set.h
@@ -37,6 +37,7 @@ #include <type_traits> +#include "absl/algorithm/container.h" #include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/node_hash_policy.h" #include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export @@ -67,7 +68,7 @@ // By default, `node_hash_set` uses the `absl::Hash` hashing framework. // All fundamental and Abseil types that support the `absl::Hash` framework have // a compatible equality operator for comparing insertions into `node_hash_set`. -// If your type is not yet supported by the `asbl::Hash` framework, see +// If your type is not yet supported by the `absl::Hash` framework, see // absl/hash/hash.h for information on extending Abseil hashing to user-defined // types. // @@ -96,6 +97,46 @@ using Base = typename node_hash_set::raw_hash_set; public: + // Constructors and Assignment Operators + // + // A node_hash_set supports the same overload set as `std::unordered_map` + // for construction and assignment: + // + // * Default constructor + // + // // No allocation for the table's elements is made. + // absl::node_hash_set<std::string> set1; + // + // * Initializer List constructor + // + // absl::node_hash_set<std::string> set2 = + // {{"huey"}, {"dewey"}, {"louie"},}; + // + // * Copy constructor + // + // absl::node_hash_set<std::string> set3(set2); + // + // * Copy assignment operator + // + // // Hash functor and Comparator are copied as well + // absl::node_hash_set<std::string> set4; + // set4 = set3; + // + // * Move constructor + // + // // Move is guaranteed efficient + // absl::node_hash_set<std::string> set5(std::move(set4)); + // + // * Move assignment operator + // + // // May be efficient if allocators are compatible + // absl::node_hash_set<std::string> set6; + // set6 = std::move(set5); + // + // * Range constructor + // + // std::vector<std::string> v = {"a", "b"}; + // absl::node_hash_set<std::string> set7(v.begin(), v.end()); node_hash_set() {} using Base::Base; @@ -232,8 +273,7 @@ // // The element may be constructed even if there already is an element with the // key in the container, in which case the newly constructed element will be - // destroyed immediately. Prefer `try_emplace()` unless your key is not - // copyable or moveable. + // destroyed immediately. // // If rehashing occurs due to the insertion, all iterators are invalidated. using Base::emplace; @@ -247,8 +287,7 @@ // // The element may be constructed even if there already is an element with the // key in the container, in which case the newly constructed element will be - // destroyed immediately. Prefer `try_emplace()` unless your key is not - // copyable or moveable. + // destroyed immediately. // // If rehashing occurs due to the insertion, all iterators are invalidated. using Base::emplace_hint; @@ -435,5 +474,15 @@ static size_t element_space_used(const T*) { return sizeof(T); } }; } // namespace container_internal + +namespace container_algorithm_internal { + +// Specialization of trait in absl/algorithm/container.h +template <class Key, class Hash, class KeyEqual, class Allocator> +struct IsUnorderedContainer<absl::node_hash_set<Key, Hash, KeyEqual, Allocator>> + : std::true_type {}; + +} // namespace container_algorithm_internal } // namespace absl + #endif // ABSL_CONTAINER_NODE_HASH_SET_H_
diff --git a/absl/copts.bzl b/absl/copts.bzl deleted file mode 100644 index 5c508f1..0000000 --- a/absl/copts.bzl +++ /dev/null
@@ -1,164 +0,0 @@ -"""absl specific copts. - -Flags specified here must not impact ABI. Code compiled with and without these -opts will be linked together, and in some cases headers compiled with and -without these options will be part of the same program. -""" -GCC_FLAGS = [ - "-Wall", - "-Wextra", - "-Wcast-qual", - "-Wconversion-null", - "-Wmissing-declarations", - "-Woverlength-strings", - "-Wpointer-arith", - "-Wunused-local-typedefs", - "-Wunused-result", - "-Wvarargs", - "-Wvla", # variable-length array - "-Wwrite-strings", - # Google style does not use unsigned integers, though STL containers - # have unsigned types. - "-Wno-sign-compare", -] - -GCC_TEST_FLAGS = [ - "-Wno-conversion-null", - "-Wno-missing-declarations", - "-Wno-sign-compare", - "-Wno-unused-function", - "-Wno-unused-parameter", - "-Wno-unused-private-field", -] - -# Docs on single flags is preceded by a comment. -# Docs on groups of flags is preceded by ###. - -LLVM_FLAGS = [ - "-Wall", - "-Wextra", - "-Weverything", - # Abseil does not support C++98 - "-Wno-c++98-compat-pedantic", - # Turns off all implicit conversion warnings. Most are re-enabled below. - "-Wno-conversion", - "-Wno-covered-switch-default", - "-Wno-deprecated", - "-Wno-disabled-macro-expansion", - "-Wno-double-promotion", - ### - # Turned off as they include valid C++ code. - "-Wno-comma", - "-Wno-extra-semi", - "-Wno-packed", - "-Wno-padded", - ### - # Google style does not use unsigned integers, though STL containers - # have unsigned types. - "-Wno-sign-compare", - ### - "-Wno-float-conversion", - "-Wno-float-equal", - "-Wno-format-nonliteral", - # Too aggressive: warns on Clang extensions enclosed in Clang-only - # compilation paths. - "-Wno-gcc-compat", - ### - # Some internal globals are necessary. Don't do this at home. - "-Wno-global-constructors", - "-Wno-exit-time-destructors", - ### - "-Wno-nested-anon-types", - "-Wno-non-modular-include-in-module", - "-Wno-old-style-cast", - # Warns on preferred usage of non-POD types such as string_view - "-Wno-range-loop-analysis", - "-Wno-reserved-id-macro", - "-Wno-shorten-64-to-32", - "-Wno-switch-enum", - "-Wno-thread-safety-negative", - "-Wno-undef", - "-Wno-unknown-warning-option", - "-Wno-unreachable-code", - # Causes warnings on include guards - "-Wno-unused-macros", - "-Wno-weak-vtables", - ### - # Implicit conversion warnings turned off by -Wno-conversion - # which are re-enabled below. - "-Wbitfield-enum-conversion", - "-Wbool-conversion", - "-Wconstant-conversion", - "-Wenum-conversion", - "-Wint-conversion", - "-Wliteral-conversion", - "-Wnon-literal-null-conversion", - "-Wnull-conversion", - "-Wobjc-literal-conversion", - "-Wno-sign-conversion", - "-Wstring-conversion", - ### -] - -LLVM_TEST_FLAGS = [ - "-Wno-c99-extensions", - "-Wno-missing-noreturn", - "-Wno-missing-prototypes", - "-Wno-missing-variable-declarations", - "-Wno-null-conversion", - "-Wno-shadow", - "-Wno-shift-sign-overflow", - "-Wno-sign-compare", - "-Wno-unused-function", - "-Wno-unused-member-function", - "-Wno-unused-parameter", - "-Wno-unused-private-field", - "-Wno-unused-template", - "-Wno-used-but-marked-unused", - "-Wno-zero-as-null-pointer-constant", - # gtest depends on this GNU extension being offered. - "-Wno-gnu-zero-variadic-macro-arguments", -] - -MSVC_FLAGS = [ - "/W3", - "/wd4005", # macro-redefinition - "/wd4068", # unknown pragma - "/wd4180", # qualifier applied to function type has no meaning; ignored - "/wd4244", # conversion from 'type1' to 'type2', possible loss of data - "/wd4267", # conversion from 'size_t' to 'type', possible loss of data - "/wd4800", # forcing value to bool 'true' or 'false' (performance warning) - "/DNOMINMAX", # Don't define min and max macros (windows.h) - "/DWIN32_LEAN_AND_MEAN", # Don't bloat namespace with incompatible winsock versions. - "/D_CRT_SECURE_NO_WARNINGS", # Don't warn about usage of insecure C functions -] - -MSVC_TEST_FLAGS = [ - "/wd4018", # signed/unsigned mismatch - "/wd4101", # unreferenced local variable - "/wd4503", # decorated name length exceeded, name was truncated -] - -# /Wall with msvc includes unhelpful warnings such as C4711, C4710, ... -ABSL_DEFAULT_COPTS = select({ - "//absl:windows": MSVC_FLAGS, - "//absl:llvm_compiler": LLVM_FLAGS, - "//conditions:default": GCC_FLAGS, -}) - -# in absence of modules (--compiler=gcc or -c opt), cc_tests leak their copts -# to their (included header) dependencies and fail to build outside absl -ABSL_TEST_COPTS = ABSL_DEFAULT_COPTS + select({ - "//absl:windows": MSVC_TEST_FLAGS, - "//absl:llvm_compiler": LLVM_TEST_FLAGS, - "//conditions:default": GCC_TEST_FLAGS, -}) - -ABSL_EXCEPTIONS_FLAG = select({ - "//absl:windows": ["/U_HAS_EXCEPTIONS", "/D_HAS_EXCEPTIONS=1", "/EHsc"], - "//conditions:default": ["-fexceptions"], -}) - -ABSL_EXCEPTIONS_FLAG_LINKOPTS = select({ - "//conditions:default": [], -})
diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake new file mode 100644 index 0000000..6fde775 --- /dev/null +++ b/absl/copts/AbseilConfigureCopts.cmake
@@ -0,0 +1,34 @@ +# See absl/copts/copts.py and absl/copts/generate_copts.py +include(GENERATED_AbseilCopts) + +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(ABSL_DEFAULT_COPTS "${GCC_FLAGS}") + set(ABSL_TEST_COPTS "${GCC_FLAGS};${GCC_TEST_FLAGS}") + set(ABSL_EXCEPTIONS_FLAG "${GCC_EXCEPTIONS_FLAGS}") +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + # MATCHES so we get both Clang and AppleClang + set(ABSL_DEFAULT_COPTS "${LLVM_FLAGS}") + set(ABSL_TEST_COPTS "${LLVM_FLAGS};${LLVM_TEST_FLAGS}") + set(ABSL_EXCEPTIONS_FLAG "${LLVM_EXCEPTIONS_FLAGS}") +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(ABSL_DEFAULT_COPTS "${MSVC_FLAGS}") + set(ABSL_TEST_COPTS "${MSVC_FLAGS};${MSVC_TEST_FLAGS}") + set(ABSL_EXCEPTIONS_FLAG "${MSVC_EXCEPTIONS_FLAGS}") +else() + message(WARNING "Unknown compiler: ${CMAKE_CXX_COMPILER}. Building with no default flags") + set(ABSL_DEFAULT_COPTS "") + set(ABSL_TEST_COPTS "") + set(ABSL_EXCEPTIONS_FLAG "") +endif() + +# This flag is used internally for Bazel builds and is kept here for consistency +set(ABSL_EXCEPTIONS_FLAG_LINKOPTS "") + +if("${CMAKE_CXX_STANDARD}" EQUAL 98) + message(FATAL_ERROR "Abseil requires at least C++11") +elseif(NOT "${CMAKE_CXX_STANDARD}") + message(STATUS "No CMAKE_CXX_STANDARD set, assuming 11") + set(ABSL_CXX_STANDARD 11) +else() + set(ABSL_CXX_STANDARD "${CMAKE_CXX_STANDARD}") +endif() \ No newline at end of file
diff --git a/absl/copts/GENERATED_AbseilCopts.cmake b/absl/copts/GENERATED_AbseilCopts.cmake new file mode 100644 index 0000000..df2c3c0 --- /dev/null +++ b/absl/copts/GENERATED_AbseilCopts.cmake
@@ -0,0 +1,130 @@ +# GENERATED! DO NOT MANUALLY EDIT THIS FILE. +# +# (1) Edit absl/copts/copts.py. +# (2) Run `<path_to_absl>/copts/generate_copts.py`. + +list(APPEND GCC_EXCEPTIONS_FLAGS + "-fexceptions" +) + +list(APPEND GCC_FLAGS + "-Wall" + "-Wextra" + "-Wcast-qual" + "-Wconversion-null" + "-Wmissing-declarations" + "-Woverlength-strings" + "-Wpointer-arith" + "-Wunused-local-typedefs" + "-Wunused-result" + "-Wvarargs" + "-Wvla" + "-Wwrite-strings" + "-Wno-sign-compare" +) + +list(APPEND GCC_TEST_FLAGS + "-Wno-conversion-null" + "-Wno-missing-declarations" + "-Wno-sign-compare" + "-Wno-unused-function" + "-Wno-unused-parameter" + "-Wno-unused-private-field" +) + +list(APPEND LLVM_EXCEPTIONS_FLAGS + "-fexceptions" +) + +list(APPEND LLVM_FLAGS + "-Wall" + "-Wextra" + "-Weverything" + "-Wno-c++98-compat-pedantic" + "-Wno-conversion" + "-Wno-covered-switch-default" + "-Wno-deprecated" + "-Wno-disabled-macro-expansion" + "-Wno-double-promotion" + "-Wno-comma" + "-Wno-extra-semi" + "-Wno-packed" + "-Wno-padded" + "-Wno-sign-compare" + "-Wno-float-conversion" + "-Wno-float-equal" + "-Wno-format-nonliteral" + "-Wno-gcc-compat" + "-Wno-global-constructors" + "-Wno-exit-time-destructors" + "-Wno-nested-anon-types" + "-Wno-non-modular-include-in-module" + "-Wno-old-style-cast" + "-Wno-range-loop-analysis" + "-Wno-reserved-id-macro" + "-Wno-shorten-64-to-32" + "-Wno-switch-enum" + "-Wno-thread-safety-negative" + "-Wno-undef" + "-Wno-unknown-warning-option" + "-Wno-unreachable-code" + "-Wno-unused-macros" + "-Wno-weak-vtables" + "-Wbitfield-enum-conversion" + "-Wbool-conversion" + "-Wconstant-conversion" + "-Wenum-conversion" + "-Wint-conversion" + "-Wliteral-conversion" + "-Wnon-literal-null-conversion" + "-Wnull-conversion" + "-Wobjc-literal-conversion" + "-Wno-sign-conversion" + "-Wstring-conversion" +) + +list(APPEND LLVM_TEST_FLAGS + "-Wno-c99-extensions" + "-Wno-missing-noreturn" + "-Wno-missing-prototypes" + "-Wno-missing-variable-declarations" + "-Wno-null-conversion" + "-Wno-shadow" + "-Wno-shift-sign-overflow" + "-Wno-sign-compare" + "-Wno-unused-function" + "-Wno-unused-member-function" + "-Wno-unused-parameter" + "-Wno-unused-private-field" + "-Wno-unused-template" + "-Wno-used-but-marked-unused" + "-Wno-zero-as-null-pointer-constant" + "-Wno-gnu-zero-variadic-macro-arguments" +) + +list(APPEND MSVC_EXCEPTIONS_FLAGS + "/U_HAS_EXCEPTIONS" + "/D_HAS_EXCEPTIONS=1" + "/EHsc" +) + +list(APPEND MSVC_FLAGS + "/W3" + "/wd4005" + "/wd4068" + "/wd4180" + "/wd4244" + "/wd4267" + "/wd4800" + "/DNOMINMAX" + "/DWIN32_LEAN_AND_MEAN" + "/D_CRT_SECURE_NO_WARNINGS" + "/D_SCL_SECURE_NO_WARNINGS" + "/D_ENABLE_EXTENDED_ALIGNED_STORAGE" +) + +list(APPEND MSVC_TEST_FLAGS + "/wd4018" + "/wd4101" + "/wd4503" +)
diff --git a/absl/copts/GENERATED_copts.bzl b/absl/copts/GENERATED_copts.bzl new file mode 100644 index 0000000..af20dcc --- /dev/null +++ b/absl/copts/GENERATED_copts.bzl
@@ -0,0 +1,131 @@ +"""GENERATED! DO NOT MANUALLY EDIT THIS FILE. + +(1) Edit absl/copts/copts.py. +(2) Run `<path_to_absl>/copts/generate_copts.py`. +""" + +GCC_EXCEPTIONS_FLAGS = [ + "-fexceptions", +] + +GCC_FLAGS = [ + "-Wall", + "-Wextra", + "-Wcast-qual", + "-Wconversion-null", + "-Wmissing-declarations", + "-Woverlength-strings", + "-Wpointer-arith", + "-Wunused-local-typedefs", + "-Wunused-result", + "-Wvarargs", + "-Wvla", + "-Wwrite-strings", + "-Wno-sign-compare", +] + +GCC_TEST_FLAGS = [ + "-Wno-conversion-null", + "-Wno-missing-declarations", + "-Wno-sign-compare", + "-Wno-unused-function", + "-Wno-unused-parameter", + "-Wno-unused-private-field", +] + +LLVM_EXCEPTIONS_FLAGS = [ + "-fexceptions", +] + +LLVM_FLAGS = [ + "-Wall", + "-Wextra", + "-Weverything", + "-Wno-c++98-compat-pedantic", + "-Wno-conversion", + "-Wno-covered-switch-default", + "-Wno-deprecated", + "-Wno-disabled-macro-expansion", + "-Wno-double-promotion", + "-Wno-comma", + "-Wno-extra-semi", + "-Wno-packed", + "-Wno-padded", + "-Wno-sign-compare", + "-Wno-float-conversion", + "-Wno-float-equal", + "-Wno-format-nonliteral", + "-Wno-gcc-compat", + "-Wno-global-constructors", + "-Wno-exit-time-destructors", + "-Wno-nested-anon-types", + "-Wno-non-modular-include-in-module", + "-Wno-old-style-cast", + "-Wno-range-loop-analysis", + "-Wno-reserved-id-macro", + "-Wno-shorten-64-to-32", + "-Wno-switch-enum", + "-Wno-thread-safety-negative", + "-Wno-undef", + "-Wno-unknown-warning-option", + "-Wno-unreachable-code", + "-Wno-unused-macros", + "-Wno-weak-vtables", + "-Wbitfield-enum-conversion", + "-Wbool-conversion", + "-Wconstant-conversion", + "-Wenum-conversion", + "-Wint-conversion", + "-Wliteral-conversion", + "-Wnon-literal-null-conversion", + "-Wnull-conversion", + "-Wobjc-literal-conversion", + "-Wno-sign-conversion", + "-Wstring-conversion", +] + +LLVM_TEST_FLAGS = [ + "-Wno-c99-extensions", + "-Wno-missing-noreturn", + "-Wno-missing-prototypes", + "-Wno-missing-variable-declarations", + "-Wno-null-conversion", + "-Wno-shadow", + "-Wno-shift-sign-overflow", + "-Wno-sign-compare", + "-Wno-unused-function", + "-Wno-unused-member-function", + "-Wno-unused-parameter", + "-Wno-unused-private-field", + "-Wno-unused-template", + "-Wno-used-but-marked-unused", + "-Wno-zero-as-null-pointer-constant", + "-Wno-gnu-zero-variadic-macro-arguments", +] + +MSVC_EXCEPTIONS_FLAGS = [ + "/U_HAS_EXCEPTIONS", + "/D_HAS_EXCEPTIONS=1", + "/EHsc", +] + +MSVC_FLAGS = [ + "/W3", + "/wd4005", + "/wd4068", + "/wd4180", + "/wd4244", + "/wd4267", + "/wd4800", + "/DNOMINMAX", + "/DWIN32_LEAN_AND_MEAN", + "/D_CRT_SECURE_NO_WARNINGS", + "/D_SCL_SECURE_NO_WARNINGS", + "/D_ENABLE_EXTENDED_ALIGNED_STORAGE", +] + +MSVC_TEST_FLAGS = [ + "/wd4018", + "/wd4101", + "/wd4503", +]
diff --git a/absl/copts/configure_copts.bzl b/absl/copts/configure_copts.bzl new file mode 100644 index 0000000..57cd3f6 --- /dev/null +++ b/absl/copts/configure_copts.bzl
@@ -0,0 +1,42 @@ +"""absl specific copts. + +This file simply selects the correct options from the generated files. To +change Abseil copts, edit absl/copts/copts.py +""" + +load( + "//absl:copts/GENERATED_copts.bzl", + "GCC_EXCEPTIONS_FLAGS", + "GCC_FLAGS", + "GCC_TEST_FLAGS", + "LLVM_EXCEPTIONS_FLAGS", + "LLVM_FLAGS", + "LLVM_TEST_FLAGS", + "MSVC_EXCEPTIONS_FLAGS", + "MSVC_FLAGS", + "MSVC_TEST_FLAGS", +) + +ABSL_DEFAULT_COPTS = select({ + "//absl:windows": MSVC_FLAGS, + "//absl:llvm_compiler": LLVM_FLAGS, + "//conditions:default": GCC_FLAGS, +}) + +# in absence of modules (--compiler=gcc or -c opt), cc_tests leak their copts +# to their (included header) dependencies and fail to build outside absl +ABSL_TEST_COPTS = ABSL_DEFAULT_COPTS + select({ + "//absl:windows": MSVC_TEST_FLAGS, + "//absl:llvm_compiler": LLVM_TEST_FLAGS, + "//conditions:default": GCC_TEST_FLAGS, +}) + +ABSL_EXCEPTIONS_FLAG = select({ + "//absl:windows": MSVC_EXCEPTIONS_FLAGS, + "//absl:llvm_compiler": LLVM_EXCEPTIONS_FLAGS, + "//conditions:default": GCC_EXCEPTIONS_FLAGS, +}) + +ABSL_EXCEPTIONS_FLAG_LINKOPTS = select({ + "//conditions:default": [], +})
diff --git a/absl/copts/copts.py b/absl/copts/copts.py new file mode 100644 index 0000000..7968903 --- /dev/null +++ b/absl/copts/copts.py
@@ -0,0 +1,156 @@ +"""Abseil compiler options. + +This is the source of truth for Abseil compiler options. To modify Abseil +compilation options: + + (1) Edit the appropriate list in this file. + (2) Run `<path_to_absl>/copts/generate_copts.py`. + +The generated copts are consumed by configure_copts.bzl and +AbseilConfigureCopts.cmake. +""" + +import collections # absl:google-only(used for internal flags) + +COPT_VARS = { + "GCC_FLAGS": [ + "-Wall", + "-Wextra", + "-Wcast-qual", + "-Wconversion-null", + "-Wmissing-declarations", + "-Woverlength-strings", + "-Wpointer-arith", + "-Wunused-local-typedefs", + "-Wunused-result", + "-Wvarargs", + "-Wvla", # variable-length array + "-Wwrite-strings", + # Google style does not use unsigned integers, though STL containers + # have unsigned types. + "-Wno-sign-compare", + ], + "GCC_TEST_FLAGS": [ + "-Wno-conversion-null", + "-Wno-missing-declarations", + "-Wno-sign-compare", + "-Wno-unused-function", + "-Wno-unused-parameter", + "-Wno-unused-private-field", + ], + "GCC_EXCEPTIONS_FLAGS": ["-fexceptions"], + + # Docs on single flags is preceded by a comment. + # Docs on groups of flags is preceded by ###. + "LLVM_FLAGS": [ + "-Wall", + "-Wextra", + "-Weverything", + # Abseil does not support C++98 + "-Wno-c++98-compat-pedantic", + # Turns off all implicit conversion warnings. Most are re-enabled below. + "-Wno-conversion", + "-Wno-covered-switch-default", + "-Wno-deprecated", + "-Wno-disabled-macro-expansion", + "-Wno-double-promotion", + ### + # Turned off as they include valid C++ code. + "-Wno-comma", + "-Wno-extra-semi", + "-Wno-packed", + "-Wno-padded", + ### + # Google style does not use unsigned integers, though STL containers + # have unsigned types. + "-Wno-sign-compare", + ### + "-Wno-float-conversion", + "-Wno-float-equal", + "-Wno-format-nonliteral", + # Too aggressive: warns on Clang extensions enclosed in Clang-only + # compilation paths. + "-Wno-gcc-compat", + ### + # Some internal globals are necessary. Don't do this at home. + "-Wno-global-constructors", + "-Wno-exit-time-destructors", + ### + "-Wno-nested-anon-types", + "-Wno-non-modular-include-in-module", + "-Wno-old-style-cast", + # Warns on preferred usage of non-POD types such as string_view + "-Wno-range-loop-analysis", + "-Wno-reserved-id-macro", + "-Wno-shorten-64-to-32", + "-Wno-switch-enum", + "-Wno-thread-safety-negative", + "-Wno-undef", + "-Wno-unknown-warning-option", + "-Wno-unreachable-code", + # Causes warnings on include guards + "-Wno-unused-macros", + "-Wno-weak-vtables", + ### + # Implicit conversion warnings turned off by -Wno-conversion + # which are re-enabled below. + "-Wbitfield-enum-conversion", + "-Wbool-conversion", + "-Wconstant-conversion", + "-Wenum-conversion", + "-Wint-conversion", + "-Wliteral-conversion", + "-Wnon-literal-null-conversion", + "-Wnull-conversion", + "-Wobjc-literal-conversion", + "-Wno-sign-conversion", + "-Wstring-conversion", + ], + "LLVM_TEST_FLAGS": [ + "-Wno-c99-extensions", + "-Wno-missing-noreturn", + "-Wno-missing-prototypes", + "-Wno-missing-variable-declarations", + "-Wno-null-conversion", + "-Wno-shadow", + "-Wno-shift-sign-overflow", + "-Wno-sign-compare", + "-Wno-unused-function", + "-Wno-unused-member-function", + "-Wno-unused-parameter", + "-Wno-unused-private-field", + "-Wno-unused-template", + "-Wno-used-but-marked-unused", + "-Wno-zero-as-null-pointer-constant", + # gtest depends on this GNU extension being offered. + "-Wno-gnu-zero-variadic-macro-arguments", + ], + "LLVM_EXCEPTIONS_FLAGS": ["-fexceptions"], + # /Wall with msvc includes unhelpful warnings such as C4711, C4710, ... + "MSVC_FLAGS": [ + "/W3", + "/wd4005", # macro-redefinition + "/wd4068", # unknown pragma + "/wd4180", # qualifier applied to function type has no meaning; ignored + "/wd4244", # conversion from 'type1' to 'type2', possible loss of data + "/wd4267", # conversion from 'size_t' to 'type', possible loss of data + # forcing value to bool 'true' or 'false' (performance warning) + "/wd4800", + "/DNOMINMAX", # Don't define min and max macros (windows.h) + # Don't bloat namespace with incompatible winsock versions. + "/DWIN32_LEAN_AND_MEAN", + # Don't warn about usage of insecure C functions. + "/D_CRT_SECURE_NO_WARNINGS", + "/D_SCL_SECURE_NO_WARNINGS", + # Introduced in VS 2017 15.8, allow overaligned types in aligned_storage + "/D_ENABLE_EXTENDED_ALIGNED_STORAGE", + ], + "MSVC_TEST_FLAGS": [ + "/wd4018", # signed/unsigned mismatch + "/wd4101", # unreferenced local variable + "/wd4503", # decorated name length exceeded, name was truncated + ], + "MSVC_EXCEPTIONS_FLAGS": [ + "/U_HAS_EXCEPTIONS", "/D_HAS_EXCEPTIONS=1", "/EHsc" + ] +}
diff --git a/absl/copts/generate_copts.py b/absl/copts/generate_copts.py new file mode 100755 index 0000000..28b677e --- /dev/null +++ b/absl/copts/generate_copts.py
@@ -0,0 +1,108 @@ +#!/usr/bin/python +"""Generate Abseil compile compile option configs. + +Usage: <path_to_absl>/copts/generate_copts.py + +The configs are generated from copts.py. +""" + +from os import path +import sys +from copts import COPT_VARS + + +# Helper functions +def file_header_lines(): + return [ + "GENERATED! DO NOT MANUALLY EDIT THIS FILE.", "", + "(1) Edit absl/copts/copts.py.", + "(2) Run `python <path_to_absl>/copts/generate_copts.py`." + ] + + +def flatten(*lists): + return [item for sublist in lists for item in sublist] + + +def relative_filename(filename): + return path.join(path.dirname(__file__), filename) + + +# Style classes. These contain all the syntactic styling needed to generate a +# copt file for different build tools. +class CMakeStyle(object): + """Style object for CMake copts file.""" + + def separator(self): + return "" + + def list_introducer(self, name): + return "list(APPEND " + name + + def list_closer(self): + return ")\n" + + def docstring(self): + return "\n".join((("# " + line).strip() for line in file_header_lines())) + + def filename(self): + return "GENERATED_AbseilCopts.cmake" + + +class StarlarkStyle(object): + """Style object for Starlark copts file.""" + + def separator(self): + return "," + + def list_introducer(self, name): + return name + " = [" + + def list_closer(self): + return "]\n" + + def docstring(self): + docstring_quotes = "\"\"\"" + return docstring_quotes + "\n".join( + flatten(file_header_lines(), [docstring_quotes])) + + def filename(self): + return "GENERATED_copts.bzl" + + +# Copt file generation +def copt_list(name, arg_list, style): + make_line = lambda s: " \"" + s + "\"" + style.separator() + external_str_list = [make_line(s) for s in arg_list] + + return "\n".join( + flatten( + [style.list_introducer(name)], + external_str_list, + [style.list_closer()])) + + +def generate_copt_file(style): + """Creates a generated copt file using the given style object. + + Args: + style: either StarlarkStyle() or CMakeStyle() + """ + with open(relative_filename(style.filename()), "w") as f: + f.write(style.docstring()) + f.write("\n") + for var_name, arg_list in sorted(COPT_VARS.items()): + f.write("\n") + f.write(copt_list(var_name, arg_list, style)) + + +def main(argv): + if len(argv) > 1: + raise RuntimeError("generate_copts needs no command line args") + + generate_copt_file(StarlarkStyle()) + generate_copt_file(CMakeStyle()) + + +if __name__ == "__main__": + main(sys.argv)
diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index e1e7fce..84b994d 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel
@@ -15,7 +15,7 @@ # load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", ) @@ -149,6 +149,7 @@ copts = ABSL_DEFAULT_COPTS, deps = [ "//absl/base", + "//absl/base:core_headers", "//absl/base:dynamic_annotations", ], ) @@ -180,22 +181,8 @@ cc_library( name = "leak_check", - srcs = select({ - # The leak checking interface depends on weak function - # declarations that may not necessarily have definitions. - # Windows doesn't support this, and ios requires - # guaranteed definitions for weak symbols. - "//absl:ios": [], - "//absl:windows": [], - "//conditions:default": [ - "leak_check.cc", - ], - }), - hdrs = select({ - "//absl:ios": [], - "//absl:windows": [], - "//conditions:default": ["leak_check.h"], - }), + srcs = ["leak_check.cc"], + hdrs = ["leak_check.h"], deps = ["//absl/base:core_headers"], )
diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index 4af2ec8..4c1fc50 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt
@@ -14,204 +14,297 @@ # limitations under the License. # -list(APPEND DEBUGGING_PUBLIC_HEADERS - "failure_signal_handler.h" - "leak_check.h" - "stacktrace.h" - "symbolize.h" -) - -# TODO(cohenjon) The below is all kinds of wrong. Make this match what we do in -# Bazel -list(APPEND DEBUGGING_INTERNAL_HEADERS - "internal/address_is_readable.h" - "internal/demangle.h" - "internal/elf_mem_image.h" - "internal/examine_stack.h" - "internal/stacktrace_config.h" - "internal/symbolize.h" - "internal/vdso_support.h" -) - -list(APPEND DEBUGGING_INTERNAL_SRC - "internal/address_is_readable.cc" - "internal/elf_mem_image.cc" - "internal/vdso_support.cc" -) - - -list(APPEND STACKTRACE_SRC - "stacktrace.cc" - ${DEBUGGING_INTERNAL_SRC} - ${DEBUGGING_PUBLIC_HEADERS} - ${DEBUGGING_INTERNAL_HEADERS} -) - -list(APPEND SYMBOLIZE_SRC - "symbolize.cc" - "symbolize_elf.inc" - "symbolize_unimplemented.inc" - "symbolize_win32.inc" - "internal/demangle.cc" - ${DEBUGGING_PUBLIC_HEADERS} - ${DEBUGGING_INTERNAL_HEADERS} - ${DEBUGGING_INTERNAL_SRC} -) - -list(APPEND FAILURE_SIGNAL_HANDLER_SRC - "failure_signal_handler.cc" - ${DEBUGGING_PUBLIC_HEADERS} -) - -list(APPEND EXAMINE_STACK_SRC - "internal/examine_stack.cc" - ${DEBUGGING_PUBLIC_HEADERS} - ${DEBUGGING_INTERNAL_HEADERS} -) - -absl_library( - TARGET - absl_stacktrace - SOURCES - ${STACKTRACE_SRC} - EXPORT_NAME +absl_cc_library( + NAME stacktrace + HDRS + "stacktrace.h" + SRCS + "stacktrace.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::debugging_internal + absl::base + absl::core_headers + PUBLIC ) -absl_library( - TARGET - absl_symbolize - SOURCES - ${SYMBOLIZE_SRC} - PUBLIC_LIBRARIES - absl::base - absl_malloc_internal - EXPORT_NAME +absl_cc_library( + NAME symbolize -) - -absl_library( - TARGET - absl_failure_signal_handler - SOURCES - ${FAILURE_SIGNAL_HANDLER_SRC} - PUBLIC_LIBRARIES - absl_base absl::examine_stack absl::stacktrace absl_synchronization - EXPORT_NAME - failure_signal_handler -) - -# Internal-only. Projects external to Abseil should not depend -# directly on this library. -absl_library( - TARGET - absl_examine_stack - SOURCES - ${EXAMINE_STACK_SRC} - EXPORT_NAME - examine_stack -) - -list(APPEND LEAK_CHECK_SRC - "leak_check.cc" -) - - -# leak_check library -absl_library( - TARGET - absl_leak_check - SOURCES - ${LEAK_CHECK_SRC} - PUBLIC_LIBRARIES - absl_base - EXPORT_NAME - leak_check -) - - -# component target -absl_header_library( - TARGET - absl_debugging - PUBLIC_LIBRARIES - absl_stacktrace absl_leak_check - EXPORT_NAME - debugging -) - -# -## TESTS -# - -list(APPEND STACK_CONSUMPTION_SRC - "internal/stack_consumption.cc" - "internal/stack_consumption.h" -) - -absl_library( - TARGET - absl_stack_consumption - SOURCES - ${STACK_CONSUMPTION_SRC} -) - -absl_test( - TARGET - absl_stack_consumption_test - SOURCES - "internal/stack_consumption_test.cc" - PUBLIC_LIBRARIES - absl_stack_consumption + HDRS + "symbolize.h" + "internal/symbolize.h" + SRCS + "symbolize.cc" + "symbolize_elf.inc" + "symbolize_unimplemented.inc" + "symbolize_win32.inc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::debugging_internal + absl::demangle_internal absl::base + absl::core_headers + absl::malloc_internal + PUBLIC ) -list(APPEND DEMANGLE_TEST_SRC "internal/demangle_test.cc") - -absl_test( - TARGET - demangle_test - SOURCES - ${DEMANGLE_TEST_SRC} - PUBLIC_LIBRARIES - absl_symbolize absl_stack_consumption -) - -list(APPEND SYMBOLIZE_TEST_SRC "symbolize_test.cc") - -absl_test( - TARGET +absl_cc_test( + NAME symbolize_test - SOURCES - ${SYMBOLIZE_TEST_SRC} - PUBLIC_LIBRARIES - absl::base absl::memory absl_symbolize absl_stack_consumption + SRCS + "symbolize_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::stack_consumption + absl::symbolize + absl::base + absl::core_headers + absl::memory + gmock ) -list(APPEND FAILURE_SIGNAL_HANDLER_TEST_SRC "failure_signal_handler_test.cc") +absl_cc_library( + NAME + examine_stack + HDRS + "internal/examine_stack.h" + SRCS + "internal/examine_stack.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::stacktrace + absl::symbolize + absl::base + absl::core_headers +) -absl_test( - TARGET +absl_cc_library( + NAME + failure_signal_handler + HDRS + "failure_signal_handler.h" + SRCS + "failure_signal_handler.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::examine_stack + absl::stacktrace + absl::base + absl::config + absl::core_headers + PUBLIC +) + +absl_cc_test( + NAME failure_signal_handler_test - SOURCES - ${FAILURE_SIGNAL_HANDLER_TEST_SRC} - PUBLIC_LIBRARIES - absl_examine_stack - absl_failure_signal_handler - absl_stacktrace - absl_symbolize + SRCS + "failure_signal_handler_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::failure_signal_handler + absl::stacktrace + absl::symbolize absl::base absl::strings + Threads::Threads + gmock ) -# test leak_check_test -list(APPEND LEAK_CHECK_TEST_SRC "leak_check_test.cc") +absl_cc_library( + NAME + debugging_internal + HDRS + "internal/address_is_readable.h" + "internal/elf_mem_image.h" + "internal/stacktrace_aarch64-inl.inc" + "internal/stacktrace_arm-inl.inc" + "internal/stacktrace_config.h" + "internal/stacktrace_generic-inl.inc" + "internal/stacktrace_powerpc-inl.inc" + "internal/stacktrace_unimplemented-inl.inc" + "internal/stacktrace_win32-inl.inc" + "internal/stacktrace_x86-inl.inc" + "internal/vdso_support.h" + SRCS + "internal/address_is_readable.cc" + "internal/elf_mem_image.cc" + "internal/vdso_support.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::base + absl::core_headers + absl::dynamic_annotations +) -absl_test( - TARGET +absl_cc_library( + NAME + demangle_internal + HDRS + "internal/demangle.h" + SRCS + "internal/demangle.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::base + absl::core_headers + PUBLIC +) + +absl_cc_test( + NAME + demangle_test + SRCS + "internal/demangle_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::demangle_internal + absl::stack_consumption + absl::base + absl::core_headers + absl::memory + gmock_main +) + +absl_cc_library( + NAME + leak_check + HDRS + "leak_check.h" + SRCS + "leak_check.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::core_headers + PUBLIC +) + +absl_cc_library( + NAME + leak_check_disable + SRCS + "leak_check_disable.cc" + PUBLIC +) + +# TODO(cohenjon) Move into the copts code. +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(ABSL_LSAN_LINKOPTS "-fsanitize=leak") +endif() + +absl_cc_library( + NAME + leak_check_api_enabled_for_testing + HDRS + "leak_check.h" + SRCS + "leak_check.cc" + COPTS + $<$<BOOL:${ABSL_USING_CLANG}>:-DLEAK_SANITIZER> + TESTONLY +) + +absl_cc_library( + NAME + leak_check_api_disabled_for_testing + HDRS + "leak_check.h" + SRCS + "leak_check.cc" + COPTS + "-ULEAK_SANITIZER" + TESTONLY +) + +absl_cc_test( + NAME leak_check_test - SOURCES - ${LEAK_CHECK_TEST_SRC} - PUBLIC_LIBRARIES - absl_leak_check + SRCS + "leak_check_test.cc" + COPTS + "$<$<CXX_COMPILER_ID:Clang>:-DABSL_EXPECT_LEAK_SANITIZER>" + LINKOPTS + "${ABSL_LSAN_LINKOPTS}" + DEPS + absl::leak_check_api_enabled_for_testing + absl::base + gmock_main +) + +absl_cc_test( + NAME + leak_check_no_lsan_test + SRCS + "leak_check_test.cc" + COPTS + "-UABSL_EXPECT_LEAK_SANITIZER" + DEPS + absl::leak_check_api_disabled_for_testing + absl::base + gmock_main +) + +absl_cc_test( + NAME + disabled_leak_check_test + SRCS + "leak_check_fail_test.cc" + LINKOPTS + "${ABSL_LSAN_LINKOPTS}" + DEPS + absl::leak_check_api_enabled_for_testing + absl::leak_check_disable + absl::base + gmock_main +) + +absl_cc_library( + NAME + stack_consumption + HDRS + "internal/stack_consumption.h" + SRCS + "internal/stack_consumption.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::base + absl::core_headers + TESTONLY +) + +absl_cc_test( + NAME + stack_consumption_test + SRCS + "internal/stack_consumption_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::stack_consumption + absl::base + absl::core_headers + gmock_main +) + +# component target +absl_cc_library( + NAME + debugging + DEPS + absl::stacktrace + absl::leak_check + PUBLIC )
diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc index d4b957b..c2e56f9 100644 --- a/absl/debugging/failure_signal_handler.cc +++ b/absl/debugging/failure_signal_handler.cc
@@ -119,7 +119,11 @@ #ifndef _WIN32 static bool SetupAlternateStackOnce() { +#if defined(__wasm__) || defined (__asjms__) const size_t page_mask = getpagesize() - 1; +#else + const size_t page_mask = sysconf(_SC_PAGESIZE) - 1; +#endif size_t stack_size = (std::max(SIGSTKSZ, 65536) + page_mask) & ~page_mask; #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ defined(THREAD_SANITIZER)
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 4835445..3ee3df5 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc
@@ -1636,6 +1636,15 @@ } state->parse_state = copy; + // Pointer-to-member access expressions. This parses the same as a binary + // operator, but it's implemented separately because "ds" shouldn't be + // accepted in other contexts that parse an operator name. + if (ParseTwoCharToken(state, "ds") && ParseExpression(state) && + ParseExpression(state)) { + return true; + } + state->parse_state = copy; + // Parameter pack expansion if (ParseTwoCharToken(state, "sp") && ParseExpression(state)) { return true;
diff --git a/absl/debugging/internal/stacktrace_config.h b/absl/debugging/internal/stacktrace_config.h index dd713da..578e496 100644 --- a/absl/debugging/internal/stacktrace_config.h +++ b/absl/debugging/internal/stacktrace_config.h
@@ -41,8 +41,9 @@ #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_aarch64-inl.inc" # elif defined(__arm__) +// Note: When using glibc this may require -funwind-tables to function properly. #define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_arm-inl.inc" + "absl/debugging/internal/stacktrace_generic-inl.inc" # else #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_unimplemented-inl.inc"
diff --git a/absl/debugging/internal/stacktrace_generic-inl.inc b/absl/debugging/internal/stacktrace_generic-inl.inc index 2c9ca41..08b87bd 100644 --- a/absl/debugging/internal/stacktrace_generic-inl.inc +++ b/absl/debugging/internal/stacktrace_generic-inl.inc
@@ -19,6 +19,7 @@ template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, const void *ucp, int *min_dropped_frames) { + static_cast<void>(ucp); // Unused. static const int kStackLength = 64; void * stack[kStackLength]; int size;
diff --git a/absl/debugging/stacktrace.cc b/absl/debugging/stacktrace.cc index 463fad2..7bbd65a 100644 --- a/absl/debugging/stacktrace.cc +++ b/absl/debugging/stacktrace.cc
@@ -80,29 +80,29 @@ } // anonymous namespace -ABSL_ATTRIBUTE_NOINLINE -int GetStackFrames(void** result, int* sizes, int max_depth, int skip_count) { +ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int GetStackFrames( + void** result, int* sizes, int max_depth, int skip_count) { return Unwind<true, false>(result, sizes, max_depth, skip_count, nullptr, nullptr); } -ABSL_ATTRIBUTE_NOINLINE -int GetStackFramesWithContext(void** result, int* sizes, int max_depth, - int skip_count, const void* uc, - int* min_dropped_frames) { +ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int +GetStackFramesWithContext(void** result, int* sizes, int max_depth, + int skip_count, const void* uc, + int* min_dropped_frames) { return Unwind<true, true>(result, sizes, max_depth, skip_count, uc, min_dropped_frames); } -ABSL_ATTRIBUTE_NOINLINE -int GetStackTrace(void** result, int max_depth, int skip_count) { +ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int GetStackTrace( + void** result, int max_depth, int skip_count) { return Unwind<false, false>(result, nullptr, max_depth, skip_count, nullptr, nullptr); } -ABSL_ATTRIBUTE_NOINLINE -int GetStackTraceWithContext(void** result, int max_depth, int skip_count, - const void* uc, int* min_dropped_frames) { +ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int +GetStackTraceWithContext(void** result, int max_depth, int skip_count, + const void* uc, int* min_dropped_frames) { return Unwind<false, true>(result, nullptr, max_depth, skip_count, uc, min_dropped_frames); }
diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc index e21439c..97d767a 100644 --- a/absl/debugging/symbolize_elf.inc +++ b/absl/debugging/symbolize_elf.inc
@@ -333,7 +333,11 @@ } // namespace static int SymbolizerSize() { +#if defined(__wasm__) || defined(__asmjs__) int pagesize = getpagesize(); +#else + int pagesize = sysconf(_SC_PAGESIZE); +#endif return ((sizeof(Symbolizer) - 1) / pagesize + 1) * pagesize; }
diff --git a/absl/hash/BUILD.bazel b/absl/hash/BUILD.bazel index 50aa550..5f24b99 100644 --- a/absl/hash/BUILD.bazel +++ b/absl/hash/BUILD.bazel
@@ -15,7 +15,7 @@ # load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", ) @@ -93,7 +93,6 @@ srcs = ["internal/city.cc"], hdrs = [ "internal/city.h", - "internal/city_crc.h", ], copts = ABSL_DEFAULT_COPTS, deps = [
diff --git a/absl/hash/CMakeLists.txt b/absl/hash/CMakeLists.txt index 35081e3..8f97d7c 100644 --- a/absl/hash/CMakeLists.txt +++ b/absl/hash/CMakeLists.txt
@@ -14,67 +14,98 @@ # limitations under the License. # -list(APPEND HASH_PUBLIC_HEADERS - "hash.h" -) - -list(APPEND HASH_INTERNAL_HEADERS - "internal/city.h" - "internal/city_crc.h" - "internal/hash.h" -) - -# absl_hash library -list(APPEND HASH_SRC - "internal/city.cc" - "internal/hash.cc" - ${HASH_PUBLIC_HEADERS} - ${HASH_INTERNAL_HEADERS} -) - -set(HASH_PUBLIC_LIBRARIES absl::hash absl::container absl::strings absl::str_format absl::utility) - -absl_library( - TARGET - absl_hash - SOURCES - ${HASH_SRC} - PUBLIC_LIBRARIES - ${HASH_PUBLIC_LIBRARIES} - EXPORT_NAME +absl_cc_library( + NAME hash + HDRS + "hash.h" + SRCS + "internal/hash.cc" + "internal/hash.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::core_headers + absl::endian + absl::fixed_array + absl::meta + absl::int128 + absl::strings + absl::optional + absl::variant + absl::utility + absl::city + PUBLIC ) -# -## TESTS -# +absl_cc_library( + NAME + hash_testing + HDRS + "hash_testing.h" + DEPS + absl::spy_hash_state + absl::meta + absl::strings + absl::variant + gmock + TESTONLY +) -# testing support -set(HASH_TEST_HEADERS hash_testing.h internal/spy_hash_state.h) -set(HASH_TEST_PUBLIC_LIBRARIES absl::hash absl::container absl::numeric absl::strings absl::str_format) - -# hash_test -set(HASH_TEST_SRC "hash_test.cc" ${HASH_TEST_HEADERS}) - -absl_test( - TARGET +absl_cc_test( + NAME hash_test - SOURCES - ${HASH_TEST_SRC} - PUBLIC_LIBRARIES - ${HASH_TEST_PUBLIC_LIBRARIES} + SRCS + "hash_test.cc" + DEPS + absl::hash + absl::hash_testing + absl::core_headers + absl::flat_hash_set + absl::spy_hash_state + absl::meta + absl::int128 + gmock_main ) -# hash_test -set(CITY_TEST_SRC "internal/city_test.cc") +absl_cc_library( + NAME + spy_hash_state + HDRS + "internal/spy_hash_state.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::hash + absl::strings + absl::str_format + TESTONLY +) -absl_test( - TARGET +absl_cc_library( + NAME + city + HDRS + "internal/city.h" + SRCS + "internal/city.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::config + absl::core_headers + absl::endian +) + +absl_cc_test( + NAME city_test - SOURCES - ${CITY_TEST_SRC} - PUBLIC_LIBRARIES - ${HASH_TEST_PUBLIC_LIBRARIES} + SRCS + "internal/city_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::city + gmock_main ) -
diff --git a/absl/hash/hash.h b/absl/hash/hash.h index c7ba4c2..36c7c2b 100644 --- a/absl/hash/hash.h +++ b/absl/hash/hash.h
@@ -25,8 +25,8 @@ // * `AbslHashValue`, an extension point that allows you to extend types to // support Abseil hashing without requiring you to define a hashing // algorithm. -// * `HashState`, a type-erased class which implement the manipulation of the -// hash state (H) itself. containing member functions `combine()` and +// * `HashState`, a type-erased class which implements the manipulation of the +// hash state (H) itself, contains member functions `combine()` and // `combine_contiguous()`, which you can use to contribute to an existing // hash state when hashing your types. // @@ -69,7 +69,7 @@ // `absl::Hash` // ----------------------------------------------------------------------------- // -// `absl::Hash<T>` is a convenient general-purpose hash functor for a type `T` +// `absl::Hash<T>` is a convenient general-purpose hash functor for any type `T` // satisfying any of the following conditions (in order): // // * T is an arithmetic or pointer type @@ -98,7 +98,7 @@ // * absl::string_view // * absl::InlinedVector // * absl::FixedArray -// * absl::unit128 +// * absl::uint128 // * absl::Time, absl::Duration, and absl::TimeZone // // Note: the list above is not meant to be exhaustive. Additional type support @@ -142,7 +142,7 @@ // // The "hash state" concept contains two member functions for mixing hash state: // -// * `H::combine()` +// * `H::combine(state, values...)` // // Combines an arbitrary number of values into a hash state, returning the // updated state. Note that the existing hash state is move-only and must be @@ -160,7 +160,7 @@ // state = H::combine(std::move(state), value2); // state = H::combine(std::move(state), value3); // -// * `H::combine_contiguous()` +// * `H::combine_contiguous(state, data, size)` // // Combines a contiguous array of `size` elements into a hash state, // returning the updated state. Note that the existing hash state is
diff --git a/absl/hash/hash_testing.h b/absl/hash/hash_testing.h index 1e3cda6..52bcb55 100644 --- a/absl/hash/hash_testing.h +++ b/absl/hash/hash_testing.h
@@ -90,7 +90,7 @@ // template <typename H> // friend H AbslHashValue(H state, Bad2 x) { // // Uses a and b. -// return H::combine(x.a, x.b); +// return H::combine(std::move(state), x.a, x.b); // } // friend bool operator==(Bad2 x, Bad2 y) { // // Only uses a. @@ -107,7 +107,7 @@ // template <typename H> // friend H AbslHashValue(H state, Bad3 x) { // // Only uses a. -// return H::combine(x.a); +// return H::combine(std::move(state), x.a); // } // friend bool operator==(Bad3 x, Bad3 y) { // // Uses a and b. @@ -123,19 +123,21 @@ // int *p, size; // template <typename H> // friend H AbslHashValue(H state, Bad4 x) { -// return H::combine_range(x.p, x.p + x.size); +// return H::combine_contiguous(std::move(state), x.p, x.p + x.size); // } // friend bool operator==(Bad4 x, Bad4 y) { -// return std::equal(x.p, x.p + x.size, y.p, y.p + y.size); +// // Compare two ranges for equality. C++14 code can instead use std::equal. +// return absl::equal(x.p, x.p + x.size, y.p, y.p + y.size); // } // }; // // An easy solution to this is to combine the size after combining the range, // like so: -// template <typename H> -// friend H AbslHashValue(H state, Bad4 x) { -// return H::combine(H::combine_range(x.p, x.p + x.size), x.size); -// } +// template <typename H> +// friend H AbslHashValue(H state, Bad4 x) { +// return H::combine( +// H::combine_contiguous(std::move(state), x.p, x.p + x.size), x.size); +// } // template <int&... ExplicitBarrier, typename Container> ABSL_MUST_USE_RESULT testing::AssertionResult @@ -227,7 +229,8 @@ // Now we verify that AbslHashValue is also correctly implemented. for (const auto& c : classes) { - // All elements of the equivalence class must have the same hash expansion. + // All elements of the equivalence class must have the same hash + // expansion. const SpyHashState expected = c[0].expand(); for (const Info& v : c) { if (v.expand() != v.expand()) { @@ -285,7 +288,7 @@ }; template <typename... T> -struct MakeTypeSet : TypeSet<>{}; +struct MakeTypeSet : TypeSet<> {}; template <typename T, typename... Ts> struct MakeTypeSet<T, Ts...> : MakeTypeSet<Ts...>::template Insert<T>::type {}; @@ -346,8 +349,7 @@ ABSL_MUST_USE_RESULT testing::AssertionResult VerifyTypeImplementsAbslHashCorrectly(const Container& values, Eq equals) { return hash_internal::VerifyTypeImplementsAbslHashCorrectly( - hash_internal::ContainerAsVector<Container>::Do(values), - equals); + hash_internal::ContainerAsVector<Container>::Do(values), equals); } template <int&..., typename T>
diff --git a/absl/hash/internal/city.cc b/absl/hash/internal/city.cc index 8f72dd1..122906f 100644 --- a/absl/hash/internal/city.cc +++ b/absl/hash/internal/city.cc
@@ -340,251 +340,5 @@ return HashLen16(CityHash64(s, len) - seed0, seed1); } -// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings -// of any length representable in signed long. Based on City and Murmur. -static uint128 CityMurmur(const char *s, size_t len, uint128 seed) { - uint64_t a = Uint128Low64(seed); - uint64_t b = Uint128High64(seed); - uint64_t c = 0; - uint64_t d = 0; - int64_t l = len - 16; - if (l <= 0) { // len <= 16 - a = ShiftMix(a * k1) * k1; - c = b * k1 + HashLen0to16(s, len); - d = ShiftMix(a + (len >= 8 ? Fetch64(s) : c)); - } else { // len > 16 - c = HashLen16(Fetch64(s + len - 8) + k1, a); - d = HashLen16(b + len, c + Fetch64(s + len - 16)); - a += d; - do { - a ^= ShiftMix(Fetch64(s) * k1) * k1; - a *= k1; - b ^= a; - c ^= ShiftMix(Fetch64(s + 8) * k1) * k1; - c *= k1; - d ^= c; - s += 16; - l -= 16; - } while (l > 0); - } - a = HashLen16(a, c); - b = HashLen16(d, b); - return uint128(a ^ b, HashLen16(b, a)); -} - -uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) { - if (len < 128) { - return CityMurmur(s, len, seed); - } - - // We expect len >= 128 to be the common case. Keep 56 bytes of state: - // v, w, x, y, and z. - std::pair<uint64_t, uint64_t> v, w; - uint64_t x = Uint128Low64(seed); - uint64_t y = Uint128High64(seed); - uint64_t z = len * k1; - v.first = Rotate(y ^ k1, 49) * k1 + Fetch64(s); - v.second = Rotate(v.first, 42) * k1 + Fetch64(s + 8); - w.first = Rotate(y + z, 35) * k1 + x; - w.second = Rotate(x + Fetch64(s + 88), 53) * k1; - - // This is the same inner loop as CityHash64(), manually unrolled. - do { - x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1; - y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1; - x ^= w.second; - y += v.first + Fetch64(s + 40); - z = Rotate(z + w.first, 33) * k1; - v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first); - w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16)); - std::swap(z, x); - s += 64; - x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1; - y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1; - x ^= w.second; - y += v.first + Fetch64(s + 40); - z = Rotate(z + w.first, 33) * k1; - v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first); - w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16)); - std::swap(z, x); - s += 64; - len -= 128; - } while (ABSL_PREDICT_TRUE(len >= 128)); - x += Rotate(v.first + z, 49) * k0; - y = y * k0 + Rotate(w.second, 37); - z = z * k0 + Rotate(w.first, 27); - w.first *= 9; - v.first *= k0; - // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s. - for (size_t tail_done = 0; tail_done < len;) { - tail_done += 32; - y = Rotate(x + y, 42) * k0 + v.second; - w.first += Fetch64(s + len - tail_done + 16); - x = x * k0 + w.first; - z += w.second + Fetch64(s + len - tail_done); - w.second += v.first; - v = WeakHashLen32WithSeeds(s + len - tail_done, v.first + z, v.second); - v.first *= k0; - } - // At this point our 56 bytes of state should contain more than - // enough information for a strong 128-bit hash. We use two - // different 56-byte-to-8-byte hashes to get a 16-byte final result. - x = HashLen16(x, v.first); - y = HashLen16(y + z, w.first); - return uint128(HashLen16(x + v.second, w.second) + y, - HashLen16(x + w.second, y + v.second)); -} - -uint128 CityHash128(const char *s, size_t len) { - return len >= 16 - ? CityHash128WithSeed(s + 16, len - 16, - uint128(Fetch64(s), Fetch64(s + 8) + k0)) - : CityHash128WithSeed(s, len, uint128(k0, k1)); -} } // namespace hash_internal } // namespace absl - -#ifdef __SSE4_2__ -#include <nmmintrin.h> -#include "absl/hash/internal/city_crc.h" - -namespace absl { -namespace hash_internal { - -// Requires len >= 240. -static void CityHashCrc256Long(const char *s, size_t len, uint32_t seed, - uint64_t *result) { - uint64_t a = Fetch64(s + 56) + k0; - uint64_t b = Fetch64(s + 96) + k0; - uint64_t c = result[0] = HashLen16(b, len); - uint64_t d = result[1] = Fetch64(s + 120) * k0 + len; - uint64_t e = Fetch64(s + 184) + seed; - uint64_t f = 0; - uint64_t g = 0; - uint64_t h = c + d; - uint64_t x = seed; - uint64_t y = 0; - uint64_t z = 0; - - // 240 bytes of input per iter. - size_t iters = len / 240; - len -= iters * 240; - do { -#undef CHUNK -#define CHUNK(r) \ - PERMUTE3(x, z, y); \ - b += Fetch64(s); \ - c += Fetch64(s + 8); \ - d += Fetch64(s + 16); \ - e += Fetch64(s + 24); \ - f += Fetch64(s + 32); \ - a += b; \ - h += f; \ - b += c; \ - f += d; \ - g += e; \ - e += z; \ - g += x; \ - z = _mm_crc32_u64(z, b + g); \ - y = _mm_crc32_u64(y, e + h); \ - x = _mm_crc32_u64(x, f + a); \ - e = Rotate(e, r); \ - c += e; \ - s += 40 - - CHUNK(0); - PERMUTE3(a, h, c); - CHUNK(33); - PERMUTE3(a, h, f); - CHUNK(0); - PERMUTE3(b, h, f); - CHUNK(42); - PERMUTE3(b, h, d); - CHUNK(0); - PERMUTE3(b, h, e); - CHUNK(33); - PERMUTE3(a, h, e); - } while (--iters > 0); - - while (len >= 40) { - CHUNK(29); - e ^= Rotate(a, 20); - h += Rotate(b, 30); - g ^= Rotate(c, 40); - f += Rotate(d, 34); - PERMUTE3(c, h, g); - len -= 40; - } - if (len > 0) { - s = s + len - 40; - CHUNK(33); - e ^= Rotate(a, 43); - h += Rotate(b, 42); - g ^= Rotate(c, 41); - f += Rotate(d, 40); - } - result[0] ^= h; - result[1] ^= g; - g += h; - a = HashLen16(a, g + z); - x += y << 32; - b += x; - c = HashLen16(c, z) + h; - d = HashLen16(d, e + result[0]); - g += e; - h += HashLen16(x, f); - e = HashLen16(a, d) + g; - z = HashLen16(b, c) + a; - y = HashLen16(g, h) + c; - result[0] = e + z + y + x; - a = ShiftMix((a + y) * k0) * k0 + b; - result[1] += a + result[0]; - a = ShiftMix(a * k0) * k0 + c; - result[2] = a + result[1]; - a = ShiftMix((a + e) * k0) * k0; - result[3] = a + result[2]; -} - -// Requires len < 240. -static void CityHashCrc256Short(const char *s, size_t len, uint64_t *result) { - char buf[240]; - memcpy(buf, s, len); - memset(buf + len, 0, 240 - len); - CityHashCrc256Long(buf, 240, ~static_cast<uint32_t>(len), result); -} - -void CityHashCrc256(const char *s, size_t len, uint64_t *result) { - if (ABSL_PREDICT_TRUE(len >= 240)) { - CityHashCrc256Long(s, len, 0, result); - } else { - CityHashCrc256Short(s, len, result); - } -} - -uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed) { - if (len <= 900) { - return CityHash128WithSeed(s, len, seed); - } else { - uint64_t result[4]; - CityHashCrc256(s, len, result); - uint64_t u = Uint128High64(seed) + result[0]; - uint64_t v = Uint128Low64(seed) + result[1]; - return uint128(HashLen16(u, v + result[2]), - HashLen16(Rotate(v, 32), u * k0 + result[3])); - } -} - -uint128 CityHashCrc128(const char *s, size_t len) { - if (len <= 900) { - return CityHash128(s, len); - } else { - uint64_t result[4]; - CityHashCrc256(s, len, result); - return uint128(result[2], result[3]); - } -} - -} // namespace hash_internal -} // namespace absl - -#endif
diff --git a/absl/hash/internal/city.h b/absl/hash/internal/city.h index 55b37b8..16df556 100644 --- a/absl/hash/internal/city.h +++ b/absl/hash/internal/city.h
@@ -23,15 +23,6 @@ // is Murmur3. For 64-bit x86 code, CityHash64 is an excellent choice for hash // tables and most other hashing (excluding cryptography). // -// For 64-bit x86 code, on long strings, the picture is more complicated. -// On many recent Intel CPUs, such as Nehalem, Westmere, Sandy Bridge, etc., -// CityHashCrc128 appears to be faster than all competitors of comparable -// quality. CityHash128 is also good but not quite as fast. We believe our -// nearest competitor is Bob Jenkins' Spooky. We don't have great data for -// other 64-bit CPUs, but for long strings we know that Spooky is slightly -// faster than CityHash on some relatively recent AMD x86-64 CPUs, for example. -// Note that CityHashCrc128 is declared in citycrc.h. -// // For 32-bit x86 code, we don't know of anything faster than CityHash32 that // is of comparable quality. We believe our nearest competitor is Murmur3A. // (On 64-bit CPUs, it is typically faster to use the other CityHash variants.) @@ -79,13 +70,6 @@ uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0, uint64_t seed1); -// Hash function for a byte array. -uint128 CityHash128(const char *s, size_t len); - -// Hash function for a byte array. For convenience, a 128-bit seed is also -// hashed into the result. -uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed); - // Hash function for a byte array. Most useful in 32-bit binaries. uint32_t CityHash32(const char *s, size_t len);
diff --git a/absl/hash/internal/city_crc.h b/absl/hash/internal/city_crc.h deleted file mode 100644 index 6be6557..0000000 --- a/absl/hash/internal/city_crc.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2018 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// This file declares the subset of the CityHash functions that require -// _mm_crc32_u64(). See the CityHash README for details. -// -// Functions in the CityHash family are not suitable for cryptography. - -#ifndef ABSL_HASH_INTERNAL_CITY_CRC_H_ -#define ABSL_HASH_INTERNAL_CITY_CRC_H_ - -#include "absl/hash/internal/city.h" - -namespace absl { -namespace hash_internal { - -// Hash function for a byte array. -uint128 CityHashCrc128(const char *s, size_t len); - -// Hash function for a byte array. For convenience, a 128-bit seed is also -// hashed into the result. -uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed); - -// Hash function for a byte array. Sets result[0] ... result[3]. -void CityHashCrc256(const char *s, size_t len, uint64_t *result); - -} // namespace hash_internal -} // namespace absl - -#endif // ABSL_HASH_INTERNAL_CITY_CRC_H_
diff --git a/absl/hash/internal/city_test.cc b/absl/hash/internal/city_test.cc index 678da53..0427cd1 100644 --- a/absl/hash/internal/city_test.cc +++ b/absl/hash/internal/city_test.cc
@@ -18,9 +18,6 @@ #include <cstdio> #include <iostream> #include "gtest/gtest.h" -#ifdef __SSE4_2__ -#include "absl/hash/internal/city_crc.h" -#endif namespace absl { namespace hash_internal { @@ -28,7 +25,6 @@ static const uint64_t k0 = 0xc3a5c85c97cb3127ULL; static const uint64_t kSeed0 = 1234567; static const uint64_t kSeed1 = k0; -static const uint128 kSeed128(kSeed0, kSeed1); static const int kDataSize = 1 << 20; static const int kTestSize = 300; @@ -49,1754 +45,539 @@ } #define C(x) 0x##x##ULL -static const uint64_t testdata[kTestSize][16] = { +static const uint64_t testdata[kTestSize][4] = { {C(9ae16a3b2f90404f), C(75106db890237a4a), C(3feac5f636039766), - C(3df09dfc64c09a2b), C(3cb540c392e51e29), C(6b56343feac0663), - C(5b7bc50fd8e8ad92), C(3df09dfc64c09a2b), C(3cb540c392e51e29), - C(6b56343feac0663), C(5b7bc50fd8e8ad92), C(95162f24e6a5f930), - C(6808bdf4f1eb06e0), C(b3b1f3a67b624d82), C(c9a62f12bd4cd80b), C(dc56d17a)}, {C(541150e87f415e96), C(1aef0d24b3148a1a), C(bacc300e1e82345a), - C(c3cdc41e1df33513), C(2c138ff2596d42f6), C(f58e9082aed3055f), - C(162e192b2957163d), C(c3cdc41e1df33513), C(2c138ff2596d42f6), - C(f58e9082aed3055f), C(162e192b2957163d), C(fb99e85e0d16f90c), - C(608462c15bdf27e8), C(e7d2c5c943572b62), C(1baaa9327642798c), C(99929334)}, - {C(f3786a4b25827c1), C(34ee1a2bf767bd1c), C(2f15ca2ebfb631f2), - C(3149ba1dac77270d), C(70e2e076e30703c), C(59bcc9659bc5296), - C(9ecbc8132ae2f1d7), C(3149ba1dac77270d), C(70e2e076e30703c), - C(59bcc9659bc5296), C(9ecbc8132ae2f1d7), C(a01d30789bad7cf2), - C(ae03fe371981a0e0), C(127e3883b8788934), C(d0ac3d4c0a6fca32), - C(4252edb7)}, + {C(f3786a4b25827c1), C(34ee1a2bf767bd1c), C(2f15ca2ebfb631f2), C(4252edb7)}, {C(ef923a7a1af78eab), C(79163b1e1e9a9b18), C(df3b2aca6e1e4a30), - C(2193fb7620cbf23b), C(8b6a8ff06cda8302), C(1a44469afd3e091f), - C(8b0449376612506), C(2193fb7620cbf23b), C(8b6a8ff06cda8302), - C(1a44469afd3e091f), C(8b0449376612506), C(e9d9d41c32ad91d1), - C(b44ab09f58e3c608), C(19e9175f9fcf784), C(839b3c9581b4a480), C(ebc34f3c)}, + C(ebc34f3c)}, {C(11df592596f41d88), C(843ec0bce9042f9c), C(cce2ea1e08b1eb30), - C(4d09e42f09cc3495), C(666236631b9f253b), C(d28b3763cd02b6a3), - C(43b249e57c4d0c1b), C(4d09e42f09cc3495), C(666236631b9f253b), - C(d28b3763cd02b6a3), C(43b249e57c4d0c1b), C(3887101c8adea101), - C(8a9355d4efc91df0), C(3e610944cc9fecfd), C(5bf9eb60b08ac0ce), C(26f2b463)}, {C(831f448bdc5600b3), C(62a24be3120a6919), C(1b44098a41e010da), - C(dc07df53b949c6b), C(d2b11b2081aeb002), C(d212b02c1b13f772), - C(c0bed297b4be1912), C(dc07df53b949c6b), C(d2b11b2081aeb002), - C(d212b02c1b13f772), C(c0bed297b4be1912), C(682d3d2ad304e4af), - C(40e9112a655437a1), C(268b09f7ee09843f), C(6b9698d43859ca47), C(b042c047)}, - {C(3eca803e70304894), C(d80de767e4a920a), C(a51cfbb292efd53d), - C(d183dcda5f73edfa), C(3a93cbf40f30128c), C(1a92544d0b41dbda), - C(aec2c4bee81975e1), C(d183dcda5f73edfa), C(3a93cbf40f30128c), - C(1a92544d0b41dbda), C(aec2c4bee81975e1), C(5f91814d1126ba4b), - C(f8ac57eee87fcf1f), C(c55c644a5d0023cd), C(adb761e827825ff2), - C(e73bb0a8)}, + {C(3eca803e70304894), C(d80de767e4a920a), C(a51cfbb292efd53d), C(e73bb0a8)}, {C(1b5a063fb4c7f9f1), C(318dbc24af66dee9), C(10ef7b32d5c719af), - C(b140a02ef5c97712), C(b7d00ef065b51b33), C(635121d532897d98), - C(532daf21b312a6d6), C(b140a02ef5c97712), C(b7d00ef065b51b33), - C(635121d532897d98), C(532daf21b312a6d6), C(c0b09b75d943910), - C(8c84dfb5ef2a8e96), C(e5c06034b0353433), C(3170faf1c33a45dd), C(91dfdd75)}, {C(a0f10149a0e538d6), C(69d008c20f87419f), C(41b36376185b3e9e), - C(26b6689960ccf81d), C(55f23b27bb9efd94), C(3a17f6166dd765db), - C(c891a8a62931e782), C(26b6689960ccf81d), C(55f23b27bb9efd94), - C(3a17f6166dd765db), C(c891a8a62931e782), C(23852dc37ddd2607), - C(8b7f1b1ec897829e), C(d1d69452a54eed8a), C(56431f2bd766ec24), C(c87f95de)}, {C(fb8d9c70660b910b), C(a45b0cc3476bff1b), C(b28d1996144f0207), - C(98ec31113e5e35d2), C(5e4aeb853f1b9aa7), C(bcf5c8fe4465b7c8), - C(b1ea3a8243996f15), C(98ec31113e5e35d2), C(5e4aeb853f1b9aa7), - C(bcf5c8fe4465b7c8), C(b1ea3a8243996f15), C(cabbccedb6407571), - C(d1e40a84c445ec3a), C(33302aa908cf4039), C(9f15f79211b5cdf8), C(3f5538ef)}, {C(236827beae282a46), C(e43970221139c946), C(4f3ac6faa837a3aa), - C(71fec0f972248915), C(2170ec2061f24574), C(9eb346b6caa36e82), - C(2908f0fdbca48e73), C(71fec0f972248915), C(2170ec2061f24574), - C(9eb346b6caa36e82), C(2908f0fdbca48e73), C(8101c99f07c64abb), - C(b9f4b02b1b6a96a7), C(583a2b10cd222f88), C(199dae4cf9db24c), C(70eb1a1f)}, + C(70eb1a1f)}, {C(c385e435136ecf7c), C(d9d17368ff6c4a08), C(1b31eed4e5251a67), - C(df01a322c43a6200), C(298b65a1714b5a7e), C(933b83f0aedf23c), - C(157bcb44d63f765a), C(df01a322c43a6200), C(298b65a1714b5a7e), - C(933b83f0aedf23c), C(157bcb44d63f765a), C(d6e9fc7a272d8b51), - C(3ee5073ef1a9b777), C(63149e31fac02c59), C(2f7979ff636ba1d8), C(cfd63b83)}, {C(e3f6828b6017086d), C(21b4d1900554b3b0), C(bef38be1809e24f1), - C(d93251758985ee6c), C(32a9e9f82ba2a932), C(3822aacaa95f3329), - C(db349b2f90a490d8), C(d93251758985ee6c), C(32a9e9f82ba2a932), - C(3822aacaa95f3329), C(db349b2f90a490d8), C(8d49194a894a19ca), - C(79a78b06e42738e6), C(7e0f1eda3d390c66), C(1c291d7e641100a5), C(894a52ef)}, {C(851fff285561dca0), C(4d1277d73cdf416f), C(28ccffa61010ebe2), - C(77a4ccacd131d9ee), C(e1d08eeb2f0e29aa), C(70b9e3051383fa45), - C(582d0120425caba), C(77a4ccacd131d9ee), C(e1d08eeb2f0e29aa), - C(70b9e3051383fa45), C(582d0120425caba), C(a740eef1846e4564), - C(572dddb74ac3ae00), C(fdb5ca9579163bbd), C(a649b9b799c615d2), C(9cde6a54)}, {C(61152a63595a96d9), C(d1a3a91ef3a7ba45), C(443b6bb4a493ad0c), - C(a154296d11362d06), C(d0f0bf1f1cb02fc1), C(ccb87e09309f90d1), - C(b24a8e4881911101), C(a154296d11362d06), C(d0f0bf1f1cb02fc1), - C(ccb87e09309f90d1), C(b24a8e4881911101), C(1a481b4528559f58), - C(bf837a3150896995), C(4989ef6b941a3757), C(2e725ab72d0b2948), C(6c4898d5)}, {C(44473e03be306c88), C(30097761f872472a), C(9fd1b669bfad82d7), - C(3bab18b164396783), C(47e385ff9d4c06f), C(18062081bf558df), - C(63416eb68f104a36), C(3bab18b164396783), C(47e385ff9d4c06f), - C(18062081bf558df), C(63416eb68f104a36), C(4abda1560c47ac80), - C(1ea0e63dc6587aee), C(33ec79d92ebc1de), C(94f9dccef771e048), C(13e1978e)}, - {C(3ead5f21d344056), C(fb6420393cfb05c3), C(407932394cbbd303), - C(ac059617f5906673), C(94d50d3dcd3069a7), C(2b26c3b92dea0f0), - C(99b7374cc78fc3fb), C(ac059617f5906673), C(94d50d3dcd3069a7), - C(2b26c3b92dea0f0), C(99b7374cc78fc3fb), C(1a8e3c73cdd40ee8), - C(cbb5fca06747f45b), C(ceec44238b291841), C(28bf35cce9c90a25), C(51b4ba8)}, + C(13e1978e)}, + {C(3ead5f21d344056), C(fb6420393cfb05c3), C(407932394cbbd303), C(51b4ba8)}, {C(6abbfde37ee03b5b), C(83febf188d2cc113), C(cda7b62d94d5b8ee), - C(a4375590b8ae7c82), C(168fd42f9ecae4ff), C(23bbde43de2cb214), - C(a8c333112a243c8c), C(a4375590b8ae7c82), C(168fd42f9ecae4ff), - C(23bbde43de2cb214), C(a8c333112a243c8c), C(10ac012e8c518b49), - C(64a44605d8b29458), C(a67e701d2a679075), C(3a3a20f43ec92303), C(b6b06e40)}, - {C(943e7ed63b3c080), C(1ef207e9444ef7f8), C(ef4a9f9f8c6f9b4a), - C(6b54fc38d6a84108), C(32f4212a47a4665), C(6b5a9a8f64ee1da6), - C(9f74e86c6da69421), C(6b54fc38d6a84108), C(32f4212a47a4665), - C(6b5a9a8f64ee1da6), C(9f74e86c6da69421), C(946dd0cb30c1a08e), - C(fdf376956907eaaa), C(a59074c6eec03028), C(b1a3abcf283f34ac), C(240a2f2)}, + {C(943e7ed63b3c080), C(1ef207e9444ef7f8), C(ef4a9f9f8c6f9b4a), C(240a2f2)}, {C(d72ce05171ef8a1a), C(c6bd6bd869203894), C(c760e6396455d23a), - C(f86af0b40dcce7b), C(8d3c15d613394d3c), C(491e400491cd4ece), - C(7c19d3530ea3547f), C(f86af0b40dcce7b), C(8d3c15d613394d3c), - C(491e400491cd4ece), C(7c19d3530ea3547f), C(1362963a1dc32af9), - C(fb9bc11762e1385c), C(9e164ef1f5376083), C(6c15819b5e828a7e), C(5dcefc30)}, {C(4182832b52d63735), C(337097e123eea414), C(b5a72ca0456df910), - C(7ebc034235bc122f), C(d9a7783d4edd8049), C(5f8b04a15ae42361), - C(fc193363336453dd), C(7ebc034235bc122f), C(d9a7783d4edd8049), - C(5f8b04a15ae42361), C(fc193363336453dd), C(9b6c50224ef8c4f8), - C(ba225c7942d16c3f), C(6f6d55226a73c412), C(abca061fe072152a), C(7a48b105)}, {C(d6cdae892584a2cb), C(58de0fa4eca17dcd), C(43df30b8f5f1cb00), - C(9e4ea5a4941e097d), C(547e048d5a9daaba), C(eb6ecbb0b831d185), - C(e0168df5fad0c670), C(9e4ea5a4941e097d), C(547e048d5a9daaba), - C(eb6ecbb0b831d185), C(e0168df5fad0c670), C(afa9705f98c2c96a), - C(749436f48137a96b), C(759c041fc21df486), C(b23bf400107aa2ec), C(fd55007b)}, {C(5c8e90bc267c5ee4), C(e9ae044075d992d9), C(f234cbfd1f0a1e59), - C(ce2744521944f14c), C(104f8032f99dc152), C(4e7f425bfac67ca7), - C(9461b911a1c6d589), C(ce2744521944f14c), C(104f8032f99dc152), - C(4e7f425bfac67ca7), C(9461b911a1c6d589), C(5e5ecc726db8b60d), - C(cce68b0586083b51), C(8a7f8e54a9cba0fc), C(42f010181d16f049), C(6b95894c)}, {C(bbd7f30ac310a6f3), C(b23b570d2666685f), C(fb13fb08c9814fe7), - C(4ee107042e512374), C(1e2c8c0d16097e13), C(210c7500995aa0e6), - C(6c13190557106457), C(4ee107042e512374), C(1e2c8c0d16097e13), - C(210c7500995aa0e6), C(6c13190557106457), C(a99b31c96777f381), - C(8312ae8301d386c0), C(ed5042b2a4fa96a3), C(d71d1bb23907fe97), C(3360e827)}, - {C(36a097aa49519d97), C(8204380a73c4065), C(77c2004bdd9e276a), - C(6ee1f817ce0b7aee), C(e9dcb3507f0596ca), C(6bc63c666b5100e2), - C(e0b056f1821752af), C(6ee1f817ce0b7aee), C(e9dcb3507f0596ca), - C(6bc63c666b5100e2), C(e0b056f1821752af), C(8ea1114e60292678), - C(904b80b46becc77), C(46cd9bb6e9dff52f), C(4c91e3b698355540), C(45177e0b)}, - {C(dc78cb032c49217), C(112464083f83e03a), C(96ae53e28170c0f5), - C(d367ff54952a958), C(cdad930657371147), C(aa24dc2a9573d5fe), - C(eb136daa89da5110), C(d367ff54952a958), C(cdad930657371147), - C(aa24dc2a9573d5fe), C(eb136daa89da5110), C(de623005f6d46057), - C(b50c0c92b95e9b7f), C(a8aa54050b81c978), C(573fb5c7895af9b5), - C(7c6fffe4)}, + {C(36a097aa49519d97), C(8204380a73c4065), C(77c2004bdd9e276a), C(45177e0b)}, + {C(dc78cb032c49217), C(112464083f83e03a), C(96ae53e28170c0f5), C(7c6fffe4)}, {C(441593e0da922dfe), C(936ef46061469b32), C(204a1921197ddd87), - C(50d8a70e7a8d8f56), C(256d150ae75dab76), C(e81f4c4a1989036a), - C(d0f8db365f9d7e00), C(50d8a70e7a8d8f56), C(256d150ae75dab76), - C(e81f4c4a1989036a), C(d0f8db365f9d7e00), C(753d686677b14522), - C(9f76e0cb6f2d0a66), C(ab14f95988ec0d39), C(97621d9da9c9812f), C(bbc78da4)}, {C(2ba3883d71cc2133), C(72f2bbb32bed1a3c), C(27e1bd96d4843251), - C(a90f761e8db1543a), C(c339e23c09703cd8), C(f0c6624c4b098fd3), - C(1bae2053e41fa4d9), C(a90f761e8db1543a), C(c339e23c09703cd8), - C(f0c6624c4b098fd3), C(1bae2053e41fa4d9), C(3589e273c22ba059), - C(63798246e5911a0b), C(18e710ec268fc5dc), C(714a122de1d074f3), C(c5c25d39)}, {C(f2b6d2adf8423600), C(7514e2f016a48722), C(43045743a50396ba), - C(23dacb811652ad4f), C(c982da480e0d4c7d), C(3a9c8ed5a399d0a9), - C(951b8d084691d4e4), C(23dacb811652ad4f), C(c982da480e0d4c7d), - C(3a9c8ed5a399d0a9), C(951b8d084691d4e4), C(d9f87b4988cff2f7), - C(217a191d986aa3bc), C(6ad23c56b480350), C(dd78673938ceb2e7), C(b6e5d06e)}, + C(b6e5d06e)}, {C(38fffe7f3680d63c), C(d513325255a7a6d1), C(31ed47790f6ca62f), - C(c801faaa0a2e331f), C(491dbc58279c7f88), C(9c0178848321c97a), - C(9d934f814f4d6a3c), C(c801faaa0a2e331f), C(491dbc58279c7f88), - C(9c0178848321c97a), C(9d934f814f4d6a3c), C(606a3e4fc8763192), - C(bc15cb36a677ee84), C(52d5904157e1fe71), C(1588dd8b1145b79b), C(6178504e)}, - {C(b7477bf0b9ce37c6), C(63b1c580a7fd02a4), C(f6433b9f10a5dac), - C(68dd76db9d64eca7), C(36297682b64b67), C(42b192d71f414b7a), - C(79692cef44fa0206), C(68dd76db9d64eca7), C(36297682b64b67), - C(42b192d71f414b7a), C(79692cef44fa0206), C(f0979252f4776d07), - C(4b87cd4f1c9bbf52), C(51b84bbc6312c710), C(150720fbf85428a7), - C(bd4c3637)}, + {C(b7477bf0b9ce37c6), C(63b1c580a7fd02a4), C(f6433b9f10a5dac), C(bd4c3637)}, {C(55bdb0e71e3edebd), C(c7ab562bcf0568bc), C(43166332f9ee684f), - C(b2e25964cd409117), C(a010599d6287c412), C(fa5d6461e768dda2), - C(cb3ce74e8ec4f906), C(b2e25964cd409117), C(a010599d6287c412), - C(fa5d6461e768dda2), C(cb3ce74e8ec4f906), C(6120abfd541a2610), - C(aa88b148cc95794d), C(2686ca35df6590e3), C(c6b02d18616ce94d), C(6e7ac474)}, - {C(782fa1b08b475e7), C(fb7138951c61b23b), C(9829105e234fb11e), - C(9a8c431f500ef06e), C(d848581a580b6c12), C(fecfe11e13a2bdb4), - C(6c4fa0273d7db08c), C(9a8c431f500ef06e), C(d848581a580b6c12), - C(fecfe11e13a2bdb4), C(6c4fa0273d7db08c), C(482f43bf5ae59fcb), - C(f651fbca105d79e6), C(f09f78695d865817), C(7a99d0092085cf47), - C(1fb4b518)}, + {C(782fa1b08b475e7), C(fb7138951c61b23b), C(9829105e234fb11e), C(1fb4b518)}, {C(c5dc19b876d37a80), C(15ffcff666cfd710), C(e8c30c72003103e2), - C(7870765b470b2c5d), C(78a9103ff960d82), C(7bb50ffc9fac74b3), - C(477e70ab2b347db2), C(7870765b470b2c5d), C(78a9103ff960d82), - C(7bb50ffc9fac74b3), C(477e70ab2b347db2), C(a625238bdf7c07cf), - C(1128d515174809f5), C(b0f1647e82f45873), C(17792d1c4f222c39), C(31d13d6d)}, {C(5e1141711d2d6706), C(b537f6dee8de6933), C(3af0a1fbbe027c54), - C(ea349dbc16c2e441), C(38a7455b6a877547), C(5f97b9750e365411), - C(e8cde7f93af49a3), C(ea349dbc16c2e441), C(38a7455b6a877547), - C(5f97b9750e365411), C(e8cde7f93af49a3), C(ba101925ec1f7e26), - C(d5e84cab8192c71e), C(e256427726fdd633), C(a4f38e2c6116890d), C(26fa72e3)}, - {C(782edf6da001234f), C(f48cbd5c66c48f3), C(808754d1e64e2a32), - C(5d9dde77353b1a6d), C(11f58c54581fa8b1), C(da90fa7c28c37478), - C(5e9a2eafc670a88a), C(5d9dde77353b1a6d), C(11f58c54581fa8b1), - C(da90fa7c28c37478), C(5e9a2eafc670a88a), C(e35e1bc172e011ef), - C(bf9255a4450ae7fe), C(55f85194e26bc55f), C(4f327873e14d0e54), - C(6a7433bf)}, + {C(782edf6da001234f), C(f48cbd5c66c48f3), C(808754d1e64e2a32), C(6a7433bf)}, {C(d26285842ff04d44), C(8f38d71341eacca9), C(5ca436f4db7a883c), - C(bf41e5376b9f0eec), C(2252d21eb7e1c0e9), C(f4b70a971855e732), - C(40c7695aa3662afd), C(bf41e5376b9f0eec), C(2252d21eb7e1c0e9), - C(f4b70a971855e732), C(40c7695aa3662afd), C(770fe19e16ab73bb), - C(d603ebda6393d749), C(e58c62439aa50dbd), C(96d51e5a02d2d7cf), C(4e6df758)}, {C(c6ab830865a6bae6), C(6aa8e8dd4b98815c), C(efe3846713c371e5), - C(a1924cbf0b5f9222), C(7f4872369c2b4258), C(cd6da30530f3ea89), - C(b7f8b9a704e6cea1), C(a1924cbf0b5f9222), C(7f4872369c2b4258), - C(cd6da30530f3ea89), C(b7f8b9a704e6cea1), C(fa06ff40433fd535), - C(fb1c36fe8f0737f1), C(bb7050561171f80), C(b1bc23235935d897), C(d57f63ea)}, - {C(44b3a1929232892), C(61dca0e914fc217), C(a607cc142096b964), - C(f7dbc8433c89b274), C(2f5f70581c9b7d32), C(39bf5e5fec82dcca), - C(8ade56388901a619), C(f7dbc8433c89b274), C(2f5f70581c9b7d32), - C(39bf5e5fec82dcca), C(8ade56388901a619), C(c1c6a725caab3ea9), - C(c1c7906c2f80b898), C(9c3871a04cc884e6), C(df01813cbbdf217f), - C(52ef73b3)}, - {C(4b603d7932a8de4f), C(fae64c464b8a8f45), C(8fafab75661d602a), - C(8ffe870ef4adc087), C(65bea2be41f55b54), C(82f3503f636aef1), - C(5f78a282378b6bb0), C(8ffe870ef4adc087), C(65bea2be41f55b54), - C(82f3503f636aef1), C(5f78a282378b6bb0), C(7bf2422c0beceddb), - C(9d238d4780114bd), C(7ad198311906597f), C(ec8f892c0422aca3), C(3cb36c3)}, + C(d57f63ea)}, + {C(44b3a1929232892), C(61dca0e914fc217), C(a607cc142096b964), C(52ef73b3)}, + {C(4b603d7932a8de4f), C(fae64c464b8a8f45), C(8fafab75661d602a), C(3cb36c3)}, {C(4ec0b54cf1566aff), C(30d2c7269b206bf4), C(77c22e82295e1061), - C(3df9b04434771542), C(feddce785ccb661f), C(a644aff716928297), - C(dd46aee73824b4ed), C(3df9b04434771542), C(feddce785ccb661f), - C(a644aff716928297), C(dd46aee73824b4ed), C(bf8d71879da29b02), - C(fc82dccbfc8022a0), C(31bfcd0d9f48d1d3), C(c64ee24d0e7b5f8b), C(72c39bea)}, {C(ed8b7a4b34954ff7), C(56432de31f4ee757), C(85bd3abaa572b155), - C(7d2c38a926dc1b88), C(5245b9eb4cd6791d), C(fb53ab03b9ad0855), - C(3664026c8fc669d7), C(7d2c38a926dc1b88), C(5245b9eb4cd6791d), - C(fb53ab03b9ad0855), C(3664026c8fc669d7), C(45024d5080bc196), - C(b236ebec2cc2740), C(27231ad0e3443be4), C(145780b63f809250), C(a65aa25c)}, + C(a65aa25c)}, {C(5d28b43694176c26), C(714cc8bc12d060ae), C(3437726273a83fe6), - C(864b1b28ec16ea86), C(6a78a5a4039ec2b9), C(8e959533e35a766), - C(347b7c22b75ae65f), C(864b1b28ec16ea86), C(6a78a5a4039ec2b9), - C(8e959533e35a766), C(347b7c22b75ae65f), C(5005892bb61e647c), - C(fe646519b4a1894d), C(cd801026f74a8a53), C(8713463e9a1ab9ce), C(74740539)}, {C(6a1ef3639e1d202e), C(919bc1bd145ad928), C(30f3f7e48c28a773), - C(2e8c49d7c7aaa527), C(5e2328fc8701db7c), C(89ef1afca81f7de8), - C(b1857db11985d296), C(2e8c49d7c7aaa527), C(5e2328fc8701db7c), - C(89ef1afca81f7de8), C(b1857db11985d296), C(17763d695f616115), - C(b8f7bf1fcdc8322c), C(cf0c61938ab07a27), C(1122d3e6edb4e866), C(c3ae3c26)}, - {C(159f4d9e0307b111), C(3e17914a5675a0c), C(af849bd425047b51), - C(3b69edadf357432b), C(3a2e311c121e6bf2), C(380fad1e288d57e5), - C(bf7c7e8ef0e3b83a), C(3b69edadf357432b), C(3a2e311c121e6bf2), - C(380fad1e288d57e5), C(bf7c7e8ef0e3b83a), C(92966d5f4356ae9b), - C(2a03fc66c4d6c036), C(2516d8bddb0d5259), C(b3ffe9737ff5090), C(f29db8a2)}, + {C(159f4d9e0307b111), C(3e17914a5675a0c), C(af849bd425047b51), C(f29db8a2)}, {C(cc0a840725a7e25b), C(57c69454396e193a), C(976eaf7eee0b4540), - C(cd7a46850b95e901), C(c57f7d060dda246f), C(6b9406ead64079bf), - C(11b28e20a573b7bd), C(cd7a46850b95e901), C(c57f7d060dda246f), - C(6b9406ead64079bf), C(11b28e20a573b7bd), C(2d6db356e9369ace), - C(dc0afe10fba193), C(5cdb10885dbbfce), C(5c700e205782e35a), C(1ef4cbf4)}, + C(1ef4cbf4)}, {C(a2b27ee22f63c3f1), C(9ebde0ce1b3976b2), C(2fe6a92a257af308), - C(8c1df927a930af59), C(a462f4423c9e384e), C(236542255b2ad8d9), - C(595d201a2c19d5bc), C(8c1df927a930af59), C(a462f4423c9e384e), - C(236542255b2ad8d9), C(595d201a2c19d5bc), C(22c87d4604a67f3), - C(585a06eb4bc44c4f), C(b4175a7ac7eabcd8), C(a457d3eeba14ab8c), C(a9be6c41)}, - {C(d8f2f234899bcab3), C(b10b037297c3a168), C(debea2c510ceda7f), - C(9498fefb890287ce), C(ae68c2be5b1a69a6), C(6189dfba34ed656c), - C(91658f95836e5206), C(9498fefb890287ce), C(ae68c2be5b1a69a6), - C(6189dfba34ed656c), C(91658f95836e5206), C(c0bb4fff32aecd4d), - C(94125f505a50eef9), C(6ac406e7cfbce5bb), C(344a4b1dcdb7f5d8), C(fa31801)}, + {C(d8f2f234899bcab3), C(b10b037297c3a168), C(debea2c510ceda7f), C(fa31801)}, {C(584f28543864844f), C(d7cee9fc2d46f20d), C(a38dca5657387205), - C(7a0b6dbab9a14e69), C(c6d0a9d6b0e31ac4), C(a674d85812c7cf6), - C(63538c0351049940), C(7a0b6dbab9a14e69), C(c6d0a9d6b0e31ac4), - C(a674d85812c7cf6), C(63538c0351049940), C(9710e5f0bc93d1d), - C(c2bea5bd7c54ddd4), C(48739af2bed0d32d), C(ba2c4e09e21fba85), C(8331c5d8)}, - {C(a94be46dd9aa41af), C(a57e5b7723d3f9bd), C(34bf845a52fd2f), - C(843b58463c8df0ae), C(74b258324e916045), C(bdd7353230eb2b38), - C(fad31fced7abade5), C(843b58463c8df0ae), C(74b258324e916045), - C(bdd7353230eb2b38), C(fad31fced7abade5), C(2436aeafb0046f85), - C(65bc9af9e5e33161), C(92733b1b3ae90628), C(f48143eaf78a7a89), - C(e9876db8)}, + {C(a94be46dd9aa41af), C(a57e5b7723d3f9bd), C(34bf845a52fd2f), C(e9876db8)}, {C(9a87bea227491d20), C(a468657e2b9c43e7), C(af9ba60db8d89ef7), - C(cc76f429ea7a12bb), C(5f30eaf2bb14870a), C(434e824cb3e0cd11), - C(431a4d382e39d16e), C(cc76f429ea7a12bb), C(5f30eaf2bb14870a), - C(434e824cb3e0cd11), C(431a4d382e39d16e), C(9e51f913c4773a8), - C(32ab1925823d0add), C(99c61b54c1d8f69d), C(38cfb80f02b43b1f), C(27b0604e)}, {C(27688c24958d1a5c), C(e3b4a1c9429cf253), C(48a95811f70d64bc), - C(328063229db22884), C(67e9c95f8ba96028), C(7c6bf01c60436075), - C(fa55161e7d9030b2), C(328063229db22884), C(67e9c95f8ba96028), - C(7c6bf01c60436075), C(fa55161e7d9030b2), C(dadbc2f0dab91681), - C(da39d7a4934ca11), C(162e845d24c1b45c), C(eb5b9dcd8c6ed31b), C(dcec07f2)}, + C(dcec07f2)}, {C(5d1d37790a1873ad), C(ed9cd4bcc5fa1090), C(ce51cde05d8cd96a), - C(f72c26e624407e66), C(a0eb541bdbc6d409), C(c3f40a2f40b3b213), - C(6a784de68794492d), C(f72c26e624407e66), C(a0eb541bdbc6d409), - C(c3f40a2f40b3b213), C(6a784de68794492d), C(10a38a23dbef7937), - C(6a5560f853252278), C(c3387bbf3c7b82ba), C(fbee7c12eb072805), C(cff0a82a)}, {C(1f03fd18b711eea9), C(566d89b1946d381a), C(6e96e83fc92563ab), - C(405f66cf8cae1a32), C(d7261740d8f18ce6), C(fea3af64a413d0b2), - C(d64d1810e83520fe), C(405f66cf8cae1a32), C(d7261740d8f18ce6), - C(fea3af64a413d0b2), C(d64d1810e83520fe), C(e1334a00a580c6e8), - C(454049e1b52c15f), C(8895d823d9778247), C(efa7f2e88b826618), C(fec83621)}, - {C(f0316f286cf527b6), C(f84c29538de1aa5a), C(7612ed3c923d4a71), - C(d4eccebe9393ee8a), C(2eb7867c2318cc59), C(1ce621fd700fe396), - C(686450d7a346878a), C(d4eccebe9393ee8a), C(2eb7867c2318cc59), - C(1ce621fd700fe396), C(686450d7a346878a), C(75a5f37579f8b4cb), - C(500cc16eb6541dc7), C(b7b02317b539d9a6), C(3519ddff5bc20a29), C(743d8dc)}, + C(fec83621)}, + {C(f0316f286cf527b6), C(f84c29538de1aa5a), C(7612ed3c923d4a71), C(743d8dc)}, {C(297008bcb3e3401d), C(61a8e407f82b0c69), C(a4a35bff0524fa0e), - C(7a61d8f552a53442), C(821d1d8d8cfacf35), C(7cc06361b86d0559), - C(119b617a8c2be199), C(7a61d8f552a53442), C(821d1d8d8cfacf35), - C(7cc06361b86d0559), C(119b617a8c2be199), C(2996487da6721759), - C(61a901376070b91d), C(d88dee12ae9c9b3c), C(5665491be1fa53a7), C(64d41d26)}, - {C(43c6252411ee3be), C(b4ca1b8077777168), C(2746dc3f7da1737f), - C(2247a4b2058d1c50), C(1b3fa184b1d7bcc0), C(deb85613995c06ed), - C(cbe1d957485a3ccd), C(2247a4b2058d1c50), C(1b3fa184b1d7bcc0), - C(deb85613995c06ed), C(cbe1d957485a3ccd), C(dfe241f8f33c96b6), - C(6597eb05019c2109), C(da344b2a63a219cf), C(79b8e3887612378a), - C(acd90c81)}, + {C(43c6252411ee3be), C(b4ca1b8077777168), C(2746dc3f7da1737f), C(acd90c81)}, {C(ce38a9a54fad6599), C(6d6f4a90b9e8755e), C(c3ecc79ff105de3f), - C(e8b9ee96efa2d0e), C(90122905c4ab5358), C(84f80c832d71979c), - C(229310f3ffbbf4c6), C(e8b9ee96efa2d0e), C(90122905c4ab5358), - C(84f80c832d71979c), C(229310f3ffbbf4c6), C(cc9eb42100cd63a7), - C(7a283f2f3da7b9f), C(359b061d314e7a72), C(d0d959720028862), C(7c746a4b)}, - {C(270a9305fef70cf), C(600193999d884f3a), C(f4d49eae09ed8a1), - C(2e091b85660f1298), C(bfe37fae1cdd64c9), C(8dddfbab930f6494), - C(2ccf4b08f5d417a), C(2e091b85660f1298), C(bfe37fae1cdd64c9), - C(8dddfbab930f6494), C(2ccf4b08f5d417a), C(365c2ee85582fe6), - C(dee027bcd36db62a), C(b150994d3c7e5838), C(fdfd1a0e692e436d), - C(b1047e99)}, + C(7c746a4b)}, + {C(270a9305fef70cf), C(600193999d884f3a), C(f4d49eae09ed8a1), C(b1047e99)}, {C(e71be7c28e84d119), C(eb6ace59932736e6), C(70c4397807ba12c5), - C(7a9d77781ac53509), C(4489c3ccfda3b39c), C(fa722d4f243b4964), - C(25f15800bffdd122), C(7a9d77781ac53509), C(4489c3ccfda3b39c), - C(fa722d4f243b4964), C(25f15800bffdd122), C(ed85e4157fbd3297), - C(aab1967227d59efd), C(2199631212eb3839), C(3e4c19359aae1cc2), C(d1fd1068)}, {C(b5b58c24b53aaa19), C(d2a6ab0773dd897f), C(ef762fe01ecb5b97), - C(9deefbcfa4cab1f1), C(b58f5943cd2492ba), C(a96dcc4d1f4782a7), - C(102b62a82309dde5), C(9deefbcfa4cab1f1), C(b58f5943cd2492ba), - C(a96dcc4d1f4782a7), C(102b62a82309dde5), C(35fe52684763b338), - C(afe2616651eaad1f), C(43e38715bdfa05e7), C(83c9ba83b5ec4a40), C(56486077)}, {C(44dd59bd301995cf), C(3ccabd76493ada1a), C(540db4c87d55ef23), - C(cfc6d7adda35797), C(14c7d1f32332cf03), C(2d553ffbff3be99d), - C(c91c4ee0cb563182), C(cfc6d7adda35797), C(14c7d1f32332cf03), - C(2d553ffbff3be99d), C(c91c4ee0cb563182), C(9aa5e507f49136f0), - C(760c5dd1a82c4888), C(beea7e974a1cfb5c), C(640b247774fe4bf7), C(6069be80)}, - {C(b4d4789eb6f2630b), C(bf6973263ce8ef0e), C(d1c75c50844b9d3), - C(bce905900c1ec6ea), C(c30f304f4045487d), C(a5c550166b3a142b), - C(2f482b4e35327287), C(bce905900c1ec6ea), C(c30f304f4045487d), - C(a5c550166b3a142b), C(2f482b4e35327287), C(15b21ddddf355438), - C(496471fa3006bab), C(2a8fd458d06c1a32), C(db91e8ae812f0b8d), C(2078359b)}, + {C(b4d4789eb6f2630b), C(bf6973263ce8ef0e), C(d1c75c50844b9d3), C(2078359b)}, {C(12807833c463737c), C(58e927ea3b3776b4), C(72dd20ef1c2f8ad0), - C(910b610de7a967bf), C(801bc862120f6bf5), C(9653efeed5897681), - C(f5367ff83e9ebbb3), C(910b610de7a967bf), C(801bc862120f6bf5), - C(9653efeed5897681), C(f5367ff83e9ebbb3), C(cf56d489afd1b0bf), - C(c7c793715cae3de8), C(631f91d64abae47c), C(5f1f42fb14a444a2), C(9ea21004)}, {C(e88419922b87176f), C(bcf32f41a7ddbf6f), C(d6ebefd8085c1a0f), - C(d1d44fe99451ef72), C(ec951ba8e51e3545), C(c0ca86b360746e96), - C(aa679cc066a8040b), C(d1d44fe99451ef72), C(ec951ba8e51e3545), - C(c0ca86b360746e96), C(aa679cc066a8040b), C(51065861ece6ffc1), - C(76777368a2997e11), C(87f278f46731100c), C(bbaa4140bdba4527), C(9c9cfe88)}, {C(105191e0ec8f7f60), C(5918dbfcca971e79), C(6b285c8a944767b9), - C(d3e86ac4f5eccfa4), C(e5399df2b106ca1), C(814aadfacd217f1d), - C(2754e3def1c405a9), C(d3e86ac4f5eccfa4), C(e5399df2b106ca1), - C(814aadfacd217f1d), C(2754e3def1c405a9), C(99290323b9f06e74), - C(a9782e043f271461), C(13c8b3b8c275a860), C(6038d620e581e9e7), C(b70a6ddd)}, {C(a5b88bf7399a9f07), C(fca3ddfd96461cc4), C(ebe738fdc0282fc6), - C(69afbc800606d0fb), C(6104b97a9db12df7), C(fcc09198bb90bf9f), - C(c5e077e41a65ba91), C(69afbc800606d0fb), C(6104b97a9db12df7), - C(fcc09198bb90bf9f), C(c5e077e41a65ba91), C(db261835ee8aa08e), - C(db0ee662e5796dc9), C(fc1880ecec499e5f), C(648866fbe1502034), C(dea37298)}, {C(d08c3f5747d84f50), C(4e708b27d1b6f8ac), C(70f70fd734888606), - C(909ae019d761d019), C(368bf4aab1b86ef9), C(308bd616d5460239), - C(4fd33269f76783ea), C(909ae019d761d019), C(368bf4aab1b86ef9), - C(308bd616d5460239), C(4fd33269f76783ea), C(7d53b37c19713eab), - C(6bba6eabda58a897), C(91abb50efc116047), C(4e902f347e0e0e35), C(8f480819)}, - {C(2f72d12a40044b4b), C(889689352fec53de), C(f03e6ad87eb2f36), - C(ef79f28d874b9e2d), C(b512089e8e63b76c), C(24dc06833bf193a9), - C(3c23308ba8e99d7e), C(ef79f28d874b9e2d), C(b512089e8e63b76c), - C(24dc06833bf193a9), C(3c23308ba8e99d7e), C(5ceff7b85cacefb7), - C(ef390338898cd73), C(b12967d7d2254f54), C(de874cbd8aef7b75), C(30b3b16)}, + {C(2f72d12a40044b4b), C(889689352fec53de), C(f03e6ad87eb2f36), C(30b3b16)}, {C(aa1f61fdc5c2e11e), C(c2c56cd11277ab27), C(a1e73069fdf1f94f), - C(8184bab36bb79df0), C(c81929ce8655b940), C(301b11bf8a4d8ce8), - C(73126fd45ab75de9), C(8184bab36bb79df0), C(c81929ce8655b940), - C(301b11bf8a4d8ce8), C(73126fd45ab75de9), C(4bd6f76e4888229a), - C(9aae355b54a756d5), C(ca3de9726f6e99d5), C(83f80cac5bc36852), C(f31bc4e8)}, {C(9489b36fe2246244), C(3355367033be74b8), C(5f57c2277cbce516), - C(bc61414f9802ecaf), C(8edd1e7a50562924), C(48f4ab74a35e95f2), - C(cc1afcfd99a180e7), C(bc61414f9802ecaf), C(8edd1e7a50562924), - C(48f4ab74a35e95f2), C(cc1afcfd99a180e7), C(517dd5e3acf66110), - C(7dd3ad9e8978b30d), C(1f6d5dfc70de812b), C(947daaba6441aaf3), C(419f953b)}, {C(358d7c0476a044cd), C(e0b7b47bcbd8854f), C(ffb42ec696705519), - C(d45e44c263e95c38), C(df61db53923ae3b1), C(f2bc948cc4fc027c), - C(8a8000c6066772a3), C(d45e44c263e95c38), C(df61db53923ae3b1), - C(f2bc948cc4fc027c), C(8a8000c6066772a3), C(9fd93c942d31fa17), - C(d7651ecebe09cbd3), C(68682cefb6a6f165), C(541eb99a2dcee40e), C(20e9e76d)}, {C(b0c48df14275265a), C(9da4448975905efa), C(d716618e414ceb6d), - C(30e888af70df1e56), C(4bee54bd47274f69), C(178b4059e1a0afe5), - C(6e2c96b7f58e5178), C(30e888af70df1e56), C(4bee54bd47274f69), - C(178b4059e1a0afe5), C(6e2c96b7f58e5178), C(bb429d3b9275e9bc), - C(c198013f09cafdc6), C(ec0a6ee4fb5de348), C(744e1e8ed2eb1eb0), C(646f0ff8)}, {C(daa70bb300956588), C(410ea6883a240c6d), C(f5c8239fb5673eb3), - C(8b1d7bb4903c105f), C(cfb1c322b73891d4), C(5f3b792b22f07297), - C(fd64061f8be86811), C(8b1d7bb4903c105f), C(cfb1c322b73891d4), - C(5f3b792b22f07297), C(fd64061f8be86811), C(1d2db712921cfc2b), - C(cd1b2b2f2cee18ae), C(6b6f8790dc7feb09), C(46c179efa3f0f518), C(eeb7eca8)}, - {C(4ec97a20b6c4c7c2), C(5913b1cd454f29fd), C(a9629f9daf06d685), - C(852c9499156a8f3), C(3a180a6abfb79016), C(9fc3c4764037c3c9), - C(2890c42fc0d972cf), C(852c9499156a8f3), C(3a180a6abfb79016), - C(9fc3c4764037c3c9), C(2890c42fc0d972cf), C(1f92231d4e537651), - C(fab8bb07aa54b7b9), C(e05d2d771c485ed4), C(d50b34bf808ca731), C(8112bb9)}, + {C(4ec97a20b6c4c7c2), C(5913b1cd454f29fd), C(a9629f9daf06d685), C(8112bb9)}, {C(5c3323628435a2e8), C(1bea45ce9e72a6e3), C(904f0a7027ddb52e), - C(939f31de14dcdc7b), C(a68fdf4379df068), C(f169e1f0b835279d), - C(7498e432f9619b27), C(939f31de14dcdc7b), C(a68fdf4379df068), - C(f169e1f0b835279d), C(7498e432f9619b27), C(1aa2a1f11088e785), - C(d6ad72f45729de78), C(9a63814157c80267), C(55538e35c648e435), C(85a6d477)}, {C(c1ef26bea260abdb), C(6ee423f2137f9280), C(df2118b946ed0b43), - C(11b87fb1b900cc39), C(e33e59b90dd815b1), C(aa6cb5c4bafae741), - C(739699951ca8c713), C(11b87fb1b900cc39), C(e33e59b90dd815b1), - C(aa6cb5c4bafae741), C(739699951ca8c713), C(2b4389a967310077), - C(1d5382568a31c2c9), C(55d1e787fbe68991), C(277c254bc31301e7), C(56f76c84)}, {C(6be7381b115d653a), C(ed046190758ea511), C(de6a45ffc3ed1159), - C(a64760e4041447d0), C(e3eac49f3e0c5109), C(dd86c4d4cb6258e2), - C(efa9857afd046c7f), C(a64760e4041447d0), C(e3eac49f3e0c5109), - C(dd86c4d4cb6258e2), C(efa9857afd046c7f), C(fab793dae8246f16), - C(c9e3b121b31d094c), C(a2a0f55858465226), C(dba6f0ff39436344), C(9af45d55)}, {C(ae3eece1711b2105), C(14fd3f4027f81a4a), C(abb7e45177d151db), - C(501f3e9b18861e44), C(465201170074e7d8), C(96d5c91970f2cb12), - C(40fd28c43506c95d), C(501f3e9b18861e44), C(465201170074e7d8), - C(96d5c91970f2cb12), C(40fd28c43506c95d), C(e86c4b07802aaff3), - C(f317d14112372a70), C(641b13e587711650), C(4915421ab1090eaa), C(d1c33760)}, {C(376c28588b8fb389), C(6b045e84d8491ed2), C(4e857effb7d4e7dc), - C(154dd79fd2f984b4), C(f11171775622c1c3), C(1fbe30982e78e6f0), - C(a460a15dcf327e44), C(154dd79fd2f984b4), C(f11171775622c1c3), - C(1fbe30982e78e6f0), C(a460a15dcf327e44), C(f359e0900cc3d582), - C(7e11070447976d00), C(324e6daf276ea4b5), C(7aa6e2df0cc94fa2), C(c56bbf69)}, {C(58d943503bb6748f), C(419c6c8e88ac70f6), C(586760cbf3d3d368), - C(b7e164979d5ccfc1), C(12cb4230d26bf286), C(f1bf910d44bd84cb), - C(b32c24c6a40272), C(b7e164979d5ccfc1), C(12cb4230d26bf286), - C(f1bf910d44bd84cb), C(b32c24c6a40272), C(11ed12e34c48c039), - C(b0c2538e51d0a6ac), C(4269bb773e1d553a), C(e35a9dbabd34867), C(abecfb9b)}, + C(abecfb9b)}, {C(dfff5989f5cfd9a1), C(bcee2e7ea3a96f83), C(681c7874adb29017), - C(3ff6c8ac7c36b63a), C(48bc8831d849e326), C(30b078e76b0214e2), - C(42954e6ad721b920), C(3ff6c8ac7c36b63a), C(48bc8831d849e326), - C(30b078e76b0214e2), C(42954e6ad721b920), C(f9aeb33d164b4472), - C(7b353b110831dbdc), C(16f64c82f44ae17b), C(b71244cc164b3b2b), C(8de13255)}, {C(7fb19eb1a496e8f5), C(d49e5dfdb5c0833f), C(c0d5d7b2f7c48dc7), - C(1a57313a32f22dde), C(30af46e49850bf8b), C(aa0fe8d12f808f83), - C(443e31d70873bb6b), C(1a57313a32f22dde), C(30af46e49850bf8b), - C(aa0fe8d12f808f83), C(443e31d70873bb6b), C(bbeb67c49c9fdc13), - C(18f1e2a88f59f9d5), C(fb1b05038e5def11), C(d0450b5ce4c39c52), C(a98ee299)}, {C(5dba5b0dadccdbaa), C(4ba8da8ded87fcdc), C(f693fdd25badf2f0), - C(e9029e6364286587), C(ae69f49ecb46726c), C(18e002679217c405), - C(bd6d66e85332ae9f), C(e9029e6364286587), C(ae69f49ecb46726c), - C(18e002679217c405), C(bd6d66e85332ae9f), C(6bf330b1c353dd2a), - C(74e9f2e71e3a4152), C(3f85560b50f6c413), C(d33a52a47eaed2b4), C(3015f556)}, {C(688bef4b135a6829), C(8d31d82abcd54e8e), C(f95f8a30d55036d7), - C(3d8c90e27aa2e147), C(2ec937ce0aa236b4), C(89b563996d3a0b78), - C(39b02413b23c3f08), C(3d8c90e27aa2e147), C(2ec937ce0aa236b4), - C(89b563996d3a0b78), C(39b02413b23c3f08), C(8d475a2e64faf2d2), - C(48567f7dca46ecaf), C(254cda08d5f87a6d), C(ec6ae9f729c47039), C(5a430e29)}, {C(d8323be05433a412), C(8d48fa2b2b76141d), C(3d346f23978336a5), - C(4d50c7537562033f), C(57dc7625b61dfe89), C(9723a9f4c08ad93a), - C(5309596f48ab456b), C(4d50c7537562033f), C(57dc7625b61dfe89), - C(9723a9f4c08ad93a), C(5309596f48ab456b), C(7e453088019d220f), - C(8776067ba6ab9714), C(67e1d06bd195de39), C(74a1a32f8994b918), C(2797add0)}, {C(3b5404278a55a7fc), C(23ca0b327c2d0a81), C(a6d65329571c892c), - C(45504801e0e6066b), C(86e6c6d6152a3d04), C(4f3db1c53eca2952), - C(d24d69b3e9ef10f3), C(45504801e0e6066b), C(86e6c6d6152a3d04), - C(4f3db1c53eca2952), C(d24d69b3e9ef10f3), C(93a0de2219e66a70), - C(8932c7115ccb1f8a), C(5ef503fdf2841a8c), C(38064dd9efa80a41), C(27d55016)}, {C(2a96a3f96c5e9bbc), C(8caf8566e212dda8), C(904de559ca16e45e), - C(f13bc2d9c2fe222e), C(be4ccec9a6cdccfd), C(37b2cbdd973a3ac9), - C(7b3223cd9c9497be), C(f13bc2d9c2fe222e), C(be4ccec9a6cdccfd), - C(37b2cbdd973a3ac9), C(7b3223cd9c9497be), C(d5904440f376f889), - C(62b13187699c473c), C(4751b89251f26726), C(9500d84fa3a61ba8), C(84945a82)}, {C(22bebfdcc26d18ff), C(4b4d8dcb10807ba1), C(40265eee30c6b896), - C(3752b423073b119a), C(377dc5eb7c662bdb), C(2b9f07f93a6c25b9), - C(96f24ede2bdc0718), C(3752b423073b119a), C(377dc5eb7c662bdb), - C(2b9f07f93a6c25b9), C(96f24ede2bdc0718), C(f7699b12c31417bd), - C(17b366f401c58b2), C(bf60188d5f437b37), C(484436e56df17f04), C(3ef7e224)}, + C(3ef7e224)}, {C(627a2249ec6bbcc2), C(c0578b462a46735a), C(4974b8ee1c2d4f1f), - C(ebdbb918eb6d837f), C(8fb5f218dd84147c), C(c77dd1f881df2c54), - C(62eac298ec226dc3), C(ebdbb918eb6d837f), C(8fb5f218dd84147c), - C(c77dd1f881df2c54), C(62eac298ec226dc3), C(43eded83c4b60bd0), - C(9a0a403b5487503b), C(25f305d9147f0bda), C(3ad417f511bc1e64), C(35ed8dc8)}, - {C(3abaf1667ba2f3e0), C(ee78476b5eeadc1), C(7e56ac0a6ca4f3f4), - C(f1b9b413df9d79ed), C(a7621b6fd02db503), C(d92f7ba9928a4ffe), - C(53f56babdcae96a6), C(f1b9b413df9d79ed), C(a7621b6fd02db503), - C(d92f7ba9928a4ffe), C(53f56babdcae96a6), C(5302b89fc48713ab), - C(d03e3b04dbe7a2f2), C(fa74ef8af6d376a7), C(103c8cdea1050ef2), - C(6a75e43d)}, + {C(3abaf1667ba2f3e0), C(ee78476b5eeadc1), C(7e56ac0a6ca4f3f4), C(6a75e43d)}, {C(3931ac68c5f1b2c9), C(efe3892363ab0fb0), C(40b707268337cd36), - C(a53a6b64b1ac85c9), C(d50e7f86ee1b832b), C(7bab08fdd26ba0a4), - C(7587743c18fe2475), C(a53a6b64b1ac85c9), C(d50e7f86ee1b832b), - C(7bab08fdd26ba0a4), C(7587743c18fe2475), C(e3b5d5d490cf5761), - C(dfc053f7d065edd5), C(42ffd8d5fb70129f), C(599ca38677cccdc3), C(235d9805)}, - {C(b98fb0606f416754), C(46a6e5547ba99c1e), C(c909d82112a8ed2), - C(dbfaae9642b3205a), C(f676a1339402bcb9), C(f4f12a5b1ac11f29), - C(7db8bad81249dee4), C(dbfaae9642b3205a), C(f676a1339402bcb9), - C(f4f12a5b1ac11f29), C(7db8bad81249dee4), C(b26e46f2da95922e), - C(2aaedd5e12e3c611), C(a0e2d9082966074), C(c64da8a167add63d), C(f7d69572)}, + {C(b98fb0606f416754), C(46a6e5547ba99c1e), C(c909d82112a8ed2), C(f7d69572)}, {C(7f7729a33e58fcc4), C(2e4bc1e7a023ead4), C(e707008ea7ca6222), - C(47418a71800334a0), C(d10395d8fc64d8a4), C(8257a30062cb66f), - C(6786f9b2dc1ff18a), C(47418a71800334a0), C(d10395d8fc64d8a4), - C(8257a30062cb66f), C(6786f9b2dc1ff18a), C(5633f437bb2f180f), - C(e5a3a405737d22d6), C(ca0ff1ef6f7f0b74), C(d0ae600684b16df8), C(bacd0199)}, {C(42a0aa9ce82848b3), C(57232730e6bee175), C(f89bb3f370782031), - C(caa33cf9b4f6619c), C(b2c8648ad49c209f), C(9e89ece0712db1c0), - C(101d8274a711a54b), C(caa33cf9b4f6619c), C(b2c8648ad49c209f), - C(9e89ece0712db1c0), C(101d8274a711a54b), C(538e79f1e70135cd), - C(e1f5a76f983c844e), C(653c082fd66088fc), C(1b9c9b464b654958), C(e428f50e)}, {C(6b2c6d38408a4889), C(de3ef6f68fb25885), C(20754f456c203361), - C(941f5023c0c943f9), C(dfdeb9564fd66f24), C(2140cec706b9d406), - C(7b22429b131e9c72), C(941f5023c0c943f9), C(dfdeb9564fd66f24), - C(2140cec706b9d406), C(7b22429b131e9c72), C(94215c22eb940f45), - C(d28b9ed474f7249a), C(6f25e88f2fbf9f56), C(b6718f9e605b38ac), C(81eaaad3)}, {C(930380a3741e862a), C(348d28638dc71658), C(89dedcfd1654ea0d), - C(7e7f61684080106), C(837ace9794582976), C(5ac8ca76a357eb1b), - C(32b58308625661fb), C(7e7f61684080106), C(837ace9794582976), - C(5ac8ca76a357eb1b), C(32b58308625661fb), C(c09705c4572025d9), - C(f9187f6af0291303), C(1c0edd8ee4b02538), C(e6cb105daa0578a), C(addbd3e3)}, + C(addbd3e3)}, {C(94808b5d2aa25f9a), C(cec72968128195e0), C(d9f4da2bdc1e130f), - C(272d8dd74f3006cc), C(ec6c2ad1ec03f554), C(4ad276b249a5d5dd), - C(549a22a17c0cde12), C(272d8dd74f3006cc), C(ec6c2ad1ec03f554), - C(4ad276b249a5d5dd), C(549a22a17c0cde12), C(602119cb824d7cde), - C(f4d3cef240ef35fa), C(e889895e01911bc7), C(785a7e5ac20e852b), C(e66dbca0)}, {C(b31abb08ae6e3d38), C(9eb9a95cbd9e8223), C(8019e79b7ee94ea9), - C(7b2271a7a3248e22), C(3b4f700e5a0ba523), C(8ebc520c227206fe), - C(da3f861490f5d291), C(7b2271a7a3248e22), C(3b4f700e5a0ba523), - C(8ebc520c227206fe), C(da3f861490f5d291), C(d08a689f9f3aa60e), - C(547c1b97a068661f), C(4b15a67fa29172f0), C(eaf40c085191d80f), C(afe11fd5)}, {C(dccb5534a893ea1a), C(ce71c398708c6131), C(fe2396315457c164), - C(3f1229f4d0fd96fb), C(33130aa5fa9d43f2), C(e42693d5b34e63ab), - C(2f4ef2be67f62104), C(3f1229f4d0fd96fb), C(33130aa5fa9d43f2), - C(e42693d5b34e63ab), C(2f4ef2be67f62104), C(372e5153516e37b9), - C(af9ec142ab12cc86), C(777920c09345e359), C(e7c4a383bef8adc6), C(a71a406f)}, {C(6369163565814de6), C(8feb86fb38d08c2f), C(4976933485cc9a20), - C(7d3e82d5ba29a90d), C(d5983cc93a9d126a), C(37e9dfd950e7b692), - C(80673be6a7888b87), C(7d3e82d5ba29a90d), C(d5983cc93a9d126a), - C(37e9dfd950e7b692), C(80673be6a7888b87), C(57f732dc600808bc), - C(59477199802cc78b), C(f824810eb8f2c2de), C(c4a3437f05b3b61c), C(9d90eaf5)}, {C(edee4ff253d9f9b3), C(96ef76fb279ef0ad), C(a4d204d179db2460), - C(1f3dcdfa513512d6), C(4dc7ec07283117e4), C(4438bae88ae28bf9), - C(aa7eae72c9244a0d), C(1f3dcdfa513512d6), C(4dc7ec07283117e4), - C(4438bae88ae28bf9), C(aa7eae72c9244a0d), C(b9aedc8d3ecc72df), - C(b75a8eb090a77d62), C(6b15677f9cd91507), C(51d8282cb3a9ddbf), C(6665db10)}, {C(941993df6e633214), C(929bc1beca5b72c6), C(141fc52b8d55572d), - C(b3b782ad308f21ed), C(4f2676485041dee0), C(bfe279aed5cb4bc8), - C(2a62508a467a22ff), C(b3b782ad308f21ed), C(4f2676485041dee0), - C(bfe279aed5cb4bc8), C(2a62508a467a22ff), C(e74d29eab742385d), - C(56b05cd90ecfc293), C(c603728ea73f8844), C(8638fcd21bc692c4), C(9c977cbf)}, {C(859838293f64cd4c), C(484403b39d44ad79), C(bf674e64d64b9339), - C(44d68afda9568f08), C(478568ed51ca1d65), C(679c204ad3d9e766), - C(b28e788878488dc1), C(44d68afda9568f08), C(478568ed51ca1d65), - C(679c204ad3d9e766), C(b28e788878488dc1), C(d001a84d3a84fae6), - C(d376958fe4cb913e), C(17435277e36c86f0), C(23657b263c347aa6), C(ee83ddd4)}, - {C(c19b5648e0d9f555), C(328e47b2b7562993), C(e756b92ba4bd6a51), - C(c3314e362764ddb8), C(6481c084ee9ec6b5), C(ede23fb9a251771), - C(bd617f2643324590), C(c3314e362764ddb8), C(6481c084ee9ec6b5), - C(ede23fb9a251771), C(bd617f2643324590), C(d2d30c9b95e030f5), - C(8a517312ffc5795e), C(8b1f325033bd535e), C(3ee6e867e03f2892), C(26519cc)}, + {C(c19b5648e0d9f555), C(328e47b2b7562993), C(e756b92ba4bd6a51), C(26519cc)}, {C(f963b63b9006c248), C(9e9bf727ffaa00bc), C(c73bacc75b917e3a), - C(2c6aa706129cc54c), C(17a706f59a49f086), C(c7c1eec455217145), - C(6adfdc6e07602d42), C(2c6aa706129cc54c), C(17a706f59a49f086), - C(c7c1eec455217145), C(6adfdc6e07602d42), C(fb75fca30d848dd2), - C(5228c9ed14653ed4), C(953958910153b1a2), C(a430103a24f42a5d), C(a485a53f)}, {C(6a8aa0852a8c1f3b), C(c8f1e5e206a21016), C(2aa554aed1ebb524), - C(fc3e3c322cd5d89b), C(b7e3911dc2bd4ebb), C(fcd6da5e5fae833a), - C(51ed3c41f87f9118), C(fc3e3c322cd5d89b), C(b7e3911dc2bd4ebb), - C(fcd6da5e5fae833a), C(51ed3c41f87f9118), C(f31750cbc19c420a), - C(186dab1abada1d86), C(ca7f88cb894b3cd7), C(2859eeb1c373790c), C(f62bc412)}, {C(740428b4d45e5fb8), C(4c95a4ce922cb0a5), C(e99c3ba78feae796), - C(914f1ea2fdcebf5c), C(9566453c07cd0601), C(9841bf66d0462cd), - C(79140c1c18536aeb), C(914f1ea2fdcebf5c), C(9566453c07cd0601), - C(9841bf66d0462cd), C(79140c1c18536aeb), C(a963b930b05820c2), - C(6a7d9fa0c8c45153), C(64214c40d07cf39b), C(7057daf1d806c014), C(8975a436)}, - {C(658b883b3a872b86), C(2f0e303f0f64827a), C(975337e23dc45e1), - C(99468a917986162b), C(7b31434aac6e0af0), C(f6915c1562c7d82f), - C(e4071d82a6dd71db), C(99468a917986162b), C(7b31434aac6e0af0), - C(f6915c1562c7d82f), C(e4071d82a6dd71db), C(5f5331f077b5d996), - C(7b314ba21b747a4f), C(5a73cb9521da17f5), C(12ed435fae286d86), - C(94ff7f41)}, - {C(6df0a977da5d27d4), C(891dd0e7cb19508), C(fd65434a0b71e680), - C(8799e4740e573c50), C(9e739b52d0f341e8), C(cdfd34ba7d7b03eb), - C(5061812ce6c88499), C(8799e4740e573c50), C(9e739b52d0f341e8), - C(cdfd34ba7d7b03eb), C(5061812ce6c88499), C(612b8d8f2411dc5c), - C(878bd883d29c7787), C(47a846727182bb), C(ec4949508c8b3b9a), C(760aa031)}, - {C(a900275464ae07ef), C(11f2cfda34beb4a3), C(9abf91e5a1c38e4), - C(8063d80ab26f3d6d), C(4177b4b9b4f0393f), C(6de42ba8672b9640), - C(d0bccdb72c51c18), C(8063d80ab26f3d6d), C(4177b4b9b4f0393f), - C(6de42ba8672b9640), C(d0bccdb72c51c18), C(af3f611b7f22cf12), - C(3863c41492645755), C(928c7a616a8f14f9), C(a82c78eb2eadc58b), - C(3bda76df)}, + {C(658b883b3a872b86), C(2f0e303f0f64827a), C(975337e23dc45e1), C(94ff7f41)}, + {C(6df0a977da5d27d4), C(891dd0e7cb19508), C(fd65434a0b71e680), C(760aa031)}, + {C(a900275464ae07ef), C(11f2cfda34beb4a3), C(9abf91e5a1c38e4), C(3bda76df)}, {C(810bc8aa0c40bcb0), C(448a019568d01441), C(f60ec52f60d3aeae), - C(52c44837aa6dfc77), C(15d8d8fccdd6dc5b), C(345b793ccfa93055), - C(932160fe802ca975), C(52c44837aa6dfc77), C(15d8d8fccdd6dc5b), - C(345b793ccfa93055), C(932160fe802ca975), C(a624b0dd93fc18cd), - C(d955b254c2037f1e), C(e540533d370a664c), C(2ba4ec12514e9d7), C(498e2e65)}, + C(498e2e65)}, {C(22036327deb59ed7), C(adc05ceb97026a02), C(48bff0654262672b), - C(c791b313aba3f258), C(443c7757a4727bee), C(e30e4b2372171bdf), - C(f3db986c4156f3cb), C(c791b313aba3f258), C(443c7757a4727bee), - C(e30e4b2372171bdf), C(f3db986c4156f3cb), C(a939aefab97c6e15), - C(dbeb8acf1d5b0e6c), C(1e0eab667a795bba), C(80dd539902df4d50), C(d38deb48)}, {C(7d14dfa9772b00c8), C(595735efc7eeaed7), C(29872854f94c3507), - C(bc241579d8348401), C(16dc832804d728f0), C(e9cc71ae64e3f09e), - C(bef634bc978bac31), C(bc241579d8348401), C(16dc832804d728f0), - C(e9cc71ae64e3f09e), C(bef634bc978bac31), C(7f64b1fa2a9129e), - C(71d831bd530ac7f3), C(c7ad0a8a6d5be6f1), C(82a7d3a815c7aaab), C(82b3fb6b)}, {C(2d777cddb912675d), C(278d7b10722a13f9), C(f5c02bfb7cc078af), - C(4283001239888836), C(f44ca39a6f79db89), C(ed186122d71bcc9f), - C(8620017ab5f3ba3b), C(4283001239888836), C(f44ca39a6f79db89), - C(ed186122d71bcc9f), C(8620017ab5f3ba3b), C(e787472187f176c), - C(267e64c4728cf181), C(f1ba4b3007c15e30), C(8e3a75d5b02ecfc0), C(e500e25f)}, {C(f2ec98824e8aa613), C(5eb7e3fb53fe3bed), C(12c22860466e1dd4), - C(374dd4288e0b72e5), C(ff8916db706c0df4), C(cb1a9e85de5e4b8d), - C(d4d12afb67a27659), C(374dd4288e0b72e5), C(ff8916db706c0df4), - C(cb1a9e85de5e4b8d), C(d4d12afb67a27659), C(feb69095d1ba175a), - C(e2003aab23a47fad), C(8163a3ecab894b49), C(46d356674ce041f6), C(bd2bb07c)}, {C(5e763988e21f487f), C(24189de8065d8dc5), C(d1519d2403b62aa0), - C(9136456740119815), C(4d8ff7733b27eb83), C(ea3040bc0c717ef8), - C(7617ab400dfadbc), C(9136456740119815), C(4d8ff7733b27eb83), - C(ea3040bc0c717ef8), C(7617ab400dfadbc), C(fb336770c10b17a1), - C(6123b68b5b31f151), C(1e147d5f295eccf2), C(9ecbb1333556f977), C(3a2b431d)}, {C(48949dc327bb96ad), C(e1fd21636c5c50b4), C(3f6eb7f13a8712b4), - C(14cf7f02dab0eee8), C(6d01750605e89445), C(4f1cf4006e613b78), - C(57c40c4db32bec3b), C(14cf7f02dab0eee8), C(6d01750605e89445), - C(4f1cf4006e613b78), C(57c40c4db32bec3b), C(1fde5a347f4a326e), - C(cb5a54308adb0e3f), C(14994b2ba447a23c), C(7067d0abb4257b68), C(7322a83d)}, {C(b7c4209fb24a85c5), C(b35feb319c79ce10), C(f0d3de191833b922), - C(570d62758ddf6397), C(5e0204fb68a7b800), C(4383a9236f8b5a2b), - C(7bc1a64641d803a4), C(570d62758ddf6397), C(5e0204fb68a7b800), - C(4383a9236f8b5a2b), C(7bc1a64641d803a4), C(5434d61285099f7a), - C(d49449aacdd5dd67), C(97855ba0e9a7d75d), C(da67328062f3a62f), C(a645ca1c)}, {C(9c9e5be0943d4b05), C(b73dc69e45201cbb), C(aab17180bfe5083d), - C(c738a77a9a55f0e2), C(705221addedd81df), C(fd9bd8d397abcfa3), - C(8ccf0004aa86b795), C(c738a77a9a55f0e2), C(705221addedd81df), - C(fd9bd8d397abcfa3), C(8ccf0004aa86b795), C(2bb5db2280068206), - C(8c22d29f307a01d), C(274a22de02f473c8), C(b8791870f4268182), C(8909a45a)}, + C(8909a45a)}, {C(3898bca4dfd6638d), C(f911ff35efef0167), C(24bdf69e5091fc88), - C(9b82567ab6560796), C(891b69462b41c224), C(8eccc7e4f3af3b51), - C(381e54c3c8f1c7d0), C(9b82567ab6560796), C(891b69462b41c224), - C(8eccc7e4f3af3b51), C(381e54c3c8f1c7d0), C(c80fbc489a558a55), - C(1ba88e062a663af7), C(af7b1ef1c0116303), C(bd20e1a5a6b1a0cd), C(bd30074c)}, - {C(5b5d2557400e68e7), C(98d610033574cee), C(dfd08772ce385deb), - C(3c13e894365dc6c2), C(26fc7bbcda3f0ef), C(dbb71106cdbfea36), - C(785239a742c6d26d), C(3c13e894365dc6c2), C(26fc7bbcda3f0ef), - C(dbb71106cdbfea36), C(785239a742c6d26d), C(f810c415ae05b2f4), - C(bb9b9e7398526088), C(70128f1bf830a32b), C(bcc73f82b6410899), - C(c17cf001)}, + {C(5b5d2557400e68e7), C(98d610033574cee), C(dfd08772ce385deb), C(c17cf001)}, {C(a927ed8b2bf09bb6), C(606e52f10ae94eca), C(71c2203feb35a9ee), - C(6e65ec14a8fb565), C(34bff6f2ee5a7f79), C(2e329a5be2c011b), - C(73161c93331b14f9), C(6e65ec14a8fb565), C(34bff6f2ee5a7f79), - C(2e329a5be2c011b), C(73161c93331b14f9), C(15d13f2408aecf88), - C(9f5b61b8a4b55b31), C(8fe25a43b296dba6), C(bdad03b7300f284e), C(26ffd25a)}, {C(8d25746414aedf28), C(34b1629d28b33d3a), C(4d5394aea5f82d7b), - C(379f76458a3c8957), C(79dd080f9843af77), C(c46f0a7847f60c1d), - C(af1579c5797703cc), C(379f76458a3c8957), C(79dd080f9843af77), - C(c46f0a7847f60c1d), C(af1579c5797703cc), C(8b7d31f338755c14), - C(2eff97679512aaa8), C(df07d68e075179ed), C(c8fa6c7a729e7f1f), C(f1d8ce3c)}, {C(b5bbdb73458712f2), C(1ff887b3c2a35137), C(7f7231f702d0ace9), - C(1e6f0910c3d25bd8), C(ad9e250862102467), C(1c842a07abab30cd), - C(cd8124176bac01ac), C(1e6f0910c3d25bd8), C(ad9e250862102467), - C(1c842a07abab30cd), C(cd8124176bac01ac), C(ea6ebe7a79b67edc), - C(73f598ac9db26713), C(4f4e72d7460b8fc), C(365dc4b9fdf13f21), C(3ee8fb17)}, + C(3ee8fb17)}, {C(3d32a26e3ab9d254), C(fc4070574dc30d3a), C(f02629579c2b27c9), - C(b1cf09b0184a4834), C(5c03db48eb6cc159), C(f18c7fcf34d1df47), - C(dfb043419ecf1fa9), C(b1cf09b0184a4834), C(5c03db48eb6cc159), - C(f18c7fcf34d1df47), C(dfb043419ecf1fa9), C(dcd78d13f9ca658f), - C(4355d408ffe8e49f), C(81eefee908b593b4), C(590c213c20e981a3), C(a77acc2a)}, - {C(9371d3c35fa5e9a5), C(42967cf4d01f30), C(652d1eeae704145c), - C(ceaf1a0d15234f15), C(1450a54e45ba9b9), C(65e9c1fd885aa932), - C(354d4bc034ba8cbe), C(ceaf1a0d15234f15), C(1450a54e45ba9b9), - C(65e9c1fd885aa932), C(354d4bc034ba8cbe), C(8fd4ff484c08fb4b), - C(bf46749866f69ba0), C(cf1c21ede82c9477), C(4217548c43da109), C(f4556dee)}, - {C(cbaa3cb8f64f54e0), C(76c3b48ee5c08417), C(9f7d24e87e61ce9), - C(85b8e53f22e19507), C(bb57137739ca486b), C(c77f131cca38f761), - C(c56ac3cf275be121), C(85b8e53f22e19507), C(bb57137739ca486b), - C(c77f131cca38f761), C(c56ac3cf275be121), C(9ec1a6c9109d2685), - C(3dad0922e76afdb0), C(fd58cbf952958103), C(7b04c908e78639a1), - C(de287a64)}, + {C(9371d3c35fa5e9a5), C(42967cf4d01f30), C(652d1eeae704145c), C(f4556dee)}, + {C(cbaa3cb8f64f54e0), C(76c3b48ee5c08417), C(9f7d24e87e61ce9), C(de287a64)}, {C(b2e23e8116c2ba9f), C(7e4d9c0060101151), C(3310da5e5028f367), - C(adc52dddb76f6e5e), C(4aad4e925a962b68), C(204b79b7f7168e64), - C(df29ed6671c36952), C(adc52dddb76f6e5e), C(4aad4e925a962b68), - C(204b79b7f7168e64), C(df29ed6671c36952), C(e02927cac396d210), - C(5d500e71742b638a), C(5c9998af7f27b124), C(3fba9a2573dc2f7), C(878e55b9)}, - {C(8aa77f52d7868eb9), C(4d55bd587584e6e2), C(d2db37041f495f5), - C(ce030d15b5fe2f4), C(86b4a7a0780c2431), C(ee070a9ae5b51db7), - C(edc293d9595be5d8), C(ce030d15b5fe2f4), C(86b4a7a0780c2431), - C(ee070a9ae5b51db7), C(edc293d9595be5d8), C(3dfc5ec108260a2b), - C(8afe28c7123bf4e2), C(da82ef38023a7a5f), C(3e1f77b0174b77c3), C(7648486)}, + C(878e55b9)}, + {C(8aa77f52d7868eb9), C(4d55bd587584e6e2), C(d2db37041f495f5), C(7648486)}, {C(858fea922c7fe0c3), C(cfe8326bf733bc6f), C(4e5e2018cf8f7dfc), - C(64fd1bc011e5bab7), C(5c9e858728015568), C(97ac42c2b00b29b1), - C(7f89caf08c109aee), C(64fd1bc011e5bab7), C(5c9e858728015568), - C(97ac42c2b00b29b1), C(7f89caf08c109aee), C(9a8af34fd0e9dacf), - C(bbc54161aa1507e0), C(7cda723ccbbfe5ee), C(2c289d839fb93f58), C(57ac0fb1)}, {C(46ef25fdec8392b1), C(e48d7b6d42a5cd35), C(56a6fe1c175299ca), - C(fdfa836b41dcef62), C(2f8db8030e847e1b), C(5ba0a49ac4f9b0f8), - C(dae897ed3e3fce44), C(fdfa836b41dcef62), C(2f8db8030e847e1b), - C(5ba0a49ac4f9b0f8), C(dae897ed3e3fce44), C(9c432e31aef626e7), - C(9a36e1c6cd6e3dd), C(5095a167c34d19d), C(a70005cfa6babbea), C(d01967ca)}, + C(d01967ca)}, {C(8d078f726b2df464), C(b50ee71cdcabb299), C(f4af300106f9c7ba), - C(7d222caae025158a), C(cc028d5fd40241b9), C(dd42515b639e6f97), - C(e08e86531a58f87f), C(7d222caae025158a), C(cc028d5fd40241b9), - C(dd42515b639e6f97), C(e08e86531a58f87f), C(d93612c835b37d7b), - C(91dd61729b2fa7f4), C(ba765a1bdda09db7), C(55258b451b2b1297), C(96ecdf74)}, {C(35ea86e6960ca950), C(34fe1fe234fc5c76), C(a00207a3dc2a72b7), - C(80395e48739e1a67), C(74a67d8f7f43c3d7), C(dd2bdd1d62246c6e), - C(a1f44298ba80acf6), C(80395e48739e1a67), C(74a67d8f7f43c3d7), - C(dd2bdd1d62246c6e), C(a1f44298ba80acf6), C(ad86d86c187bf38), - C(26feea1f2eee240d), C(ed7f1fd066b23897), C(a768cf1e0fbb502), C(779f5506)}, + C(779f5506)}, {C(8aee9edbc15dd011), C(51f5839dc8462695), C(b2213e17c37dca2d), - C(133b299a939745c5), C(796e2aac053f52b3), C(e8d9fe1521a4a222), - C(819a8863e5d1c290), C(133b299a939745c5), C(796e2aac053f52b3), - C(e8d9fe1521a4a222), C(819a8863e5d1c290), C(c0737f0fe34d36ad), - C(e6d6d4a267a5cc31), C(98300a7911674c23), C(bef189661c257098), C(3c94c2de)}, {C(c3e142ba98432dda), C(911d060cab126188), C(b753fbfa8365b844), - C(fd1a9ba5e71b08a2), C(7ac0dc2ed7778533), C(b543161ff177188a), - C(492fc08a6186f3f4), C(fd1a9ba5e71b08a2), C(7ac0dc2ed7778533), - C(b543161ff177188a), C(492fc08a6186f3f4), C(fc4745f516afd3b6), - C(88c30370a53080e), C(65a1bb34abc465e2), C(abbd14662911c8b3), C(39f98faf)}, + C(39f98faf)}, {C(123ba6b99c8cd8db), C(448e582672ee07c4), C(cebe379292db9e65), - C(938f5bbab544d3d6), C(d2a95f9f2d376d73), C(68b2f16149e81aa3), - C(ad7e32f82d86c79d), C(938f5bbab544d3d6), C(d2a95f9f2d376d73), - C(68b2f16149e81aa3), C(ad7e32f82d86c79d), C(4574015ae8626ce2), - C(455aa6137386a582), C(658ad2542e8ec20), C(e31d7be2ca35d00), C(7af31199)}, + C(7af31199)}, {C(ba87acef79d14f53), C(b3e0fcae63a11558), C(d5ac313a593a9f45), - C(eea5f5a9f74af591), C(578710bcc36fbea2), C(7a8393432188931d), - C(705cfc5ec7cc172), C(eea5f5a9f74af591), C(578710bcc36fbea2), - C(7a8393432188931d), C(705cfc5ec7cc172), C(da85ebe5fc427976), - C(bfa5c7a454df54c8), C(4632b72a81bf66d2), C(5dd72877db539ee2), C(e341a9d6)}, - {C(bcd3957d5717dc3), C(2da746741b03a007), C(873816f4b1ece472), - C(2b826f1a2c08c289), C(da50f56863b55e74), C(b18712f6b3eed83b), - C(bdc7cc05ab4c685f), C(2b826f1a2c08c289), C(da50f56863b55e74), - C(b18712f6b3eed83b), C(bdc7cc05ab4c685f), C(9e45fb833d1b0af), - C(d7213081db29d82e), C(d2a6b6c6a09ed55e), C(98a7686cba323ca9), - C(ca24aeeb)}, + {C(bcd3957d5717dc3), C(2da746741b03a007), C(873816f4b1ece472), C(ca24aeeb)}, {C(61442ff55609168e), C(6447c5fc76e8c9cf), C(6a846de83ae15728), - C(effc2663cffc777f), C(93214f8f463afbed), C(a156ef06066f4e4e), - C(a407b6ed8769d51e), C(effc2663cffc777f), C(93214f8f463afbed), - C(a156ef06066f4e4e), C(a407b6ed8769d51e), C(bb2f9ed29745c02a), - C(981eecd435b36ad9), C(461a5a05fb9cdff4), C(bd6cb2a87b9f910c), C(b2252b57)}, - {C(dbe4b1b2d174757f), C(506512da18712656), C(6857f3e0b8dd95f), - C(5a4fc2728a9bb671), C(ebb971522ec38759), C(1a5a093e6cf1f72b), - C(729b057fe784f504), C(5a4fc2728a9bb671), C(ebb971522ec38759), - C(1a5a093e6cf1f72b), C(729b057fe784f504), C(71fcbf42a767f9cf), - C(114cfe772da6cdd), C(60cdf9cb629d9d7a), C(e270d10ad088b24e), C(72c81da1)}, + {C(dbe4b1b2d174757f), C(506512da18712656), C(6857f3e0b8dd95f), C(72c81da1)}, {C(531e8e77b363161c), C(eece0b43e2dae030), C(8294b82c78f34ed1), - C(e777b1fd580582f2), C(7b880f58da112699), C(562c6b189a6333f4), - C(139d64f88a611d4), C(e777b1fd580582f2), C(7b880f58da112699), - C(562c6b189a6333f4), C(139d64f88a611d4), C(53d8ef17eda64fa4), - C(bf3eded14dc60a04), C(2b5c559cf5ec07c5), C(8895f7339d03a48a), C(6b9fce95)}, {C(f71e9c926d711e2b), C(d77af2853a4ceaa1), C(9aa0d6d76a36fae7), - C(dd16cd0fbc08393), C(29a414a5d8c58962), C(72793d8d1022b5b2), - C(2e8e69cf7cbffdf0), C(dd16cd0fbc08393), C(29a414a5d8c58962), - C(72793d8d1022b5b2), C(2e8e69cf7cbffdf0), C(3721c0473aa99c9a), - C(1cff4ed9c31cd91c), C(4990735033cc482b), C(7fdf8c701c72f577), C(19399857)}, {C(cb20ac28f52df368), C(e6705ee7880996de), C(9b665cc3ec6972f2), - C(4260e8c254e9924b), C(f197a6eb4591572d), C(8e867ff0fb7ab27c), - C(f95502fb503efaf3), C(4260e8c254e9924b), C(f197a6eb4591572d), - C(8e867ff0fb7ab27c), C(f95502fb503efaf3), C(30c41876b08e3e22), - C(958e2419e3cd22f4), C(f0f3aa1fe119a107), C(481662310a379100), C(3c57a994)}, {C(e4a794b4acb94b55), C(89795358057b661b), C(9c4cdcec176d7a70), - C(4890a83ee435bc8b), C(d8c1c00fceb00914), C(9e7111ba234f900f), - C(eb8dbab364d8b604), C(4890a83ee435bc8b), C(d8c1c00fceb00914), - C(9e7111ba234f900f), C(eb8dbab364d8b604), C(b3261452963eebb), - C(6cf94b02792c4f95), C(d88fa815ef1e8fc), C(2d687af66604c73), C(c053e729)}, + C(c053e729)}, {C(cb942e91443e7208), C(e335de8125567c2a), C(d4d74d268b86df1f), - C(8ba0fdd2ffc8b239), C(f413b366c1ffe02f), C(c05b2717c59a8a28), - C(981188eab4fcc8fb), C(8ba0fdd2ffc8b239), C(f413b366c1ffe02f), - C(c05b2717c59a8a28), C(981188eab4fcc8fb), C(e563f49a1d9072ba), - C(3c6a3aa4a26367dc), C(ba0db13448653f34), C(31065d756074d7d6), C(51cbbba7)}, {C(ecca7563c203f7ba), C(177ae2423ef34bb2), C(f60b7243400c5731), - C(cf1edbfe7330e94e), C(881945906bcb3cc6), C(4acf0293244855da), - C(65ae042c1c2a28c2), C(cf1edbfe7330e94e), C(881945906bcb3cc6), - C(4acf0293244855da), C(65ae042c1c2a28c2), C(b25fa0a1cab33559), - C(d98e8daa28124131), C(fce17f50b9c351b3), C(3f995ccf7386864b), C(1acde79a)}, {C(1652cb940177c8b5), C(8c4fe7d85d2a6d6d), C(f6216ad097e54e72), - C(f6521b912b368ae6), C(a9fe4eff81d03e73), C(d6f623629f80d1a3), - C(2b9604f32cb7dc34), C(f6521b912b368ae6), C(a9fe4eff81d03e73), - C(d6f623629f80d1a3), C(2b9604f32cb7dc34), C(2a43d84dcf59c7e2), - C(d0a197c70c5dae0b), C(6e84d4bbc71d76a0), C(c7e94620378c6cb2), C(2d160d13)}, {C(31fed0fc04c13ce8), C(3d5d03dbf7ff240a), C(727c5c9b51581203), - C(6b5ffc1f54fecb29), C(a8e8e7ad5b9a21d9), C(c4d5a32cd6aac22d), - C(d7e274ad22d4a79a), C(6b5ffc1f54fecb29), C(a8e8e7ad5b9a21d9), - C(c4d5a32cd6aac22d), C(d7e274ad22d4a79a), C(368841ea5731a112), - C(feaf7bc2e73ca48f), C(636fb272e9ea1f6), C(5d9cb7580c3f6207), C(787f5801)}, + C(787f5801)}, {C(e7b668947590b9b3), C(baa41ad32938d3fa), C(abcbc8d4ca4b39e4), - C(381ee1b7ea534f4e), C(da3759828e3de429), C(3e015d76729f9955), - C(cbbec51a6485fbde), C(381ee1b7ea534f4e), C(da3759828e3de429), - C(3e015d76729f9955), C(cbbec51a6485fbde), C(9b86605281f20727), - C(fc6fcf508676982a), C(3b135f7a813a1040), C(d3a4706bea1db9c9), C(c9629828)}, {C(1de2119923e8ef3c), C(6ab27c096cf2fe14), C(8c3658edca958891), - C(4cc8ed3ada5f0f2), C(4a496b77c1f1c04e), C(9085b0a862084201), - C(a1894bde9e3dee21), C(4cc8ed3ada5f0f2), C(4a496b77c1f1c04e), - C(9085b0a862084201), C(a1894bde9e3dee21), C(367fb472dc5b277d), - C(7d39ccca16fc6745), C(763f988d70db9106), C(a8b66f7fecb70f02), C(be139231)}, {C(1269df1e69e14fa7), C(992f9d58ac5041b7), C(e97fcf695a7cbbb4), - C(e5d0549802d15008), C(424c134ecd0db834), C(6fc44fd91be15c6c), - C(a1a5ef95d50e537d), C(e5d0549802d15008), C(424c134ecd0db834), - C(6fc44fd91be15c6c), C(a1a5ef95d50e537d), C(d1e3daf5d05f5308), - C(4c7f81600eaa1327), C(109d1b8d1f9d0d2b), C(871e8699e0aeb862), C(7df699ef)}, {C(820826d7aba567ff), C(1f73d28e036a52f3), C(41c4c5a73f3b0893), - C(aa0d74d4a98db89b), C(36fd486d07c56e1d), C(d0ad23cbb6660d8a), - C(1264a84665b35e19), C(aa0d74d4a98db89b), C(36fd486d07c56e1d), - C(d0ad23cbb6660d8a), C(1264a84665b35e19), C(789682bf7d781b33), - C(6bfa6abd2fb5722d), C(6779cb3623d33900), C(435ca5214e1ee5f0), C(8ce6b96d)}, {C(ffe0547e4923cef9), C(3534ed49b9da5b02), C(548a273700fba03d), - C(28ac84ca70958f7e), C(d8ae575a68faa731), C(2aaaee9b9dcffd4c), - C(6c7faab5c285c6da), C(28ac84ca70958f7e), C(d8ae575a68faa731), - C(2aaaee9b9dcffd4c), C(6c7faab5c285c6da), C(45d94235f99ba78f), - C(ab5ea16f39497f5b), C(fb4d6c86fccbdca3), C(8104e6310a5fd2c7), C(6f9ed99c)}, {C(72da8d1b11d8bc8b), C(ba94b56b91b681c6), C(4e8cc51bd9b0fc8c), - C(43505ed133be672a), C(e8f2f9d973c2774e), C(677b9b9c7cad6d97), - C(4e1f5d56ef17b906), C(43505ed133be672a), C(e8f2f9d973c2774e), - C(677b9b9c7cad6d97), C(4e1f5d56ef17b906), C(eea3a6038f983767), - C(87109f077f86db01), C(ecc1ca41f74d61cc), C(34a87e86e83bed17), C(e0244796)}, - {C(d62ab4e3f88fc797), C(ea86c7aeb6283ae4), C(b5b93e09a7fe465), - C(4344a1a0134afe2), C(ff5c17f02b62341d), C(3214c6a587ce4644), - C(a905e7ed0629d05c), C(4344a1a0134afe2), C(ff5c17f02b62341d), - C(3214c6a587ce4644), C(a905e7ed0629d05c), C(b5c72690cd716e82), - C(7c6097649e6ebe7b), C(7ceee8c6e56a4dcd), C(80ca849dc53eb9e4), - C(4ccf7e75)}, + {C(d62ab4e3f88fc797), C(ea86c7aeb6283ae4), C(b5b93e09a7fe465), C(4ccf7e75)}, {C(d0f06c28c7b36823), C(1008cb0874de4bb8), C(d6c7ff816c7a737b), - C(489b697fe30aa65f), C(4da0fb621fdc7817), C(dc43583b82c58107), - C(4b0261debdec3cd6), C(489b697fe30aa65f), C(4da0fb621fdc7817), - C(dc43583b82c58107), C(4b0261debdec3cd6), C(a9748d7b6c0e016c), - C(7e8828f7ba4b034b), C(da0fa54348a2512a), C(ebf9745c0962f9ad), C(915cef86)}, {C(99b7042460d72ec6), C(2a53e5e2b8e795c2), C(53a78132d9e1b3e3), - C(c043e67e6fc64118), C(ff0abfe926d844d3), C(f2a9fe5db2e910fe), - C(ce352cdc84a964dd), C(c043e67e6fc64118), C(ff0abfe926d844d3), - C(f2a9fe5db2e910fe), C(ce352cdc84a964dd), C(b89bc028aa5e6063), - C(a354e7fdac04459c), C(68d6547e6e980189), C(c968dddfd573773e), C(5cb59482)}, - {C(4f4dfcfc0ec2bae5), C(841233148268a1b8), C(9248a76ab8be0d3), - C(334c5a25b5903a8c), C(4c94fef443122128), C(743e7d8454655c40), - C(1ab1e6d1452ae2cd), C(334c5a25b5903a8c), C(4c94fef443122128), - C(743e7d8454655c40), C(1ab1e6d1452ae2cd), C(fec766de4a8e476c), - C(cc0929da9567e71b), C(5f9ef5b5f150c35a), C(87659cabd649768f), - C(6ca3f532)}, + {C(4f4dfcfc0ec2bae5), C(841233148268a1b8), C(9248a76ab8be0d3), C(6ca3f532)}, {C(fe86bf9d4422b9ae), C(ebce89c90641ef9c), C(1c84e2292c0b5659), - C(8bde625a10a8c50d), C(eb8271ded1f79a0b), C(14dc6844f0de7a3c), - C(f85b2f9541e7e6da), C(8bde625a10a8c50d), C(eb8271ded1f79a0b), - C(14dc6844f0de7a3c), C(f85b2f9541e7e6da), C(2fe22cfd1683b961), - C(ea1d75c5b7aa01ca), C(9eef60a44876bb95), C(950c818e505c6f7f), C(e24f3859)}, {C(a90d81060932dbb0), C(8acfaa88c5fbe92b), C(7c6f3447e90f7f3f), - C(dd52fc14c8dd3143), C(1bc7508516e40628), C(3059730266ade626), - C(ffa526822f391c2), C(dd52fc14c8dd3143), C(1bc7508516e40628), - C(3059730266ade626), C(ffa526822f391c2), C(e25232d7afc8a406), - C(d2b8a5a3f3b5f670), C(6630f33edb7dfe32), C(c71250ba68c4ea86), C(adf5a9c7)}, {C(17938a1b0e7f5952), C(22cadd2f56f8a4be), C(84b0d1183d5ed7c1), - C(c1336b92fef91bf6), C(80332a3945f33fa9), C(a0f68b86f726ff92), - C(a3db5282cf5f4c0b), C(c1336b92fef91bf6), C(80332a3945f33fa9), - C(a0f68b86f726ff92), C(a3db5282cf5f4c0b), C(82640b6fc4916607), - C(2dc2a3aa1a894175), C(8b4c852bdee7cc9), C(10b9d0a08b55ff83), C(32264b75)}, + C(32264b75)}, {C(de9e0cb0e16f6e6d), C(238e6283aa4f6594), C(4fb9c914c2f0a13b), - C(497cb912b670f3b), C(d963a3f02ff4a5b6), C(4fccefae11b50391), - C(42ba47db3f7672f), C(497cb912b670f3b), C(d963a3f02ff4a5b6), - C(4fccefae11b50391), C(42ba47db3f7672f), C(1d6b655a1889feef), - C(5f319abf8fafa19f), C(715c2e49deb14620), C(8d9153082ecdcea4), C(a64b3376)}, - {C(6d4b876d9b146d1a), C(aab2d64ce8f26739), C(d315f93600e83fe5), - C(2fe9fabdbe7fdd4), C(755db249a2d81a69), C(f27929f360446d71), - C(79a1bf957c0c1b92), C(2fe9fabdbe7fdd4), C(755db249a2d81a69), - C(f27929f360446d71), C(79a1bf957c0c1b92), C(3c8a28d4c936c9cd), - C(df0d3d13b2c6a902), C(c76702dd97cd2edd), C(1aa220f7be16517), C(d33890e)}, + {C(6d4b876d9b146d1a), C(aab2d64ce8f26739), C(d315f93600e83fe5), C(d33890e)}, {C(e698fa3f54e6ea22), C(bd28e20e7455358c), C(9ace161f6ea76e66), - C(d53fb7e3c93a9e4), C(737ae71b051bf108), C(7ac71feb84c2df42), - C(3d8075cd293a15b4), C(d53fb7e3c93a9e4), C(737ae71b051bf108), - C(7ac71feb84c2df42), C(3d8075cd293a15b4), C(bf8cee5e095d8a7c), - C(e7086b3c7608143a), C(e55b0c2fa938d70c), C(fffb5f58e643649c), C(926d4b63)}, {C(7bc0deed4fb349f7), C(1771aff25dc722fa), C(19ff0644d9681917), - C(cf7d7f25bd70cd2c), C(9464ed9baeb41b4f), C(b9064f5c3cb11b71), - C(237e39229b012b20), C(cf7d7f25bd70cd2c), C(9464ed9baeb41b4f), - C(b9064f5c3cb11b71), C(237e39229b012b20), C(dd54d3f5d982dffe), - C(7fc7562dbfc81dbf), C(5b0dd1924f70945), C(f1760537d8261135), C(d51ba539)}, + C(d51ba539)}, {C(db4b15e88533f622), C(256d6d2419b41ce9), C(9d7c5378396765d5), - C(9040e5b936b8661b), C(276e08fa53ac27fd), C(8c944d39c2bdd2cc), - C(e2514c9802a5743c), C(9040e5b936b8661b), C(276e08fa53ac27fd), - C(8c944d39c2bdd2cc), C(e2514c9802a5743c), C(e82107b11ac90386), - C(7d6a22bc35055e6), C(fd6ea9d1c438d8ae), C(be6015149e981553), C(7f37636d)}, + C(7f37636d)}, {C(922834735e86ecb2), C(363382685b88328e), C(e9c92960d7144630), - C(8431b1bfd0a2379c), C(90383913aea283f9), C(a6163831eb4924d2), - C(5f3921b4f9084aee), C(8431b1bfd0a2379c), C(90383913aea283f9), - C(a6163831eb4924d2), C(5f3921b4f9084aee), C(7a70061a1473e579), - C(5b19d80dcd2c6331), C(6196b97931faad27), C(869bf6828e237c3f), C(b98026c0)}, {C(30f1d72c812f1eb8), C(b567cd4a69cd8989), C(820b6c992a51f0bc), - C(c54677a80367125e), C(3204fbdba462e606), C(8563278afc9eae69), - C(262147dd4bf7e566), C(c54677a80367125e), C(3204fbdba462e606), - C(8563278afc9eae69), C(262147dd4bf7e566), C(2178b63e7ee2d230), - C(e9c61ad81f5bff26), C(9af7a81b3c501eca), C(44104a3859f0238f), C(b877767e)}, - {C(168884267f3817e9), C(5b376e050f637645), C(1c18314abd34497a), - C(9598f6ab0683fcc2), C(1c805abf7b80e1ee), C(dec9ac42ee0d0f32), - C(8cd72e3912d24663), C(9598f6ab0683fcc2), C(1c805abf7b80e1ee), - C(dec9ac42ee0d0f32), C(8cd72e3912d24663), C(1f025d405f1c1d87), - C(bf7b6221e1668f8f), C(52316f64e692dbb0), C(7bf43df61ec51b39), C(aefae77)}, - {C(82e78596ee3e56a7), C(25697d9c87f30d98), C(7600a8342834924d), - C(6ba372f4b7ab268b), C(8c3237cf1fe243df), C(3833fc51012903df), - C(8e31310108c5683f), C(6ba372f4b7ab268b), C(8c3237cf1fe243df), - C(3833fc51012903df), C(8e31310108c5683f), C(126593715c2de429), - C(48ca8f35a3f54b90), C(b9322b632f4f8b0), C(926bb169b7337693), C(f686911)}, + {C(168884267f3817e9), C(5b376e050f637645), C(1c18314abd34497a), C(aefae77)}, + {C(82e78596ee3e56a7), C(25697d9c87f30d98), C(7600a8342834924d), C(f686911)}, {C(aa2d6cf22e3cc252), C(9b4dec4f5e179f16), C(76fb0fba1d99a99a), - C(9a62af3dbba140da), C(27857ea044e9dfc1), C(33abce9da2272647), - C(b22a7993aaf32556), C(9a62af3dbba140da), C(27857ea044e9dfc1), - C(33abce9da2272647), C(b22a7993aaf32556), C(bf8f88f8019bedf0), - C(ed2d7f01fb273905), C(6b45f15901b481cd), C(f88ebb413ba6a8d5), C(3deadf12)}, {C(7bf5ffd7f69385c7), C(fc077b1d8bc82879), C(9c04e36f9ed83a24), - C(82065c62e6582188), C(8ef787fd356f5e43), C(2922e53e36e17dfa), - C(9805f223d385010b), C(82065c62e6582188), C(8ef787fd356f5e43), - C(2922e53e36e17dfa), C(9805f223d385010b), C(692154f3491b787d), - C(e7e64700e414fbf), C(757d4d4ab65069a0), C(cd029446a8e348e2), C(ccf02a4e)}, + C(ccf02a4e)}, {C(e89c8ff9f9c6e34b), C(f54c0f669a49f6c4), C(fc3e46f5d846adef), - C(22f2aa3df2221cc), C(f66fea90f5d62174), C(b75defaeaa1dd2a7), - C(9b994cd9a7214fd5), C(22f2aa3df2221cc), C(f66fea90f5d62174), - C(b75defaeaa1dd2a7), C(9b994cd9a7214fd5), C(fac675a31804b773), - C(98bcb3b820c50fc6), C(e14af64d28cf0885), C(27466fbd2b360eb5), C(176c1722)}, - {C(a18fbcdccd11e1f4), C(8248216751dfd65e), C(40c089f208d89d7c), - C(229b79ab69ae97d), C(a87aabc2ec26e582), C(be2b053721eb26d2), - C(10febd7f0c3d6fcb), C(229b79ab69ae97d), C(a87aabc2ec26e582), - C(be2b053721eb26d2), C(10febd7f0c3d6fcb), C(9cc5b9b2f6e3bf7b), - C(655d8495fe624a86), C(6381a9f3d1f2bd7e), C(79ebabbfc25c83e2), C(26f82ad)}, + {C(a18fbcdccd11e1f4), C(8248216751dfd65e), C(40c089f208d89d7c), C(26f82ad)}, {C(2d54f40cc4088b17), C(59d15633b0cd1399), C(a8cc04bb1bffd15b), - C(d332cdb073d8dc46), C(272c56466868cb46), C(7e7fcbe35ca6c3f3), - C(ee8f51e5a70399d4), C(d332cdb073d8dc46), C(272c56466868cb46), - C(7e7fcbe35ca6c3f3), C(ee8f51e5a70399d4), C(16737a9c7581fe7b), - C(ed04bf52f4b75dcb), C(9707ffb36bd30c1a), C(1390f236fdc0de3e), C(b5244f42)}, {C(69276946cb4e87c7), C(62bdbe6183be6fa9), C(3ba9773dac442a1a), - C(702e2afc7f5a1825), C(8c49b11ea8151fdc), C(caf3fef61f5a86fa), - C(ef0b2ee8649d7272), C(702e2afc7f5a1825), C(8c49b11ea8151fdc), - C(caf3fef61f5a86fa), C(ef0b2ee8649d7272), C(9e34a4e08d9441e1), - C(7bdc0cd64d5af533), C(a926b14d99e3d868), C(fca923a17788cce4), C(49a689e5)}, - {C(668174a3f443df1d), C(407299392da1ce86), C(c2a3f7d7f2c5be28), - C(a590b202a7a5807b), C(968d2593f7ccb54e), C(9dd8d669e3e95dec), - C(ee0cc5dd58b6e93a), C(a590b202a7a5807b), C(968d2593f7ccb54e), - C(9dd8d669e3e95dec), C(ee0cc5dd58b6e93a), C(ac65d5a9466fb483), - C(221be538b2c9d806), C(5cbe9441784f9fd9), C(d4c7d5d6e3c122b8), C(59fcdd3)}, - {C(5e29be847bd5046), C(b561c7f19c8f80c3), C(5e5abd5021ccaeaf), - C(7432d63888e0c306), C(74bbceeed479cb71), C(6471586599575fdf), - C(6a859ad23365cba2), C(7432d63888e0c306), C(74bbceeed479cb71), - C(6471586599575fdf), C(6a859ad23365cba2), C(f9ceec84acd18dcc), - C(74a242ff1907437c), C(f70890194e1ee913), C(777dfcb4bb01f0ba), - C(4f4b04e9)}, + {C(668174a3f443df1d), C(407299392da1ce86), C(c2a3f7d7f2c5be28), C(59fcdd3)}, + {C(5e29be847bd5046), C(b561c7f19c8f80c3), C(5e5abd5021ccaeaf), C(4f4b04e9)}, {C(cd0d79f2164da014), C(4c386bb5c5d6ca0c), C(8e771b03647c3b63), - C(69db23875cb0b715), C(ada8dd91504ae37f), C(46bf18dbf045ed6a), - C(e1b5f67b0645ab63), C(69db23875cb0b715), C(ada8dd91504ae37f), - C(46bf18dbf045ed6a), C(e1b5f67b0645ab63), C(877be8f5dcddff4), - C(6d471b5f9ca2e2d1), C(802c86d6f495b9bb), C(a1f9b9b22b3be704), C(8b00f891)}, {C(e0e6fc0b1628af1d), C(29be5fb4c27a2949), C(1c3f781a604d3630), - C(c4af7faf883033aa), C(9bd296c4e9453cac), C(ca45426c1f7e33f9), - C(a6bbdcf7074d40c5), C(c4af7faf883033aa), C(9bd296c4e9453cac), - C(ca45426c1f7e33f9), C(a6bbdcf7074d40c5), C(e13a005d7142733b), - C(c02b7925c5eeefaf), C(d39119a60441e2d5), C(3c24c710df8f4d43), C(16e114f3)}, {C(2058927664adfd93), C(6e8f968c7963baa5), C(af3dced6fff7c394), - C(42e34cf3d53c7876), C(9cddbb26424dc5e), C(64f6340a6d8eddad), - C(2196e488eb2a3a4b), C(42e34cf3d53c7876), C(9cddbb26424dc5e), - C(64f6340a6d8eddad), C(2196e488eb2a3a4b), C(c9e9da25911a16fd), - C(e21b4683f3e196a8), C(cb80bf1a4c6fdbb4), C(53792e9b3c3e67f8), C(d6b6dadc)}, {C(dc107285fd8e1af7), C(a8641a0609321f3f), C(db06e89ffdc54466), - C(bcc7a81ed5432429), C(b6d7bdc6ad2e81f1), C(93605ec471aa37db), - C(a2a73f8a85a8e397), C(bcc7a81ed5432429), C(b6d7bdc6ad2e81f1), - C(93605ec471aa37db), C(a2a73f8a85a8e397), C(10a012b8ca7ac24b), - C(aac5fd63351595cf), C(5bb4c648a226dea0), C(9d11ecb2b5c05c5f), C(897e20ac)}, - {C(fbba1afe2e3280f1), C(755a5f392f07fce), C(9e44a9a15402809a), - C(6226a32e25099848), C(ea895661ecf53004), C(4d7e0158db2228b9), - C(e5a7d82922f69842), C(6226a32e25099848), C(ea895661ecf53004), - C(4d7e0158db2228b9), C(e5a7d82922f69842), C(2cea7713b69840ca), - C(18de7b9ae938375b), C(f127cca08f3cc665), C(b1c22d727665ad2), C(f996e05d)}, + {C(fbba1afe2e3280f1), C(755a5f392f07fce), C(9e44a9a15402809a), C(f996e05d)}, {C(bfa10785ddc1011b), C(b6e1c4d2f670f7de), C(517d95604e4fcc1f), - C(ca6552a0dfb82c73), C(b024cdf09e34ba07), C(66cd8c5a95d7393b), - C(e3939acf790d4a74), C(ca6552a0dfb82c73), C(b024cdf09e34ba07), - C(66cd8c5a95d7393b), C(e3939acf790d4a74), C(97827541a1ef051e), - C(ac2fce47ebe6500c), C(b3f06d3bddf3bd6a), C(1d74afb25e1ce5fe), C(c4306af6)}, - {C(534cc35f0ee1eb4e), C(b703820f1f3b3dce), C(884aa164cf22363), - C(f14ef7f47d8a57a3), C(80d1f86f2e061d7c), C(401d6c2f151b5a62), - C(e988460224108944), C(f14ef7f47d8a57a3), C(80d1f86f2e061d7c), - C(401d6c2f151b5a62), C(e988460224108944), C(7804d4135f68cd19), - C(5487b4b39e69fe8e), C(8cc5999015358a27), C(8f3729b61c2d5601), - C(6dcad433)}, - {C(7ca6e3933995dac), C(fd118c77daa8188), C(3aceb7b5e7da6545), - C(c8389799445480db), C(5389f5df8aacd50d), C(d136581f22fab5f), - C(c2f31f85991da417), C(c8389799445480db), C(5389f5df8aacd50d), - C(d136581f22fab5f), C(c2f31f85991da417), C(aefbf9ff84035a43), - C(8accbaf44adadd7c), C(e57f3657344b67f5), C(21490e5e8abdec51), - C(3c07374d)}, + {C(534cc35f0ee1eb4e), C(b703820f1f3b3dce), C(884aa164cf22363), C(6dcad433)}, + {C(7ca6e3933995dac), C(fd118c77daa8188), C(3aceb7b5e7da6545), C(3c07374d)}, {C(f0d6044f6efd7598), C(e044d6ba4369856e), C(91968e4f8c8a1a4c), - C(70bd1968996bffc2), C(4c613de5d8ab32ac), C(fe1f4f97206f79d8), - C(ac0434f2c4e213a9), C(70bd1968996bffc2), C(4c613de5d8ab32ac), - C(fe1f4f97206f79d8), C(ac0434f2c4e213a9), C(7490e9d82cfe22ca), - C(5fbbf7f987454238), C(c39e0dc8368ce949), C(22201d3894676c71), C(f0f4602c)}, {C(3d69e52049879d61), C(76610636ea9f74fe), C(e9bf5602f89310c0), - C(8eeb177a86053c11), C(e390122c345f34a2), C(1e30e47afbaaf8d6), - C(7b892f68e5f91732), C(8eeb177a86053c11), C(e390122c345f34a2), - C(1e30e47afbaaf8d6), C(7b892f68e5f91732), C(b87922525fa44158), - C(f440a1ee1a1a766b), C(ee8efad279d08c5c), C(421f910c5b60216e), C(3e1ea071)}, - {C(79da242a16acae31), C(183c5f438e29d40), C(6d351710ae92f3de), - C(27233b28b5b11e9b), C(c7dfe8988a942700), C(570ed11c4abad984), - C(4b4c04632f48311a), C(27233b28b5b11e9b), C(c7dfe8988a942700), - C(570ed11c4abad984), C(4b4c04632f48311a), C(12f33235442cbf9), - C(a35315ca0b5b8cdb), C(d8abde62ead5506b), C(fc0fcf8478ad5266), - C(67580f0c)}, + {C(79da242a16acae31), C(183c5f438e29d40), C(6d351710ae92f3de), C(67580f0c)}, {C(461c82656a74fb57), C(d84b491b275aa0f7), C(8f262cb29a6eb8b2), - C(49fa3070bc7b06d0), C(f12ed446bd0c0539), C(6d43ac5d1dd4b240), - C(7609524fe90bec93), C(49fa3070bc7b06d0), C(f12ed446bd0c0539), - C(6d43ac5d1dd4b240), C(7609524fe90bec93), C(391c2b2e076ec241), - C(f5e62deda7839f7b), C(3c7b3186a10d870f), C(77ef4f2cba4f1005), C(4e109454)}, - {C(53c1a66d0b13003), C(731f060e6fe797fc), C(daa56811791371e3), - C(57466046cf6896ed), C(8ac37e0e8b25b0c6), C(3e6074b52ad3cf18), - C(aa491ce7b45db297), C(57466046cf6896ed), C(8ac37e0e8b25b0c6), - C(3e6074b52ad3cf18), C(aa491ce7b45db297), C(f7a9227c5e5e22c3), - C(3d92e0841e29ce28), C(2d30da5b2859e59d), C(ff37fa1c9cbfafc2), - C(88a474a7)}, - {C(d3a2efec0f047e9), C(1cabce58853e58ea), C(7a17b2eae3256be4), - C(c2dcc9758c910171), C(cb5cddaeff4ddb40), C(5d7cc5869baefef1), - C(9644c5853af9cfeb), C(c2dcc9758c910171), C(cb5cddaeff4ddb40), - C(5d7cc5869baefef1), C(9644c5853af9cfeb), C(255c968184694ee1), - C(4e4d726eda360927), C(7d27dd5b6d100377), C(9a300e2020ddea2c), C(5b5bedd)}, + {C(53c1a66d0b13003), C(731f060e6fe797fc), C(daa56811791371e3), C(88a474a7)}, + {C(d3a2efec0f047e9), C(1cabce58853e58ea), C(7a17b2eae3256be4), C(5b5bedd)}, {C(43c64d7484f7f9b2), C(5da002b64aafaeb7), C(b576c1e45800a716), - C(3ee84d3d5b4ca00b), C(5cbc6d701894c3f9), C(d9e946f5ae1ca95), - C(24ca06e67f0b1833), C(3ee84d3d5b4ca00b), C(5cbc6d701894c3f9), - C(d9e946f5ae1ca95), C(24ca06e67f0b1833), C(3413d46b4152650e), - C(cbdfdbc2ab516f9c), C(2aad8acb739e0c6c), C(2bfc950d9f9fa977), C(1aaddfa7)}, {C(a7dec6ad81cf7fa1), C(180c1ab708683063), C(95e0fd7008d67cff), - C(6b11c5073687208), C(7e0a57de0d453f3), C(e48c267d4f646867), - C(2168e9136375f9cb), C(6b11c5073687208), C(7e0a57de0d453f3), - C(e48c267d4f646867), C(2168e9136375f9cb), C(64da194aeeea7fdf), - C(a3b9f01fa5885678), C(c316f8ee2eb2bd17), C(a7e4d80f83e4427f), C(5be07fd8)}, - {C(5408a1df99d4aff), C(b9565e588740f6bd), C(abf241813b08006e), - C(7da9e81d89fda7ad), C(274157cabe71440d), C(2c22d9a480b331f7), - C(e835c8ac746472d5), C(7da9e81d89fda7ad), C(274157cabe71440d), - C(2c22d9a480b331f7), C(e835c8ac746472d5), C(2038ce817a201ae4), - C(46f3289dfe1c5e40), C(435578a42d4b7c56), C(f96d9f409fcf561), C(cbca8606)}, + {C(5408a1df99d4aff), C(b9565e588740f6bd), C(abf241813b08006e), C(cbca8606)}, {C(a8b27a6bcaeeed4b), C(aec1eeded6a87e39), C(9daf246d6fed8326), - C(d45a938b79f54e8f), C(366b219d6d133e48), C(5b14be3c25c49405), - C(fdd791d48811a572), C(d45a938b79f54e8f), C(366b219d6d133e48), - C(5b14be3c25c49405), C(fdd791d48811a572), C(3de67b8d9e95d335), - C(903c01307cfbeed5), C(af7d65f32274f1d1), C(4dba141b5fc03c42), C(bde64d01)}, {C(9a952a8246fdc269), C(d0dcfcac74ef278c), C(250f7139836f0f1f), - C(c83d3c5f4e5f0320), C(694e7adeb2bf32e5), C(7ad09538a3da27f5), - C(2b5c18f934aa5303), C(c83d3c5f4e5f0320), C(694e7adeb2bf32e5), - C(7ad09538a3da27f5), C(2b5c18f934aa5303), C(c4dad7703d34326e), - C(825569e2bcdc6a25), C(b83d267709ca900d), C(44ed05151f5d74e6), C(ee90cf33)}, {C(c930841d1d88684f), C(5eb66eb18b7f9672), C(e455d413008a2546), - C(bc271bc0df14d647), C(b071100a9ff2edbb), C(2b1a4c1cc31a119a), - C(b5d7caa1bd946cef), C(bc271bc0df14d647), C(b071100a9ff2edbb), - C(2b1a4c1cc31a119a), C(b5d7caa1bd946cef), C(e02623ae10f4aadd), - C(d79f600389cd06fd), C(1e8da7965303e62b), C(86f50e10eeab0925), C(4305c3ce)}, - {C(94dc6971e3cf071a), C(994c7003b73b2b34), C(ea16e85978694e5), - C(336c1b59a1fc19f6), C(c173acaecc471305), C(db1267d24f3f3f36), - C(e9a5ee98627a6e78), C(336c1b59a1fc19f6), C(c173acaecc471305), - C(db1267d24f3f3f36), C(e9a5ee98627a6e78), C(718f334204305ae5), - C(e3b53c148f98d22c), C(a184012df848926), C(6e96386127d51183), C(4b3a1d76)}, - {C(7fc98006e25cac9), C(77fee0484cda86a7), C(376ec3d447060456), - C(84064a6dcf916340), C(fbf55a26790e0ebb), C(2e7f84151c31a5c2), - C(9f7f6d76b950f9bf), C(84064a6dcf916340), C(fbf55a26790e0ebb), - C(2e7f84151c31a5c2), C(9f7f6d76b950f9bf), C(125e094fbee2b146), - C(5706aa72b2eef7c2), C(1c4a2daa905ee66e), C(83d48029b5451694), - C(a8bb6d80)}, - {C(bd781c4454103f6), C(612197322f49c931), C(b9cf17fd7e5462d5), - C(e38e526cd3324364), C(85f2b63a5b5e840a), C(485d7cef5aaadd87), - C(d2b837a462f6db6d), C(e38e526cd3324364), C(85f2b63a5b5e840a), - C(485d7cef5aaadd87), C(d2b837a462f6db6d), C(3e41cef031520d9a), - C(82df73902d7f67e), C(3ba6fd54c15257cb), C(22f91f079be42d40), C(1f9fa607)}, + {C(94dc6971e3cf071a), C(994c7003b73b2b34), C(ea16e85978694e5), C(4b3a1d76)}, + {C(7fc98006e25cac9), C(77fee0484cda86a7), C(376ec3d447060456), C(a8bb6d80)}, + {C(bd781c4454103f6), C(612197322f49c931), C(b9cf17fd7e5462d5), C(1f9fa607)}, {C(da60e6b14479f9df), C(3bdccf69ece16792), C(18ebf45c4fecfdc9), - C(16818ee9d38c6664), C(5519fa9a1e35a329), C(cbd0001e4b08ed8), - C(41a965e37a0c731b), C(16818ee9d38c6664), C(5519fa9a1e35a329), - C(cbd0001e4b08ed8), C(41a965e37a0c731b), C(66e7b5dcca1ca28f), - C(963b2d993614347d), C(9b6fc6f41d411106), C(aaaecaccf7848c0c), C(8d0e4ed2)}, - {C(4ca56a348b6c4d3), C(60618537c3872514), C(2fbb9f0e65871b09), - C(30278016830ddd43), C(f046646d9012e074), C(c62a5804f6e7c9da), - C(98d51f5830e2bc1e), C(30278016830ddd43), C(f046646d9012e074), - C(c62a5804f6e7c9da), C(98d51f5830e2bc1e), C(7b2cbe5d37e3f29e), - C(7b8c3ed50bda4aa0), C(3ea60cc24639e038), C(f7706de9fb0b5801), - C(1bf31347)}, + {C(4ca56a348b6c4d3), C(60618537c3872514), C(2fbb9f0e65871b09), C(1bf31347)}, {C(ebd22d4b70946401), C(6863602bf7139017), C(c0b1ac4e11b00666), - C(7d2782b82bd494b6), C(97159ba1c26b304b), C(42b3b0fd431b2ac2), - C(faa81f82691c830c), C(7d2782b82bd494b6), C(97159ba1c26b304b), - C(42b3b0fd431b2ac2), C(faa81f82691c830c), C(7cc6449234c7e185), - C(aeaa6fa643ca86a5), C(1412db1c0f2e0133), C(4df2fe3e4072934f), C(1ae3fc5b)}, - {C(3cc4693d6cbcb0c), C(501689ea1c70ffa), C(10a4353e9c89e364), - C(58c8aba7475e2d95), C(3e2f291698c9427a), C(e8710d19c9de9e41), - C(65dda22eb04cf953), C(58c8aba7475e2d95), C(3e2f291698c9427a), - C(e8710d19c9de9e41), C(65dda22eb04cf953), C(d7729c48c250cffa), - C(ef76162b2ddfba4b), C(52371e17f4d51f6d), C(ddd002112ff0c833), - C(459c3930)}, + {C(3cc4693d6cbcb0c), C(501689ea1c70ffa), C(10a4353e9c89e364), C(459c3930)}, {C(38908e43f7ba5ef0), C(1ab035d4e7781e76), C(41d133e8c0a68ff7), - C(d1090893afaab8bc), C(96c4fe6922772807), C(4522426c2b4205eb), - C(efad99a1262e7e0d), C(d1090893afaab8bc), C(96c4fe6922772807), - C(4522426c2b4205eb), C(efad99a1262e7e0d), C(c7696029abdb465e), - C(4e18eaf03d517651), C(d006bced54c86ac8), C(4330326d1021860c), C(e00c4184)}, - {C(34983ccc6aa40205), C(21802cad34e72bc4), C(1943e8fb3c17bb8), - C(fc947167f69c0da5), C(ae79cfdb91b6f6c1), C(7b251d04c26cbda3), - C(128a33a79060d25e), C(fc947167f69c0da5), C(ae79cfdb91b6f6c1), - C(7b251d04c26cbda3), C(128a33a79060d25e), C(1eca842dbfe018dd), - C(50a4cd2ee0ba9c63), C(c2f5c97d8399682f), C(3f929fc7cbe8ecbb), - C(ffc7a781)}, + {C(34983ccc6aa40205), C(21802cad34e72bc4), C(1943e8fb3c17bb8), C(ffc7a781)}, {C(86215c45dcac9905), C(ea546afe851cae4b), C(d85b6457e489e374), - C(b7609c8e70386d66), C(36e6ccc278d1636d), C(2f873307c08e6a1c), - C(10f252a758505289), C(b7609c8e70386d66), C(36e6ccc278d1636d), - C(2f873307c08e6a1c), C(10f252a758505289), C(c8977646e81ab4b6), - C(8017b745cd80213b), C(960687db359bea0), C(ef4a470660799488), C(6a125480)}, + C(6a125480)}, {C(420fc255c38db175), C(d503cd0f3c1208d1), C(d4684e74c825a0bc), - C(4c10537443152f3d), C(720451d3c895e25d), C(aff60c4d11f513fd), - C(881e8d6d2d5fb953), C(4c10537443152f3d), C(720451d3c895e25d), - C(aff60c4d11f513fd), C(881e8d6d2d5fb953), C(9dec034a043f1f55), - C(e27a0c22e7bfb39d), C(2220b959128324), C(53240272152dbd8b), C(88a1512b)}, + C(88a1512b)}, {C(1d7a31f5bc8fe2f9), C(4763991092dcf836), C(ed695f55b97416f4), - C(f265edb0c1c411d7), C(30e1e9ec5262b7e6), C(c2c3ba061ce7957a), - C(d975f93b89a16409), C(f265edb0c1c411d7), C(30e1e9ec5262b7e6), - C(c2c3ba061ce7957a), C(d975f93b89a16409), C(e9d703123f43450a), - C(41383fedfed67c82), C(6e9f43ecbbbd6004), C(c7ccd23a24e77b8), C(549bbbe5)}, + C(549bbbe5)}, {C(94129a84c376a26e), C(c245e859dc231933), C(1b8f74fecf917453), - C(e9369d2e9007e74b), C(b1375915d1136052), C(926c2021fe1d2351), - C(1d943addaaa2e7e6), C(e9369d2e9007e74b), C(b1375915d1136052), - C(926c2021fe1d2351), C(1d943addaaa2e7e6), C(f5f515869c246738), - C(7e309cd0e1c0f2a0), C(153c3c36cf523e3b), C(4931c66872ea6758), C(c133d38c)}, - {C(1d3a9809dab05c8d), C(adddeb4f71c93e8), C(ef342eb36631edb), - C(301d7a61c4b3dbca), C(861336c3f0552d61), C(12c6db947471300f), - C(a679ef0ed761deb9), C(301d7a61c4b3dbca), C(861336c3f0552d61), - C(12c6db947471300f), C(a679ef0ed761deb9), C(5f713b720efcd147), - C(37ac330a333aa6b), C(3309dc9ec1616eef), C(52301d7a908026b5), C(fcace348)}, + {C(1d3a9809dab05c8d), C(adddeb4f71c93e8), C(ef342eb36631edb), C(fcace348)}, {C(90fa3ccbd60848da), C(dfa6e0595b569e11), C(e585d067a1f5135d), - C(6cef866ec295abea), C(c486c0d9214beb2d), C(d6e490944d5fe100), - C(59df3175d72c9f38), C(6cef866ec295abea), C(c486c0d9214beb2d), - C(d6e490944d5fe100), C(59df3175d72c9f38), C(3f23aeb4c04d1443), - C(9bf0515cd8d24770), C(958554f60ccaade2), C(5182863c90132fe8), C(ed7b6f9a)}, {C(2dbb4fc71b554514), C(9650e04b86be0f82), C(60f2304fba9274d3), - C(fcfb9443e997cab), C(f13310d96dec2772), C(709cad2045251af2), - C(afd0d30cc6376dad), C(fcfb9443e997cab), C(f13310d96dec2772), - C(709cad2045251af2), C(afd0d30cc6376dad), C(59d4bed30d550d0d), - C(58006d4e22d8aad1), C(eee12d2362d1f13b), C(35cf1d7faaf1d228), C(6d907dda)}, {C(b98bf4274d18374a), C(1b669fd4c7f9a19a), C(b1f5972b88ba2b7a), - C(73119c99e6d508be), C(5d4036a187735385), C(8fa66e192fd83831), - C(2abf64b6b592ed57), C(73119c99e6d508be), C(5d4036a187735385), - C(8fa66e192fd83831), C(2abf64b6b592ed57), C(d4501f95dd84b08c), - C(bf1552439c8bea02), C(4f56fe753ba7e0ba), C(4ca8d35cc058cfcd), C(7a4d48d5)}, {C(d6781d0b5e18eb68), C(b992913cae09b533), C(58f6021caaee3a40), - C(aafcb77497b5a20b), C(411819e5e79b77a3), C(bd779579c51c77ce), - C(58d11f5dcf5d075d), C(aafcb77497b5a20b), C(411819e5e79b77a3), - C(bd779579c51c77ce), C(58d11f5dcf5d075d), C(9eae76cde1cb4233), - C(32fe25a9bf657970), C(1c0c807948edb06a), C(b8f29a3dfaee254d), C(e686f3db)}, - {C(226651cf18f4884c), C(595052a874f0f51c), C(c9b75162b23bab42), - C(3f44f873be4812ec), C(427662c1dbfaa7b2), C(a207ff9638fb6558), - C(a738d919e45f550f), C(3f44f873be4812ec), C(427662c1dbfaa7b2), - C(a207ff9638fb6558), C(a738d919e45f550f), C(cb186ea05717e7d6), - C(1ca7d68a5871fdc1), C(5d4c119ea8ef3750), C(72b6a10fa2ff9406), C(cce7c55)}, - {C(a734fb047d3162d6), C(e523170d240ba3a5), C(125a6972809730e8), - C(d396a297799c24a1), C(8fee992e3069bad5), C(2e3a01b0697ccf57), - C(ee9c7390bd901cfa), C(d396a297799c24a1), C(8fee992e3069bad5), - C(2e3a01b0697ccf57), C(ee9c7390bd901cfa), C(56f2d9da0af28af2), - C(3fdd37b2fe8437cb), C(3d13eeeb60d6aec0), C(2432ae62e800a5ce), C(f58b96b)}, + {C(226651cf18f4884c), C(595052a874f0f51c), C(c9b75162b23bab42), C(cce7c55)}, + {C(a734fb047d3162d6), C(e523170d240ba3a5), C(125a6972809730e8), C(f58b96b)}, {C(c6df6364a24f75a3), C(c294e2c84c4f5df8), C(a88df65c6a89313b), - C(895fe8443183da74), C(c7f2f6f895a67334), C(a0d6b6a506691d31), - C(24f51712b459a9f0), C(895fe8443183da74), C(c7f2f6f895a67334), - C(a0d6b6a506691d31), C(24f51712b459a9f0), C(173a699481b9e088), - C(1dee9b77bcbf45d3), C(32b98a646a8667d0), C(3adcd4ee28f42a0e), C(1bbf6f60)}, - {C(d8d1364c1fbcd10), C(2d7cc7f54832deaa), C(4e22c876a7c57625), - C(a3d5d1137d30c4bd), C(1e7d706a49bdfb9e), C(c63282b20ad86db2), - C(aec97fa07916bfd6), C(a3d5d1137d30c4bd), C(1e7d706a49bdfb9e), - C(c63282b20ad86db2), C(aec97fa07916bfd6), C(7c9ba3e52d44f73e), - C(af62fd245811185d), C(8a9d2dacd8737652), C(bd2cce277d5fbec0), - C(ce5e0cc2)}, + {C(d8d1364c1fbcd10), C(2d7cc7f54832deaa), C(4e22c876a7c57625), C(ce5e0cc2)}, {C(aae06f9146db885f), C(3598736441e280d9), C(fba339b117083e55), - C(b22bf08d9f8aecf7), C(c182730de337b922), C(2b9adc87a0450a46), - C(192c29a9cfc00aad), C(b22bf08d9f8aecf7), C(c182730de337b922), - C(2b9adc87a0450a46), C(192c29a9cfc00aad), C(9fd733f1d84a59d9), - C(d86bd5c9839ace15), C(af20b57303172876), C(9f63cb7161b5364c), C(584cfd6f)}, {C(8955ef07631e3bcc), C(7d70965ea3926f83), C(39aed4134f8b2db6), - C(882efc2561715a9c), C(ef8132a18a540221), C(b20a3c87a8c257c1), - C(f541b8628fad6c23), C(882efc2561715a9c), C(ef8132a18a540221), - C(b20a3c87a8c257c1), C(f541b8628fad6c23), C(9552aed57a6e0467), - C(4d9fdd56867611a7), C(c330279bf23b9eab), C(44dbbaea2fcb8eba), C(8f9bbc33)}, {C(ad611c609cfbe412), C(d3c00b18bf253877), C(90b2172e1f3d0bfd), - C(371a98b2cb084883), C(33a2886ee9f00663), C(be9568818ed6e6bd), - C(f244a0fa2673469a), C(371a98b2cb084883), C(33a2886ee9f00663), - C(be9568818ed6e6bd), C(f244a0fa2673469a), C(b447050bd3e559e9), - C(d3b695dae7a13383), C(ded0bb65be471188), C(ca3c7a2b78922cae), C(d7640d95)}, - {C(d5339adc295d5d69), C(b633cc1dcb8b586a), C(ee84184cf5b1aeaf), - C(89f3aab99afbd636), C(f420e004f8148b9a), C(6818073faa797c7c), - C(dd3b4e21cbbf42ca), C(89f3aab99afbd636), C(f420e004f8148b9a), - C(6818073faa797c7c), C(dd3b4e21cbbf42ca), C(6a2b7db261164844), - C(cbead63d1895852a), C(93d37e1eae05e2f9), C(5d06db2703fbc3ae), C(3d12a2b)}, + {C(d5339adc295d5d69), C(b633cc1dcb8b586a), C(ee84184cf5b1aeaf), C(3d12a2b)}, {C(40d0aeff521375a8), C(77ba1ad7ecebd506), C(547c6f1a7d9df427), - C(21c2be098327f49b), C(7e035065ac7bbef5), C(6d7348e63023fb35), - C(9d427dc1b67c3830), C(21c2be098327f49b), C(7e035065ac7bbef5), - C(6d7348e63023fb35), C(9d427dc1b67c3830), C(4e3d018a43858341), - C(cf924bb44d6b43c5), C(4618b6a26e3446ae), C(54d3013fac3ed469), C(aaeafed0)}, {C(8b2d54ae1a3df769), C(11e7adaee3216679), C(3483781efc563e03), - C(9d097dd3152ab107), C(51e21d24126e8563), C(cba56cac884a1354), - C(39abb1b595f0a977), C(9d097dd3152ab107), C(51e21d24126e8563), - C(cba56cac884a1354), C(39abb1b595f0a977), C(81e6dd1c1109848f), - C(1644b209826d7b15), C(6ac67e4e4b4812f0), C(b3a9f5622c935bf7), C(95b9b814)}, {C(99c175819b4eae28), C(932e8ff9f7a40043), C(ec78dcab07ca9f7c), - C(c1a78b82ba815b74), C(458cbdfc82eb322a), C(17f4a192376ed8d7), - C(6f9e92968bc8ccef), C(c1a78b82ba815b74), C(458cbdfc82eb322a), - C(17f4a192376ed8d7), C(6f9e92968bc8ccef), C(93e098c333b39905), - C(d59b1cace44b7fdc), C(f7a64ed78c64c7c5), C(7c6eca5dd87ec1ce), C(45fbe66e)}, {C(2a418335779b82fc), C(af0295987849a76b), C(c12bc5ff0213f46e), - C(5aeead8d6cb25bb9), C(739315f7743ec3ff), C(9ab48d27111d2dcc), - C(5b87bd35a975929b), C(5aeead8d6cb25bb9), C(739315f7743ec3ff), - C(9ab48d27111d2dcc), C(5b87bd35a975929b), C(c3dd8d6d95a46bb3), - C(7bf9093215a4f483), C(cb557d6ed84285bd), C(daf58422f261fdb5), C(b4baa7a8)}, - {C(3b1fc6a3d279e67d), C(70ea1e49c226396), C(25505adcf104697c), - C(ba1ffba29f0367aa), C(a20bec1dd15a8b6c), C(e9bf61d2dab0f774), - C(f4f35bf5870a049c), C(ba1ffba29f0367aa), C(a20bec1dd15a8b6c), - C(e9bf61d2dab0f774), C(f4f35bf5870a049c), C(26787efa5b92385), - C(3d9533590ce30b59), C(a4da3e40530a01d4), C(6395deaefb70067c), - C(83e962fe)}, - {C(d97eacdf10f1c3c9), C(b54f4654043a36e0), C(b128f6eb09d1234), - C(d8ad7ec84a9c9aa2), C(e256cffed11f69e6), C(2cf65e4958ad5bda), - C(cfbf9b03245989a7), C(d8ad7ec84a9c9aa2), C(e256cffed11f69e6), - C(2cf65e4958ad5bda), C(cfbf9b03245989a7), C(9fa51e6686cf4444), - C(9425c117a34609d5), C(b25f7e2c6f30e96), C(ea5477c3f2b5afd1), C(aac3531c)}, + {C(3b1fc6a3d279e67d), C(70ea1e49c226396), C(25505adcf104697c), C(83e962fe)}, + {C(d97eacdf10f1c3c9), C(b54f4654043a36e0), C(b128f6eb09d1234), C(aac3531c)}, {C(293a5c1c4e203cd4), C(6b3329f1c130cefe), C(f2e32f8ec76aac91), - C(361e0a62c8187bff), C(6089971bb84d7133), C(93df7741588dd50b), - C(c2a9b6abcd1d80b1), C(361e0a62c8187bff), C(6089971bb84d7133), - C(93df7741588dd50b), C(c2a9b6abcd1d80b1), C(4d2f86869d79bc59), - C(85cd24d8aa570ff), C(b0dcf6ef0e94bbb5), C(2037c69aa7a78421), C(2b1db7cc)}, + C(2b1db7cc)}, {C(4290e018ffaedde7), C(a14948545418eb5e), C(72d851b202284636), - C(4ec02f3d2f2b23f2), C(ab3580708aa7c339), C(cdce066fbab3f65), - C(d8ed3ecf3c7647b9), C(4ec02f3d2f2b23f2), C(ab3580708aa7c339), - C(cdce066fbab3f65), C(d8ed3ecf3c7647b9), C(6d2204b3e31f344a), - C(61a4d87f80ee61d7), C(446c43dbed4b728f), C(73130ac94f58747e), C(cf00cd31)}, {C(f919a59cbde8bf2f), C(a56d04203b2dc5a5), C(38b06753ac871e48), - C(c2c9fc637dbdfcfa), C(292ab8306d149d75), C(7f436b874b9ffc07), - C(a5b56b0129218b80), C(c2c9fc637dbdfcfa), C(292ab8306d149d75), - C(7f436b874b9ffc07), C(a5b56b0129218b80), C(9188f7bdc47ec050), - C(cfe9345d03a15ade), C(40b520fb2750c49e), C(c2e83d343968af2e), C(7d3c43b8)}, {C(1d70a3f5521d7fa4), C(fb97b3fdc5891965), C(299d49bbbe3535af), - C(e1a8286a7d67946e), C(52bd956f047b298), C(cbd74332dd4204ac), - C(12b5be7752721976), C(e1a8286a7d67946e), C(52bd956f047b298), - C(cbd74332dd4204ac), C(12b5be7752721976), C(278426e27f6204b6), - C(932ca7a7cd610181), C(41647321f0a5914d), C(48f4aa61a0ae80db), C(cbd5fac6)}, {C(6af98d7b656d0d7c), C(d2e99ae96d6b5c0c), C(f63bd1603ef80627), - C(bde51033ac0413f8), C(bc0272f691aec629), C(6204332651bebc44), - C(1cbf00de026ea9bd), C(bde51033ac0413f8), C(bc0272f691aec629), - C(6204332651bebc44), C(1cbf00de026ea9bd), C(b9c7ed6a75f3ff1e), - C(7e310b76a5808e4f), C(acbbd1aad5531885), C(fc245f2473adeb9c), C(76d0fec4)}, - {C(395b7a8adb96ab75), C(582df7165b20f4a), C(e52bd30e9ff657f9), - C(6c71064996cbec8b), C(352c535edeefcb89), C(ac7f0aba15cd5ecd), - C(3aba1ca8353e5c60), C(6c71064996cbec8b), C(352c535edeefcb89), - C(ac7f0aba15cd5ecd), C(3aba1ca8353e5c60), C(5c30a288a80ce646), - C(c2940488b6617674), C(925f8cc66b370575), C(aa65d1283b9bb0ef), - C(405e3402)}, + {C(395b7a8adb96ab75), C(582df7165b20f4a), C(e52bd30e9ff657f9), C(405e3402)}, {C(3822dd82c7df012f), C(b9029b40bd9f122b), C(fd25b988468266c4), - C(43e47bd5bab1e0ef), C(4a71f363421f282f), C(880b2f32a2b4e289), - C(1299d4eda9d3eadf), C(43e47bd5bab1e0ef), C(4a71f363421f282f), - C(880b2f32a2b4e289), C(1299d4eda9d3eadf), C(d713a40226f5564), - C(4d8d34fedc769406), C(a85001b29cd9cac3), C(cae92352a41fd2b0), C(c732c481)}, {C(79f7efe4a80b951a), C(dd3a3fddfc6c9c41), C(ab4c812f9e27aa40), - C(832954ec9d0de333), C(94c390aa9bcb6b8a), C(f3b32afdc1f04f82), - C(d229c3b72e4b9a74), C(832954ec9d0de333), C(94c390aa9bcb6b8a), - C(f3b32afdc1f04f82), C(d229c3b72e4b9a74), C(1d11860d7ed624a6), - C(cadee20b3441b984), C(75307079bf306f7b), C(87902aa3b9753ba4), C(a8d123c9)}, - {C(ae6e59f5f055921a), C(e9d9b7bf68e82), C(5ce4e4a5b269cc59), - C(4960111789727567), C(149b8a37c7125ab6), C(78c7a13ab9749382), - C(1c61131260ca151a), C(4960111789727567), C(149b8a37c7125ab6), - C(78c7a13ab9749382), C(1c61131260ca151a), C(1e93276b35c309a0), - C(2618f56230acde58), C(af61130a18e4febf), C(7145deb18e89befe), - C(1e80ad7d)}, + {C(ae6e59f5f055921a), C(e9d9b7bf68e82), C(5ce4e4a5b269cc59), C(1e80ad7d)}, {C(8959dbbf07387d36), C(b4658afce48ea35d), C(8f3f82437d8cb8d6), - C(6566d74954986ba5), C(99d5235cc82519a7), C(257a23805c2d825), - C(ad75ccb968e93403), C(6566d74954986ba5), C(99d5235cc82519a7), - C(257a23805c2d825), C(ad75ccb968e93403), C(b45bd4cf78e11f7f), - C(80c5536bdc487983), C(a4fd76ecbf018c8a), C(3b9dac78a7a70d43), C(52aeb863)}, {C(4739613234278a49), C(99ea5bcd340bf663), C(258640912e712b12), - C(c8a2827404991402), C(7ee5e78550f02675), C(2ec53952db5ac662), - C(1526405a9df6794b), C(c8a2827404991402), C(7ee5e78550f02675), - C(2ec53952db5ac662), C(1526405a9df6794b), C(eddc6271170c5e1f), - C(f5a85f986001d9d6), C(95427c677bf58d58), C(53ed666dfa85cb29), C(ef7c0c18)}, {C(420e6c926bc54841), C(96dbbf6f4e7c75cd), C(d8d40fa70c3c67bb), - C(3edbc10e4bfee91b), C(f0d681304c28ef68), C(77ea602029aaaf9c), - C(90f070bd24c8483c), C(3edbc10e4bfee91b), C(f0d681304c28ef68), - C(77ea602029aaaf9c), C(90f070bd24c8483c), C(28bc8e41e08ceb86), - C(1eb56e48a65691ef), C(9fea5301c9202f0e), C(3fcb65091aa9f135), C(b6ad4b68)}, {C(c8601bab561bc1b7), C(72b26272a0ff869a), C(56fdfc986d6bc3c4), - C(83707730cad725d4), C(c9ca88c3a779674a), C(e1c696fbbd9aa933), - C(723f3baab1c17a45), C(83707730cad725d4), C(c9ca88c3a779674a), - C(e1c696fbbd9aa933), C(723f3baab1c17a45), C(f82abc7a1d851682), - C(30683836818e857d), C(78bfa3e89a5ab23f), C(6928234482b31817), C(c1e46b17)}, - {C(b2d294931a0e20eb), C(284ffd9a0815bc38), C(1f8a103aac9bbe6), - C(1ef8e98e1ea57269), C(5971116272f45a8b), C(187ad68ce95d8eac), - C(e94e93ee4e8ecaa6), C(1ef8e98e1ea57269), C(5971116272f45a8b), - C(187ad68ce95d8eac), C(e94e93ee4e8ecaa6), C(a0ff2a58611838b5), - C(b01e03849bfbae6f), C(d081e202e28ea3ab), C(51836bcee762bf13), - C(57b8df25)}, + {C(b2d294931a0e20eb), C(284ffd9a0815bc38), C(1f8a103aac9bbe6), C(57b8df25)}, {C(7966f53c37b6c6d7), C(8e6abcfb3aa2b88f), C(7f2e5e0724e5f345), - C(3eeb60c3f5f8143d), C(a25aec05c422a24f), C(b026b03ad3cca4db), - C(e6e030028cc02a02), C(3eeb60c3f5f8143d), C(a25aec05c422a24f), - C(b026b03ad3cca4db), C(e6e030028cc02a02), C(16fe679338b34bfc), - C(c1be385b5c8a9de4), C(65af5df6567530eb), C(ed3b303df4dc6335), C(e9fa36d6)}, {C(be9bb0abd03b7368), C(13bca93a3031be55), C(e864f4f52b55b472), - C(36a8d13a2cbb0939), C(254ac73907413230), C(73520d1522315a70), - C(8c9fdb5cf1e1a507), C(36a8d13a2cbb0939), C(254ac73907413230), - C(73520d1522315a70), C(8c9fdb5cf1e1a507), C(b3640570b926886), - C(fba2344ee87f7bab), C(de57341ab448df05), C(385612ee094fa977), C(8f8daefc)}, - {C(a08d128c5f1649be), C(a8166c3dbbe19aad), C(cb9f914f829ec62c), - C(5b2b7ca856fad1c3), C(8093022d682e375d), C(ea5d163ba7ea231f), - C(d6181d012c0de641), C(5b2b7ca856fad1c3), C(8093022d682e375d), - C(ea5d163ba7ea231f), C(d6181d012c0de641), C(e7d40d0ab8b08159), - C(2e82320f51b3a67e), C(27c2e356ea0b63a3), C(58842d01a2b1d077), C(6e1bb7e)}, + {C(a08d128c5f1649be), C(a8166c3dbbe19aad), C(cb9f914f829ec62c), C(6e1bb7e)}, {C(7c386f0ffe0465ac), C(530419c9d843dbf3), C(7450e3a4f72b8d8c), - C(48b218e3b721810d), C(d3757ac8609bc7fc), C(111ba02a88aefc8), - C(e86343137d3bfc2a), C(48b218e3b721810d), C(d3757ac8609bc7fc), - C(111ba02a88aefc8), C(e86343137d3bfc2a), C(44ad26b51661b507), - C(db1268670274f51e), C(62a5e75beae875f3), C(e266e7a44c5f28c6), C(fd0076f0)}, - {C(bb362094e7ef4f8), C(ff3c2a48966f9725), C(55152803acd4a7fe), - C(15747d8c505ffd00), C(438a15f391312cd6), C(e46ca62c26d821f5), - C(be78d74c9f79cb44), C(15747d8c505ffd00), C(438a15f391312cd6), - C(e46ca62c26d821f5), C(be78d74c9f79cb44), C(a8aa19f3aa59f09a), - C(effb3cddab2c9267), C(d78e41ad97cb16a5), C(ace6821513527d32), - C(899b17b6)}, + {C(bb362094e7ef4f8), C(ff3c2a48966f9725), C(55152803acd4a7fe), C(899b17b6)}, {C(cd80dea24321eea4), C(52b4fdc8130c2b15), C(f3ea100b154bfb82), - C(d9ccef1d4be46988), C(5ede0c4e383a5e66), C(da69683716a54d1e), - C(bfc3fdf02d242d24), C(d9ccef1d4be46988), C(5ede0c4e383a5e66), - C(da69683716a54d1e), C(bfc3fdf02d242d24), C(20ed30274651b3f5), - C(4c659824169e86c6), C(637226dae5b52a0e), C(7e050dbd1c71dc7f), C(e3e84e31)}, {C(d599a04125372c3a), C(313136c56a56f363), C(1e993c3677625832), - C(2870a99c76a587a4), C(99f74cc0b182dda4), C(8a5e895b2f0ca7b6), - C(3d78882d5e0bb1dc), C(2870a99c76a587a4), C(99f74cc0b182dda4), - C(8a5e895b2f0ca7b6), C(3d78882d5e0bb1dc), C(f466123732a3e25e), - C(aca5e59716a40e50), C(261d2e7383d0e686), C(ce9362d6a42c15a7), C(eef79b6b)}, - {C(dbbf541e9dfda0a), C(1479fceb6db4f844), C(31ab576b59062534), - C(a3335c417687cf3a), C(92ff114ac45cda75), C(c3b8a627384f13b5), - C(c4f25de33de8b3f7), C(a3335c417687cf3a), C(92ff114ac45cda75), - C(c3b8a627384f13b5), C(c4f25de33de8b3f7), C(eacbf520578c5964), - C(4cb19c5ab24f3215), C(e7d8a6f67f0c6e7), C(325c2413eb770ada), C(868e3315)}, - {C(c2ee3288be4fe2bf), C(c65d2f5ddf32b92), C(af6ecdf121ba5485), - C(c7cd48f7abf1fe59), C(ce600656ace6f53a), C(8a94a4381b108b34), - C(f9d1276c64bf59fb), C(c7cd48f7abf1fe59), C(ce600656ace6f53a), - C(8a94a4381b108b34), C(f9d1276c64bf59fb), C(219ce70ff5a112a5), - C(e6026c576e2d28d7), C(b8e467f25015e3a6), C(950cb904f37af710), - C(4639a426)}, + {C(dbbf541e9dfda0a), C(1479fceb6db4f844), C(31ab576b59062534), C(868e3315)}, + {C(c2ee3288be4fe2bf), C(c65d2f5ddf32b92), C(af6ecdf121ba5485), C(4639a426)}, {C(d86603ced1ed4730), C(f9de718aaada7709), C(db8b9755194c6535), - C(d803e1eead47604c), C(ad00f7611970a71b), C(bc50036b16ce71f5), - C(afba96210a2ca7d6), C(d803e1eead47604c), C(ad00f7611970a71b), - C(bc50036b16ce71f5), C(afba96210a2ca7d6), C(28f7a7be1d6765f0), - C(97bd888b93938c68), C(6ad41d1b407ded49), C(b9bfec098dc543e4), C(f3213646)}, {C(915263c671b28809), C(a815378e7ad762fd), C(abec6dc9b669f559), - C(d17c928c5342477f), C(745130b795254ad5), C(8c5db926fe88f8ba), - C(742a95c953e6d974), C(d17c928c5342477f), C(745130b795254ad5), - C(8c5db926fe88f8ba), C(742a95c953e6d974), C(279db8057b5d3e96), - C(98168411565b4ec4), C(50a72c54fa1125fa), C(27766a635db73638), C(17f148e9)}, - {C(2b67cdd38c307a5e), C(cb1d45bb5c9fe1c), C(800baf2a02ec18ad), - C(6531c1fe32bcb417), C(8c970d8df8cdbeb4), C(917ba5fc67e72b40), - C(4b65e4e263e0a426), C(6531c1fe32bcb417), C(8c970d8df8cdbeb4), - C(917ba5fc67e72b40), C(4b65e4e263e0a426), C(e0de33ce88a8b3a9), - C(f8ef98a437e16b08), C(a5162c0c7c5f7b62), C(dbdac43361b2b881), - C(bfd94880)}, + {C(2b67cdd38c307a5e), C(cb1d45bb5c9fe1c), C(800baf2a02ec18ad), C(bfd94880)}, {C(2d107419073b9cd0), C(a96db0740cef8f54), C(ec41ee91b3ecdc1b), - C(ffe319654c8e7ebc), C(6a67b8f13ead5a72), C(6dd10a34f80d532f), - C(6e9cfaece9fbca4), C(ffe319654c8e7ebc), C(6a67b8f13ead5a72), - C(6dd10a34f80d532f), C(6e9cfaece9fbca4), C(b4468eb6a30aa7e9), - C(e87995bee483222a), C(d036c2c90c609391), C(853306e82fa32247), C(bb1fa7f3)}, - {C(f3e9487ec0e26dfc), C(1ab1f63224e837fa), C(119983bb5a8125d8), - C(8950cfcf4bdf622c), C(8847dca82efeef2f), C(646b75b026708169), - C(21cab4b1687bd8b), C(8950cfcf4bdf622c), C(8847dca82efeef2f), - C(646b75b026708169), C(21cab4b1687bd8b), C(243b489a9eae6231), - C(5f3e634c4b779876), C(ff8abd1548eaf646), C(c7962f5f0151914b), C(88816b1)}, + {C(f3e9487ec0e26dfc), C(1ab1f63224e837fa), C(119983bb5a8125d8), C(88816b1)}, {C(1160987c8fe86f7d), C(879e6db1481eb91b), C(d7dcb802bfe6885d), - C(14453b5cc3d82396), C(4ef700c33ed278bc), C(1639c72ffc00d12e), - C(fb140ee6155f700d), C(14453b5cc3d82396), C(4ef700c33ed278bc), - C(1639c72ffc00d12e), C(fb140ee6155f700d), C(2e6b5c96a6620862), - C(a1f136998cbe19c), C(74e058a3b6c5a712), C(93dcf6bd33928b17), C(5c2faeb3)}, + C(5c2faeb3)}, {C(eab8112c560b967b), C(97f550b58e89dbae), C(846ed506d304051f), - C(276aa37744b5a028), C(8c10800ee90ea573), C(e6e57d2b33a1e0b7), - C(91f83563cd3b9dda), C(276aa37744b5a028), C(8c10800ee90ea573), - C(e6e57d2b33a1e0b7), C(91f83563cd3b9dda), C(afbb4739570738a1), - C(440ba98da5d8f69), C(fde4e9b0eda20350), C(e67dfa5a2138fa1), C(51b5fc6f)}, + C(51b5fc6f)}, {C(1addcf0386d35351), C(b5f436561f8f1484), C(85d38e22181c9bb1), - C(ff5c03f003c1fefe), C(e1098670afe7ff6), C(ea445030cf86de19), - C(f155c68b5c2967f8), C(ff5c03f003c1fefe), C(e1098670afe7ff6), - C(ea445030cf86de19), C(f155c68b5c2967f8), C(95d31b145dbb2e9e), - C(914fe1ca3deb3265), C(6066020b1358ccc1), C(c74bb7e2dee15036), C(33d94752)}, {C(d445ba84bf803e09), C(1216c2497038f804), C(2293216ea2237207), - C(e2164451c651adfb), C(b2534e65477f9823), C(4d70691a69671e34), - C(15be4963dbde8143), C(e2164451c651adfb), C(b2534e65477f9823), - C(4d70691a69671e34), C(15be4963dbde8143), C(762e75c406c5e9a3), - C(7b7579f7e0356841), C(480533eb066dfce5), C(90ae14ea6bfeb4ae), C(b0c92948)}, {C(37235a096a8be435), C(d9b73130493589c2), C(3b1024f59378d3be), - C(ad159f542d81f04e), C(49626a97a946096), C(d8d3998bf09fd304), - C(d127a411eae69459), C(ad159f542d81f04e), C(49626a97a946096), - C(d8d3998bf09fd304), C(d127a411eae69459), C(8f3253c4eb785a7b), - C(4049062f37e62397), C(b9fa04d3b670e5c1), C(1211a7967ac9350f), C(c7171590)}, {C(763ad6ea2fe1c99d), C(cf7af5368ac1e26b), C(4d5e451b3bb8d3d4), - C(3712eb913d04e2f2), C(2f9500d319c84d89), C(4ac6eb21a8cf06f9), - C(7d1917afcde42744), C(3712eb913d04e2f2), C(2f9500d319c84d89), - C(4ac6eb21a8cf06f9), C(7d1917afcde42744), C(6b58604b5dd10903), - C(c4288dfbc1e319fc), C(230f75ca96817c6e), C(8894cba3b763756c), C(240a67fb)}, {C(ea627fc84cd1b857), C(85e372494520071f), C(69ec61800845780b), - C(a3c1c5ca1b0367), C(eb6933997272bb3d), C(76a72cb62692a655), - C(140bb5531edf756e), C(a3c1c5ca1b0367), C(eb6933997272bb3d), - C(76a72cb62692a655), C(140bb5531edf756e), C(8d0d8067d1c925f4), - C(7b3fa56d8d77a10c), C(2bd00287b0946d88), C(f08c8e4bd65b8970), C(e1843cd5)}, {C(1f2ffd79f2cdc0c8), C(726a1bc31b337aaa), C(678b7f275ef96434), - C(5aa82bfaa99d3978), C(c18f96cade5ce18d), C(38404491f9e34c03), - C(891fb8926ba0418c), C(5aa82bfaa99d3978), C(c18f96cade5ce18d), - C(38404491f9e34c03), C(891fb8926ba0418c), C(e5f69a6398114c15), - C(7b8ded3623bc6b1d), C(2f3e5c5da5ff70e8), C(1ab142addea6a9ec), C(fda1452b)}, {C(39a9e146ec4b3210), C(f63f75802a78b1ac), C(e2e22539c94741c3), - C(8b305d532e61226e), C(caeae80da2ea2e), C(88a6289a76ac684e), - C(8ce5b5f9df1cbd85), C(8b305d532e61226e), C(caeae80da2ea2e), - C(88a6289a76ac684e), C(8ce5b5f9df1cbd85), C(8ae1fc4798e00d57), - C(e7164b8fb364fc46), C(6a978c9bd3a66943), C(ef10d5ae4dd08dc), C(a2cad330)}, + C(a2cad330)}, {C(74cba303e2dd9d6d), C(692699b83289fad1), C(dfb9aa7874678480), - C(751390a8a5c41bdc), C(6ee5fbf87605d34), C(6ca73f610f3a8f7c), - C(e898b3c996570ad), C(751390a8a5c41bdc), C(6ee5fbf87605d34), - C(6ca73f610f3a8f7c), C(e898b3c996570ad), C(98168a5858fc7110), - C(6f987fa27aa0daa2), C(f25e3e180d4b36a3), C(d0b03495aeb1be8a), C(53467e16)}, {C(4cbc2b73a43071e0), C(56c5db4c4ca4e0b7), C(1b275a162f46bd3d), - C(b87a326e413604bf), C(d8f9a5fa214b03ab), C(8a8bb8265771cf88), - C(a655319054f6e70f), C(b87a326e413604bf), C(d8f9a5fa214b03ab), - C(8a8bb8265771cf88), C(a655319054f6e70f), C(b499cb8e65a9af44), - C(bee7fafcc8307491), C(5d2e55fa9b27cda2), C(63b120f5fb2d6ee5), C(da14a8d0)}, {C(875638b9715d2221), C(d9ba0615c0c58740), C(616d4be2dfe825aa), - C(5df25f13ea7bc284), C(165edfaafd2598fb), C(af7215c5c718c696), - C(e9f2f9ca655e769), C(5df25f13ea7bc284), C(165edfaafd2598fb), - C(af7215c5c718c696), C(e9f2f9ca655e769), C(e459cfcb565d3d2d), - C(41d032631be2418a), C(c505db05fd946f60), C(54990394a714f5de), C(67333551)}, {C(fb686b2782994a8d), C(edee60693756bb48), C(e6bc3cae0ded2ef5), - C(58eb4d03b2c3ddf5), C(6d2542995f9189f1), C(c0beec58a5f5fea2), - C(ed67436f42e2a78b), C(58eb4d03b2c3ddf5), C(6d2542995f9189f1), - C(c0beec58a5f5fea2), C(ed67436f42e2a78b), C(dfec763cdb2b5193), - C(724a8d5345bd2d6), C(94d4fd1b81457c23), C(28e87c50cdede453), C(a0ebd66e)}, + C(a0ebd66e)}, {C(ab21d81a911e6723), C(4c31b07354852f59), C(835da384c9384744), - C(7f759dddc6e8549a), C(616dd0ca022c8735), C(94717ad4bc15ceb3), - C(f66c7be808ab36e), C(7f759dddc6e8549a), C(616dd0ca022c8735), - C(94717ad4bc15ceb3), C(f66c7be808ab36e), C(af8286b550b2f4b7), - C(745bd217d20a9f40), C(c73bfb9c5430f015), C(55e65922666e3fc2), C(4b769593)}, {C(33d013cc0cd46ecf), C(3de726423aea122c), C(116af51117fe21a9), - C(f271ba474edc562d), C(e6596e67f9dd3ebd), C(c0a288edf808f383), - C(b3def70681c6babc), C(f271ba474edc562d), C(e6596e67f9dd3ebd), - C(c0a288edf808f383), C(b3def70681c6babc), C(7da7864e9989b095), - C(bf2f8718693cd8a1), C(264a9144166da776), C(61ad90676870beb6), C(6aa75624)}, - {C(8ca92c7cd39fae5d), C(317e620e1bf20f1), C(4f0b33bf2194b97f), - C(45744afcf131dbee), C(97222392c2559350), C(498a19b280c6d6ed), - C(83ac2c36acdb8d49), C(45744afcf131dbee), C(97222392c2559350), - C(498a19b280c6d6ed), C(83ac2c36acdb8d49), C(7a69645c294daa62), - C(abe9d2be8275b3d2), C(39542019de371085), C(7f4efac8488cd6ad), - C(602a3f96)}, - {C(fdde3b03f018f43e), C(38f932946c78660), C(c84084ce946851ee), - C(b6dd09ba7851c7af), C(570de4e1bb13b133), C(c4e784eb97211642), - C(8285a7fcdcc7c58d), C(b6dd09ba7851c7af), C(570de4e1bb13b133), - C(c4e784eb97211642), C(8285a7fcdcc7c58d), C(d421f47990da899b), - C(8aed409c997eaa13), C(7a045929c2e29ccf), C(b373682a6202c86b), - C(cd183c4d)}, + {C(8ca92c7cd39fae5d), C(317e620e1bf20f1), C(4f0b33bf2194b97f), C(602a3f96)}, + {C(fdde3b03f018f43e), C(38f932946c78660), C(c84084ce946851ee), C(cd183c4d)}, {C(9c8502050e9c9458), C(d6d2a1a69964beb9), C(1675766f480229b5), - C(216e1d6c86cb524c), C(d01cf6fd4f4065c0), C(fffa4ec5b482ea0f), - C(a0e20ee6a5404ac1), C(216e1d6c86cb524c), C(d01cf6fd4f4065c0), - C(fffa4ec5b482ea0f), C(a0e20ee6a5404ac1), C(c1b037e4eebaf85e), - C(634e3d7c3ebf89eb), C(bcda972358c67d1), C(fd1352181e5b8578), C(960a4d07)}, + C(960a4d07)}, {C(348176ca2fa2fdd2), C(3a89c514cc360c2d), C(9f90b8afb318d6d0), - C(bceee07c11a9ac30), C(2e2d47dff8e77eb7), C(11a394cd7b6d614a), - C(1d7c41d54e15cb4a), C(bceee07c11a9ac30), C(2e2d47dff8e77eb7), - C(11a394cd7b6d614a), C(1d7c41d54e15cb4a), C(15baa5ae7312b0fc), - C(f398f596cc984635), C(8ab8fdf87a6788e8), C(b2b5c1234ab47e2), C(9ae998c4)}, + C(9ae998c4)}, {C(4a3d3dfbbaea130b), C(4e221c920f61ed01), C(553fd6cd1304531f), - C(bd2b31b5608143fe), C(ab717a10f2554853), C(293857f04d194d22), - C(d51be8fa86f254f0), C(bd2b31b5608143fe), C(ab717a10f2554853), - C(293857f04d194d22), C(d51be8fa86f254f0), C(1eee39e07686907e), - C(639039fe0e8d3052), C(d6ec1470cef97ff), C(370c82b860034f0f), C(74e2179d)}, + C(74e2179d)}, {C(b371f768cdf4edb9), C(bdef2ace6d2de0f0), C(e05b4100f7f1baec), - C(b9e0d415b4ebd534), C(c97c2a27efaa33d7), C(591cdb35f84ef9da), - C(a57d02d0e8e3756c), C(b9e0d415b4ebd534), C(c97c2a27efaa33d7), - C(591cdb35f84ef9da), C(a57d02d0e8e3756c), C(23f55f12d7c5c87b), - C(4c7ca0fe23221101), C(dbc3020480334564), C(d985992f32c236b1), C(ee9bae25)}, - {C(7a1d2e96934f61f), C(eb1760ae6af7d961), C(887eb0da063005df), - C(2228d6725e31b8ab), C(9b98f7e4d0142e70), C(b6a8c2115b8e0fe7), - C(b591e2f5ab9b94b1), C(2228d6725e31b8ab), C(9b98f7e4d0142e70), - C(b6a8c2115b8e0fe7), C(b591e2f5ab9b94b1), C(6c1feaa8065318e0), - C(4e7e2ca21c2e81fb), C(e9fe5d8ce7993c45), C(ee411fa2f12cf8df), - C(b66edf10)}, + {C(7a1d2e96934f61f), C(eb1760ae6af7d961), C(887eb0da063005df), C(b66edf10)}, {C(8be53d466d4728f2), C(86a5ac8e0d416640), C(984aa464cdb5c8bb), - C(87049e68f5d38e59), C(7d8ce44ec6bd7751), C(cc28d08ab414839c), - C(6c8f0bd34fe843e3), C(87049e68f5d38e59), C(7d8ce44ec6bd7751), - C(cc28d08ab414839c), C(6c8f0bd34fe843e3), C(b8496dcdc01f3e47), - C(2f03125c282ac26), C(82a8797ba3f5ef07), C(7c977a4d10bf52b8), C(d6209737)}, - {C(829677eb03abf042), C(43cad004b6bc2c0), C(f2f224756803971a), - C(98d0dbf796480187), C(fbcb5f3e1bef5742), C(5af2a0463bf6e921), - C(ad9555bf0120b3a3), C(98d0dbf796480187), C(fbcb5f3e1bef5742), - C(5af2a0463bf6e921), C(ad9555bf0120b3a3), C(283e39b3dc99f447), - C(bedaa1a4a0250c28), C(9d50546624ff9a57), C(4abaf523d1c090f6), C(b994a88)}, - {C(754435bae3496fc), C(5707fc006f094dcf), C(8951c86ab19d8e40), - C(57c5208e8f021a77), C(f7653fbb69cd9276), C(a484410af21d75cb), - C(f19b6844b3d627e8), C(57c5208e8f021a77), C(f7653fbb69cd9276), - C(a484410af21d75cb), C(f19b6844b3d627e8), C(f37400fc3ffd9514), - C(36ae0d821734edfd), C(5f37820af1f1f306), C(be637d40e6a5ad0), C(a05d43c0)}, + C(d6209737)}, + {C(829677eb03abf042), C(43cad004b6bc2c0), C(f2f224756803971a), C(b994a88)}, + {C(754435bae3496fc), C(5707fc006f094dcf), C(8951c86ab19d8e40), C(a05d43c0)}, {C(fda9877ea8e3805f), C(31e868b6ffd521b7), C(b08c90681fb6a0fd), - C(68110a7f83f5d3ff), C(6d77e045901b85a8), C(84ef681113036d8b), - C(3b9f8e3928f56160), C(68110a7f83f5d3ff), C(6d77e045901b85a8), - C(84ef681113036d8b), C(3b9f8e3928f56160), C(fc8b7f56c130835), - C(a11f3e800638e841), C(d9572267f5cf28c1), C(7897c8149803f2aa), C(c79f73a8)}, {C(2e36f523ca8f5eb5), C(8b22932f89b27513), C(331cd6ecbfadc1bb), - C(d1bfe4df12b04cbf), C(f58c17243fd63842), C(3a453cdba80a60af), - C(5737b2ca7470ea95), C(d1bfe4df12b04cbf), C(f58c17243fd63842), - C(3a453cdba80a60af), C(5737b2ca7470ea95), C(54d44a3f4477030c), - C(8168e02d4869aa7f), C(77f383a17778559d), C(95e1737d77a268fc), C(a490aff5)}, {C(21a378ef76828208), C(a5c13037fa841da2), C(506d22a53fbe9812), - C(61c9c95d91017da5), C(16f7c83ba68f5279), C(9c0619b0808d05f7), - C(83c117ce4e6b70a3), C(61c9c95d91017da5), C(16f7c83ba68f5279), - C(9c0619b0808d05f7), C(83c117ce4e6b70a3), C(cfb4c8af7fd01413), - C(fdef04e602e72296), C(ed6124d337889b1), C(4919c86707b830da), C(dfad65b4)}, - {C(ccdd5600054b16ca), C(f78846e84204cb7b), C(1f9faec82c24eac9), - C(58634004c7b2d19a), C(24bb5f51ed3b9073), C(46409de018033d00), - C(4a9805eed5ac802e), C(58634004c7b2d19a), C(24bb5f51ed3b9073), - C(46409de018033d00), C(4a9805eed5ac802e), C(e18de8db306baf82), - C(46bbf75f1fa025ff), C(5faf2fb09be09487), C(3fbc62bd4e558fb3), C(1d07dfb)}, + C(dfad65b4)}, + {C(ccdd5600054b16ca), C(f78846e84204cb7b), C(1f9faec82c24eac9), C(1d07dfb)}, {C(7854468f4e0cabd0), C(3a3f6b4f098d0692), C(ae2423ec7799d30d), - C(29c3529eb165eeba), C(443de3703b657c35), C(66acbce31ae1bc8d), - C(1acc99effe1d547e), C(29c3529eb165eeba), C(443de3703b657c35), - C(66acbce31ae1bc8d), C(1acc99effe1d547e), C(cf07f8a57906573d), - C(31bafb0bbb9a86e7), C(40c69492702a9346), C(7df61fdaa0b858af), C(416df9a0)}, {C(7f88db5346d8f997), C(88eac9aacc653798), C(68a4d0295f8eefa1), - C(ae59ca86f4c3323d), C(25906c09906d5c4c), C(8dd2aa0c0a6584ae), - C(232a7d96b38f40e9), C(ae59ca86f4c3323d), C(25906c09906d5c4c), - C(8dd2aa0c0a6584ae), C(232a7d96b38f40e9), C(8986ee00a2ed0042), - C(c49ae7e428c8a7d1), C(b7dd8280713ac9c2), C(e018720aed1ebc28), C(1f8fb9cc)}, {C(bb3fb5fb01d60fcf), C(1b7cc0847a215eb6), C(1246c994437990a1), - C(d4edc954c07cd8f3), C(224f47e7c00a30ab), C(d5ad7ad7f41ef0c6), - C(59e089281d869fd7), C(d4edc954c07cd8f3), C(224f47e7c00a30ab), - C(d5ad7ad7f41ef0c6), C(59e089281d869fd7), C(f29340d07a14b6f1), - C(c87c5ef76d9c4ef3), C(463118794193a9a), C(2922dcb0540f0dbc), C(7abf48e3)}, + C(7abf48e3)}, {C(2e783e1761acd84d), C(39158042bac975a0), C(1cd21c5a8071188d), - C(b1b7ec44f9302176), C(5cb476450dc0c297), C(dc5ef652521ef6a2), - C(3cc79a9e334e1f84), C(b1b7ec44f9302176), C(5cb476450dc0c297), - C(dc5ef652521ef6a2), C(3cc79a9e334e1f84), C(769e2a283dbcc651), - C(9f24b105c8511d3f), C(c31c15575de2f27e), C(ecfecf32c3ae2d66), C(dea4e3dd)}, {C(392058251cf22acc), C(944ec4475ead4620), C(b330a10b5cb94166), - C(54bc9bee7cbe1767), C(485820bdbe442431), C(54d6120ea2972e90), - C(f437a0341f29b72a), C(54bc9bee7cbe1767), C(485820bdbe442431), - C(54d6120ea2972e90), C(f437a0341f29b72a), C(8f30885c784d5704), - C(aa95376b16c7906a), C(e826928cfaf93dc3), C(20e8f54d1c16d7d8), C(c6064f22)}, - {C(adf5c1e5d6419947), C(2a9747bc659d28aa), C(95c5b8cb1f5d62c), - C(80973ea532b0f310), C(a471829aa9c17dd9), C(c2ff3479394804ab), - C(6bf44f8606753636), C(80973ea532b0f310), C(a471829aa9c17dd9), - C(c2ff3479394804ab), C(6bf44f8606753636), C(5184d2973e6dd827), - C(121b96369a332d9a), C(5c25d3475ab69e50), C(26d2961d62884168), - C(743bed9c)}, + {C(adf5c1e5d6419947), C(2a9747bc659d28aa), C(95c5b8cb1f5d62c), C(743bed9c)}, {C(6bc1db2c2bee5aba), C(e63b0ed635307398), C(7b2eca111f30dbbc), - C(230d2b3e47f09830), C(ec8624a821c1caf4), C(ea6ec411cdbf1cb1), - C(5f38ae82af364e27), C(230d2b3e47f09830), C(ec8624a821c1caf4), - C(ea6ec411cdbf1cb1), C(5f38ae82af364e27), C(a519ef515ea7187c), - C(6bad5efa7ebae05f), C(748abacb11a74a63), C(a28eef963d1396eb), C(fce254d5)}, {C(b00f898229efa508), C(83b7590ad7f6985c), C(2780e70a0592e41d), - C(7122413bdbc94035), C(e7f90fae33bf7763), C(4b6bd0fb30b12387), - C(557359c0c44f48ca), C(7122413bdbc94035), C(e7f90fae33bf7763), - C(4b6bd0fb30b12387), C(557359c0c44f48ca), C(d5656c3d6bc5f0d), - C(983ff8e5e784da99), C(628479671b445bf), C(e179a1e27ce68f5d), C(e47ec9d1)}, + C(e47ec9d1)}, {C(b56eb769ce0d9a8c), C(ce196117bfbcaf04), C(b26c3c3797d66165), - C(5ed12338f630ab76), C(fab19fcb319116d), C(167f5f42b521724b), - C(c4aa56c409568d74), C(5ed12338f630ab76), C(fab19fcb319116d), - C(167f5f42b521724b), C(c4aa56c409568d74), C(75fff4b42f8e9778), - C(94218f94710c1ea3), C(b7b05efb738b06a6), C(83fff2deabf9cd3), C(334a145c)}, + C(334a145c)}, {C(70c0637675b94150), C(259e1669305b0a15), C(46e1dd9fd387a58d), - C(fca4e5bc9292788e), C(cd509dc1facce41c), C(bbba575a59d82fe), - C(4e2e71c15b45d4d3), C(fca4e5bc9292788e), C(cd509dc1facce41c), - C(bbba575a59d82fe), C(4e2e71c15b45d4d3), C(5dc54582ead999c), - C(72612d1571963c6f), C(30318a9d2d3d1829), C(785dd00f4cc9c9a0), C(adec1e3c)}, {C(74c0b8a6821faafe), C(abac39d7491370e7), C(faf0b2a48a4e6aed), - C(967e970df9673d2a), C(d465247cffa415c0), C(33a1df0ca1107722), - C(49fc2a10adce4a32), C(967e970df9673d2a), C(d465247cffa415c0), - C(33a1df0ca1107722), C(49fc2a10adce4a32), C(c5707e079a284308), - C(573028266635dda6), C(f786f5eee6127fa0), C(b30d79cebfb51266), C(f6a9fbf8)}, {C(5fb5e48ac7b7fa4f), C(a96170f08f5acbc7), C(bbf5c63d4f52a1e5), - C(6cc09e60700563e9), C(d18f23221e964791), C(ffc23eeef7af26eb), - C(693a954a3622a315), C(815308a32a9b0daf), C(efb2ab27bf6fd0bd), - C(9f1ffc0986111118), C(f9a3aa1778ea3985), C(698fe54b2b93933b), - C(dacc2b28404d0f10), C(815308a32a9b0daf), C(efb2ab27bf6fd0bd), C(5398210c)}, }; void TestUnchanging(const uint64_t* expected, int offset, int len) { - const uint128 u = CityHash128(data + offset, len); - const uint128 v = CityHash128WithSeed(data + offset, len, kSeed128); EXPECT_EQ(expected[0], CityHash64(data + offset, len)); - EXPECT_EQ(expected[15], CityHash32(data + offset, len)); + EXPECT_EQ(expected[3], CityHash32(data + offset, len)); EXPECT_EQ(expected[1], CityHash64WithSeed(data + offset, len, kSeed0)); EXPECT_EQ(expected[2], CityHash64WithSeeds(data + offset, len, kSeed0, kSeed1)); - EXPECT_EQ(expected[3], Uint128Low64(u)); - EXPECT_EQ(expected[4], Uint128High64(u)); - EXPECT_EQ(expected[5], Uint128Low64(v)); - EXPECT_EQ(expected[6], Uint128High64(v)); -#ifdef __SSE4_2__ - const uint128 y = CityHashCrc128(data + offset, len); - const uint128 z = CityHashCrc128WithSeed(data + offset, len, kSeed128); - uint64_t crc256_results[4]; - CityHashCrc256(data + offset, len, crc256_results); - EXPECT_EQ(expected[7], Uint128Low64(y)); - EXPECT_EQ(expected[8], Uint128High64(y)); - EXPECT_EQ(expected[9], Uint128Low64(z)); - EXPECT_EQ(expected[10], Uint128High64(z)); - for (int i = 0; i < 4; i++) { - EXPECT_EQ(expected[11 + i], crc256_results[i]); - } -#endif } TEST(CityHashTest, Unchanging) {
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 4543d67..6c00f35 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h
@@ -303,13 +303,13 @@ // AbslHashValue for hashing tuples template <typename H, typename... Ts> -#if _MSC_VER +#if defined(_MSC_VER) // This SFINAE gets MSVC confused under some conditions. Let's just disable it // for now. H -#else +#else // _MSC_VER typename std::enable_if<absl::conjunction<is_hashable<Ts>...>::value, H>::type -#endif +#endif // _MSC_VER AbslHashValue(H hash_state, const std::tuple<Ts...>& t) { return hash_internal::hash_tuple(std::move(hash_state), t, absl::make_index_sequence<sizeof...(Ts)>()); @@ -494,6 +494,15 @@ } return H::combine(std::move(hash_state), v.index()); } + +// ----------------------------------------------------------------------------- +// AbslHashValue for Other Types +// ----------------------------------------------------------------------------- + +// AbslHashValue for hashing std::bitset is not defined, for the same reason as +// for vector<bool> (see std::vector above): It does not expose the raw bytes, +// and a fallback to std::hash<> is most likely faster. + // ----------------------------------------------------------------------------- // hash_range_or_bytes() @@ -536,7 +545,7 @@ // In MSVC we can't probe std::hash or stdext::hash because it triggers a // static_assert instead of failing substitution. #if defined(_MSC_VER) -#undef ABSL_HASH_INTERNAL_CAN_POISON_ +#define ABSL_HASH_INTERNAL_CAN_POISON_ 0 #else // _MSC_VER #define ABSL_HASH_INTERNAL_CAN_POISON_ 1 #endif // _MSC_VER @@ -544,6 +553,8 @@ #if defined(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE) && \ ABSL_HASH_INTERNAL_CAN_POISON_ #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 1 +#else +#define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 0 #endif enum class InvokeHashTag {
diff --git a/absl/memory/BUILD.bazel b/absl/memory/BUILD.bazel index 89a312e..c0da9ce 100644 --- a/absl/memory/BUILD.bazel +++ b/absl/memory/BUILD.bazel
@@ -15,7 +15,7 @@ # load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", "ABSL_EXCEPTIONS_FLAG",
diff --git a/absl/memory/CMakeLists.txt b/absl/memory/CMakeLists.txt index 5958f5c..4b494dc 100644 --- a/absl/memory/CMakeLists.txt +++ b/absl/memory/CMakeLists.txt
@@ -14,58 +14,45 @@ # limitations under the License. # -list(APPEND MEMORY_PUBLIC_HEADERS - "memory.h" -) - - -absl_header_library( - TARGET - absl_memory - EXPORT_NAME +absl_cc_library( + NAME memory + HDRS + "memory.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::core_headers + absl::meta + PUBLIC ) -# -## TESTS -# - -# test memory_test -list(APPEND MEMORY_TEST_SRC - "memory_test.cc" - ${MEMORY_PUBLIC_HEADERS} -) -set(MEMORY_TEST_PUBLIC_LIBRARIES absl::base absl::memory) - - - -absl_test( - TARGET +absl_cc_test( + NAME memory_test - SOURCES - ${MEMORY_TEST_SRC} - PUBLIC_LIBRARIES - ${MEMORY_TEST_PUBLIC_LIBRARIES} + SRCS + "memory_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::memory + absl::base + absl::core_headers + gmock_main ) - -# test memory_exception_safety_test -set(MEMORY_EXCEPTION_SAFETY_TEST_SRC "memory_exception_safety_test.cc") -set(MEMORY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES - absl::memory - absl_base_internal_exception_safety_testing -) - -absl_test( - TARGET +absl_cc_test( + NAME memory_exception_safety_test - SOURCES - ${MEMORY_EXCEPTION_SAFETY_TEST_SRC} - PUBLIC_LIBRARIES - ${MEMORY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES} - PRIVATE_COMPILE_FLAGS + SRCS + "memory_exception_safety_test.cc" + COPTS + ${ABSL_TEST_COPTS} ${ABSL_EXCEPTIONS_FLAG} + LINKOPTS + ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} + DEPS + absl::memory + absl::exception_safety_testing + gmock_main ) - - -
diff --git a/absl/memory/memory.h b/absl/memory/memory.h index 1eaec0f..8bf4fe8 100644 --- a/absl/memory/memory.h +++ b/absl/memory/memory.h
@@ -599,7 +599,7 @@ return a.max_size(); } static size_type max_size_impl(char, const Alloc&) { - return std::numeric_limits<size_type>::max() / sizeof(value_type); + return (std::numeric_limits<size_type>::max)() / sizeof(value_type); } template <typename A> @@ -655,59 +655,42 @@ #endif namespace memory_internal { -#ifdef ABSL_HAVE_EXCEPTIONS // ConstructRange template <typename Allocator, typename Iterator, typename... Args> void ConstructRange(Allocator& alloc, Iterator first, Iterator last, const Args&... args) { for (Iterator cur = first; cur != last; ++cur) { - try { - std::allocator_traits<Allocator>::construct(alloc, cur, args...); - } catch (...) { + ABSL_INTERNAL_TRY { + std::allocator_traits<Allocator>::construct(alloc, std::addressof(*cur), + args...); + } + ABSL_INTERNAL_CATCH_ANY { while (cur != first) { --cur; - std::allocator_traits<Allocator>::destroy(alloc, cur); + std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur)); } - throw; + ABSL_INTERNAL_RETHROW; } } } -#else // ABSL_HAVE_EXCEPTIONS // ConstructRange -template <typename Allocator, typename Iterator, typename... Args> -void ConstructRange(Allocator& alloc, Iterator first, Iterator last, - const Args&... args) { - for (; first != last; ++first) { - std::allocator_traits<Allocator>::construct(alloc, first, args...); - } -} -#endif // ABSL_HAVE_EXCEPTIONS // ConstructRange -#ifdef ABSL_HAVE_EXCEPTIONS // CopyRange template <typename Allocator, typename Iterator, typename InputIterator> void CopyRange(Allocator& alloc, Iterator destination, InputIterator first, InputIterator last) { for (Iterator cur = destination; first != last; static_cast<void>(++cur), static_cast<void>(++first)) { - try { - std::allocator_traits<Allocator>::construct(alloc, cur, *first); - } catch (...) { + ABSL_INTERNAL_TRY { + std::allocator_traits<Allocator>::construct(alloc, std::addressof(*cur), + *first); + } + ABSL_INTERNAL_CATCH_ANY { while (cur != destination) { --cur; - std::allocator_traits<Allocator>::destroy(alloc, cur); + std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur)); } - throw; + ABSL_INTERNAL_RETHROW; } } } -#else // ABSL_HAVE_EXCEPTIONS // CopyRange -template <typename Allocator, typename Iterator, typename InputIterator> -void CopyRange(Allocator& alloc, Iterator destination, InputIterator first, - InputIterator last) { - for (; first != last; - static_cast<void>(++destination), static_cast<void>(++first)) { - std::allocator_traits<Allocator>::construct(alloc, destination, *first); - } -} -#endif // ABSL_HAVE_EXCEPTIONS // CopyRange } // namespace memory_internal } // namespace absl
diff --git a/absl/memory/memory_test.cc b/absl/memory/memory_test.cc index 2e453e2..21fe32f 100644 --- a/absl/memory/memory_test.cc +++ b/absl/memory/memory_test.cc
@@ -69,6 +69,45 @@ EXPECT_EQ("hi", *p); } +// InitializationVerifier fills in a pattern when allocated so we can +// distinguish between its default and value initialized states (without +// accessing truly uninitialized memory). +struct InitializationVerifier { + static constexpr int kDefaultScalar = 0x43; + static constexpr int kDefaultArray = 0x4B; + + static void* operator new(size_t n) { + void* ret = ::operator new(n); + memset(ret, kDefaultScalar, n); + return ret; + } + + static void* operator new[](size_t n) { + void* ret = ::operator new[](n); + memset(ret, kDefaultArray, n); + return ret; + } + + int a; + int b; +}; + +TEST(Initialization, MakeUnique) { + auto p = absl::make_unique<InitializationVerifier>(); + + EXPECT_EQ(0, p->a); + EXPECT_EQ(0, p->b); +} + +TEST(Initialization, MakeUniqueArray) { + auto p = absl::make_unique<InitializationVerifier[]>(2); + + EXPECT_EQ(0, p[0].a); + EXPECT_EQ(0, p[0].b); + EXPECT_EQ(0, p[1].a); + EXPECT_EQ(0, p[1].b); +} + struct MoveOnly { MoveOnly() = default; explicit MoveOnly(int i1) : ip1{new int{i1}} {} @@ -145,7 +184,7 @@ explicit TakesStdType(const std::vector<int> &vec) {} }; using absl::make_unique; - make_unique<TakesStdType>(std::vector<int>()); + (void)make_unique<TakesStdType>(std::vector<int>()); } #if 0
diff --git a/absl/meta/BUILD.bazel b/absl/meta/BUILD.bazel index dbc9717..1c39fa9 100644 --- a/absl/meta/BUILD.bazel +++ b/absl/meta/BUILD.bazel
@@ -1,5 +1,5 @@ load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", )
diff --git a/absl/meta/CMakeLists.txt b/absl/meta/CMakeLists.txt index adb0ceb..4358db5 100644 --- a/absl/meta/CMakeLists.txt +++ b/absl/meta/CMakeLists.txt
@@ -14,39 +14,37 @@ # limitations under the License. # -list(APPEND META_PUBLIC_HEADERS - "type_traits.h" +absl_cc_library( + NAME + type_traits + HDRS + "type_traits.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::config + PUBLIC ) - -# -## TESTS -# - -# test type_traits_test -list(APPEND TYPE_TRAITS_TEST_SRC - "type_traits_test.cc" - ${META_PUBLIC_HEADERS} -) - -absl_header_library( - TARGET - absl_meta - PUBLIC_LIBRARIES - absl::base - EXPORT_NAME - meta - ) - -absl_test( - TARGET +absl_cc_test( + NAME type_traits_test - SOURCES - ${TYPE_TRAITS_TEST_SRC} - PUBLIC_LIBRARIES + SRCS + "type_traits_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::type_traits absl::base - absl::meta + absl::core_headers + gmock_main ) - - +# component target +absl_cc_library( + NAME + meta + DEPS + absl::type_traits + PUBLIC +)
diff --git a/absl/numeric/BUILD.bazel b/absl/numeric/BUILD.bazel index 324ce66..c906b8d 100644 --- a/absl/numeric/BUILD.bazel +++ b/absl/numeric/BUILD.bazel
@@ -13,7 +13,7 @@ # limitations under the License. load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", )
diff --git a/absl/numeric/CMakeLists.txt b/absl/numeric/CMakeLists.txt index 3360b2e..42468a6 100644 --- a/absl/numeric/CMakeLists.txt +++ b/absl/numeric/CMakeLists.txt
@@ -14,49 +14,45 @@ # limitations under the License. # -list(APPEND NUMERIC_PUBLIC_HEADERS - "int128.h" -) - - -# library 128 -list(APPEND INT128_SRC - "int128.cc" - ${NUMERIC_PUBLIC_HEADERS} -) -absl_library( - TARGET - absl_int128 - SOURCES - ${INT128_SRC} - PUBLIC_LIBRARIES - ${INT128_PUBLIC_LIBRARIES} - EXPORT_NAME +absl_cc_library( + NAME int128 + HDRS + "int128.h" + SRCS + "int128.cc" + "int128_have_intrinsic.inc" + "int128_no_intrinsic.inc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::config + absl::core_headers + PUBLIC ) - -absl_header_library( - TARGET - absl_numeric - PUBLIC_LIBRARIES - absl::int128 - EXPORT_NAME - numeric -) - -# test int128_test -set(INT128_TEST_SRC "int128_test.cc") -set(INT128_TEST_PUBLIC_LIBRARIES absl::numeric absl::base) - -absl_test( - TARGET +absl_cc_test( + NAME int128_test - SOURCES - ${INT128_TEST_SRC} - PUBLIC_LIBRARIES - ${INT128_TEST_PUBLIC_LIBRARIES} + SRCS + "int128_stream_test.cc" + "int128_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::int128 + absl::base + absl::core_headers + absl::hash_testing + absl::type_traits + gmock_main ) - - +# component target +absl_cc_library( + NAME + numeric + DEPS + absl::int128 + PUBLIC +)
diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc index cd79534..3c37f25 100644 --- a/absl/numeric/int128.cc +++ b/absl/numeric/int128.cc
@@ -17,7 +17,7 @@ #include <stddef.h> #include <cassert> #include <iomanip> -#include <iostream> // NOLINT(readability/streams) +#include <ostream> // NOLINT(readability/streams) #include <sstream> #include <string> #include <type_traits>
diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 79b62a7..f9c83ca 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h
@@ -37,6 +37,11 @@ #include "absl/base/macros.h" #include "absl/base/port.h" +#if defined(_MSC_VER) && defined(_WIN64) +#include <intrin.h> +#pragma intrinsic(_umul128) +#endif // defined(_MSC_VER) && defined(_WIN64) + namespace absl { @@ -227,8 +232,8 @@ // TODO(strel) add operator>>(std::istream&, uint128) constexpr uint128 Uint128Max() { - return uint128(std::numeric_limits<uint64_t>::max(), - std::numeric_limits<uint64_t>::max()); + return uint128((std::numeric_limits<uint64_t>::max)(), + (std::numeric_limits<uint64_t>::max)()); } } // namespace absl @@ -266,9 +271,9 @@ #endif // ABSL_HAVE_INTRINSIC_INT128 static constexpr bool tinyness_before = false; - static constexpr absl::uint128 min() { return 0; } + static constexpr absl::uint128 (min)() { return 0; } static constexpr absl::uint128 lowest() { return 0; } - static constexpr absl::uint128 max() { return absl::Uint128Max(); } + static constexpr absl::uint128 (max)() { return absl::Uint128Max(); } static constexpr absl::uint128 epsilon() { return 0; } static constexpr absl::uint128 round_error() { return 0; } static constexpr absl::uint128 infinity() { return 0; } @@ -384,13 +389,13 @@ constexpr uint128::uint128(int v) : lo_{static_cast<uint64_t>(v)}, - hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0} {} + hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {} constexpr uint128::uint128(long v) // NOLINT(runtime/int) : lo_{static_cast<uint64_t>(v)}, - hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0} {} + hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {} constexpr uint128::uint128(long long v) // NOLINT(runtime/int) : lo_{static_cast<uint64_t>(v)}, - hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0} {} + hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {} constexpr uint128::uint128(unsigned int v) : lo_{v}, hi_{0} {} // NOLINTNEXTLINE(runtime/int) @@ -413,13 +418,13 @@ : hi_{high}, lo_{low} {} constexpr uint128::uint128(int v) - : hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0}, + : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0}, lo_{static_cast<uint64_t>(v)} {} constexpr uint128::uint128(long v) // NOLINT(runtime/int) - : hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0}, + : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0}, lo_{static_cast<uint64_t>(v)} {} constexpr uint128::uint128(long long v) // NOLINT(runtime/int) - : hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0}, + : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0}, lo_{static_cast<uint64_t>(v)} {} constexpr uint128::uint128(unsigned int v) : hi_{0}, lo_{v} {} @@ -661,6 +666,12 @@ // can be used for uint128 storage. return static_cast<unsigned __int128>(lhs) * static_cast<unsigned __int128>(rhs); +#elif defined(_MSC_VER) && defined(_WIN64) + uint64_t carry; + uint64_t low = _umul128(Uint128Low64(lhs), Uint128Low64(rhs), &carry); + return MakeUint128(Uint128Low64(lhs) * Uint128High64(rhs) + + Uint128High64(lhs) * Uint128Low64(rhs) + carry, + low); #else // ABSL_HAVE_INTRINSIC128 uint64_t a32 = Uint128Low64(lhs) >> 32; uint64_t a00 = Uint128Low64(lhs) & 0xffffffff;
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index 6d7c261..7635a61 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel
@@ -15,7 +15,7 @@ # load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", "ABSL_EXCEPTIONS_FLAG", @@ -413,6 +413,7 @@ copts = ABSL_TEST_COPTS, visibility = ["//visibility:private"], deps = [ + ":pow10_helper", ":strings", "//absl/base", "//absl/base:core_headers", @@ -471,6 +472,8 @@ srcs = ["charconv_test.cc"], copts = ABSL_TEST_COPTS, deps = [ + ":pow10_helper", + ":str_format", ":strings", "//absl/base", "@com_google_googletest//:gtest_main", @@ -659,3 +662,23 @@ "@com_google_googletest//:gtest_main", ], ) + +cc_library( + name = "pow10_helper", + testonly = True, + srcs = ["internal/pow10_helper.cc"], + hdrs = ["internal/pow10_helper.h"], + visibility = ["//visibility:private"], +) + +cc_test( + name = "pow10_helper_test", + srcs = ["internal/pow10_helper_test.cc"], + copts = ABSL_TEST_COPTS, + visibility = ["//visibility:private"], + deps = [ + ":pow10_helper", + ":str_format", + "@com_google_googletest//:gtest_main", + ], +)
diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index f3e4162..5b877ad 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt
@@ -67,7 +67,7 @@ ${STRINGS_PUBLIC_HEADERS} ${STRINGS_INTERNAL_HEADERS} ) -set(STRINGS_PUBLIC_LIBRARIES absl::base absl_throw_delegate) +set(STRINGS_PUBLIC_LIBRARIES absl::base absl_internal_throw_delegate) absl_library( TARGET @@ -113,7 +113,7 @@ absl::strings absl::base absl::numeric - absl::container + absl::inlined_vector absl::span ) @@ -131,6 +131,15 @@ absl::strings ) +# pow10_helper +absl_library( + TARGET + pow10_helper + SOURCES + "internal/pow10_helper.cc" + "internal/pow10_helper.h" +) + # ## TESTS # @@ -207,7 +216,7 @@ # test string_view_test set(STRING_VIEW_TEST_SRC "string_view_test.cc") -set(STRING_VIEW_TEST_PUBLIC_LIBRARIES absl::strings absl_throw_delegate absl::base) +set(STRING_VIEW_TEST_PUBLIC_LIBRARIES absl::strings absl_internal_throw_delegate absl::base) absl_test( TARGET @@ -235,7 +244,7 @@ # test str_replace_test set(STR_REPLACE_TEST_SRC "str_replace_test.cc") -set(STR_REPLACE_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) +set(STR_REPLACE_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_internal_throw_delegate) absl_test( TARGET @@ -249,7 +258,7 @@ # test str_split_test set(STR_SPLIT_TEST_SRC "str_split_test.cc") -set(STR_SPLIT_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_throw_delegate) +set(STR_SPLIT_TEST_PUBLIC_LIBRARIES absl::strings absl::base absl_internal_throw_delegate) absl_test( TARGET @@ -316,7 +325,7 @@ # test numbers_test set(NUMBERS_TEST_SRC "numbers_test.cc") -set(NUMBERS_TEST_PUBLIC_LIBRARIES absl::strings) +set(NUMBERS_TEST_PUBLIC_LIBRARIES absl::strings pow10_helper) absl_test( TARGET @@ -358,7 +367,7 @@ # test charconv_test set(CHARCONV_TEST_SRC "charconv_test.cc") -set(CHARCONV_TEST_PUBLIC_LIBRARIES absl::strings) +set(CHARCONV_TEST_PUBLIC_LIBRARIES absl::strings absl::str_format pow10_helper) absl_test( TARGET @@ -460,4 +469,13 @@ absl::base ) - +# test pow10_helper_test +absl_test( + TARGET + pow10_helper_test + SOURCES + "internal/pow10_helper_test.cc" + PUBLIC_LIBRARIES + pow10_helper + absl::str_format +)
diff --git a/absl/strings/charconv_test.cc b/absl/strings/charconv_test.cc index 89418fe..d07537e 100644 --- a/absl/strings/charconv_test.cc +++ b/absl/strings/charconv_test.cc
@@ -19,7 +19,9 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/strings/internal/pow10_helper.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" #ifdef _MSC_FULL_VER #define ABSL_COMPILER_DOES_EXACT_ROUNDING 0 @@ -31,6 +33,8 @@ namespace { +using absl::strings_internal::Pow10; + #if ABSL_COMPILER_DOES_EXACT_ROUNDING // Tests that the given string is accepted by absl::from_chars, and that it @@ -678,7 +682,8 @@ auto result = absl::from_chars(input.data(), input.data() + input.size(), actual); EXPECT_EQ(result.ec, std::errc()); - EXPECT_EQ(expected, actual); + EXPECT_EQ(expected, actual) + << absl::StrFormat("%a vs %a", expected, actual); } // test legal values near upper_bound for (index = upper_bound, step = 1; index > lower_bound; @@ -690,7 +695,8 @@ auto result = absl::from_chars(input.data(), input.data() + input.size(), actual); EXPECT_EQ(result.ec, std::errc()); - EXPECT_EQ(expected, actual); + EXPECT_EQ(expected, actual) + << absl::StrFormat("%a vs %a", expected, actual); } // Test underflow values below lower_bound for (index = lower_bound - 1, step = 1; index > -1000000; @@ -747,7 +753,7 @@ // acceptable exponents in this test. TEST(FromChars, DecimalDoubleLimits) { auto input_gen = [](int index) { return absl::StrCat("1.0e", index); }; - auto expected_gen = [](int index) { return std::pow(10.0, index); }; + auto expected_gen = [](int index) { return Pow10(index); }; TestOverflowAndUnderflow<double>(input_gen, expected_gen, -323, 308); } @@ -759,7 +765,7 @@ // acceptable exponents in this test. TEST(FromChars, DecimalFloatLimits) { auto input_gen = [](int index) { return absl::StrCat("1.0e", index); }; - auto expected_gen = [](int index) { return std::pow(10.0, index); }; + auto expected_gen = [](int index) { return Pow10(index); }; TestOverflowAndUnderflow<float>(input_gen, expected_gen, -45, 38); }
diff --git a/absl/strings/internal/charconv_bigint.h b/absl/strings/internal/charconv_bigint.h index aa70af2..9d1a1bf 100644 --- a/absl/strings/internal/charconv_bigint.h +++ b/absl/strings/internal/charconv_bigint.h
@@ -57,17 +57,10 @@ "unsupported max_words value"); BigUnsigned() : size_(0), words_{} {} - explicit BigUnsigned(uint32_t v) : size_(v > 0 ? 1 : 0), words_{v} {} - explicit BigUnsigned(uint64_t v) - : size_(0), - words_{static_cast<uint32_t>(v & 0xffffffff), - static_cast<uint32_t>(v >> 32)} { - if (words_[1]) { - size_ = 2; - } else if (words_[0]) { - size_ = 1; - } - } + explicit constexpr BigUnsigned(uint64_t v) + : size_((v >> 32) ? 2 : v ? 1 : 0), + words_{static_cast<uint32_t>(v & 0xffffffffu), + static_cast<uint32_t>(v >> 32)} {} // Constructs a BigUnsigned from the given string_view containing a decimal // value. If the input std::string is not a decimal integer, constructs a 0 @@ -110,12 +103,12 @@ SetToZero(); return; } - size_ = std::min(size_ + word_shift, max_words); + size_ = (std::min)(size_ + word_shift, max_words); count %= 32; if (count == 0) { std::copy_backward(words_, words_ + size_ - word_shift, words_ + size_); } else { - for (int i = std::min(size_, max_words - 1); i > word_shift; --i) { + for (int i = (std::min)(size_, max_words - 1); i > word_shift; --i) { words_[i] = (words_[i - word_shift] << count) | (words_[i - word_shift - 1] >> (32 - count)); } @@ -274,7 +267,7 @@ void MultiplyBy(int other_size, const uint32_t* other_words) { const int original_size = size_; const int first_step = - std::min(original_size + other_size - 2, max_words - 1); + (std::min)(original_size + other_size - 2, max_words - 1); for (int step = first_step; step >= 0; --step) { MultiplyStep(original_size, other_words, other_size, step); } @@ -293,7 +286,7 @@ value = 0; } } - size_ = std::min(max_words, std::max(index + 1, size_)); + size_ = (std::min)(max_words, (std::max)(index + 1, size_)); } } @@ -316,7 +309,7 @@ } else { // Normally 32-bit AddWithCarry() sets size_, but since we don't call // it when `high` is 0, do it ourselves here. - size_ = std::min(max_words, std::max(index + 1, size_)); + size_ = (std::min)(max_words, (std::max)(index + 1, size_)); } } } @@ -355,7 +348,7 @@ // Returns -1 if lhs < rhs, 0 if lhs == rhs, and 1 if lhs > rhs. template <int N, int M> int Compare(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { - int limit = std::max(lhs.size(), rhs.size()); + int limit = (std::max)(lhs.size(), rhs.size()); for (int i = limit - 1; i >= 0; --i) { const uint32_t lhs_word = lhs.GetWord(i); const uint32_t rhs_word = rhs.GetWord(i); @@ -370,7 +363,7 @@ template <int N, int M> bool operator==(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { - int limit = std::max(lhs.size(), rhs.size()); + int limit = (std::max)(lhs.size(), rhs.size()); for (int i = 0; i < limit; ++i) { if (lhs.GetWord(i) != rhs.GetWord(i)) { return false;
diff --git a/absl/strings/internal/numbers_test_common.h b/absl/strings/internal/numbers_test_common.h index 20e3af5..f6241ff 100644 --- a/absl/strings/internal/numbers_test_common.h +++ b/absl/strings/internal/numbers_test_common.h
@@ -64,11 +64,11 @@ 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()}, + {"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()}, + {" \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}, @@ -77,7 +77,7 @@ // Base-10 version. {"34234324", true, 0, 34234324}, - {"4294967295", true, 0, std::numeric_limits<uint32_t>::max()}, + {"4294967295", true, 0, (std::numeric_limits<uint32_t>::max)()}, {"34234324 \n\t", true, 10, 34234324}, // Unusual base @@ -96,8 +96,8 @@ {" \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()}, + {"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; @@ -119,7 +119,7 @@ {"000", true, 0, 0}, {"0", true, 0, 0}, {" \t\n 0xffffffffffffffff", true, 16, - std::numeric_limits<uint64_t>::max()}, + (std::numeric_limits<uint64_t>::max)()}, {"012345670123456701234", true, 8, int64_t{012345670123456701234}}, {"12345670123456701234", true, 8, int64_t{012345670123456701234}}, @@ -130,7 +130,7 @@ {"34234324487834466", true, 0, int64_t{34234324487834466}}, {" \t\n 18446744073709551615", true, 0, - std::numeric_limits<uint64_t>::max()}, + (std::numeric_limits<uint64_t>::max)()}, {"34234324487834466 \n\t ", true, 0, int64_t{34234324487834466}}, @@ -156,12 +156,13 @@ // 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)()}, {"0X10000000000000000", false, 16, - std::numeric_limits<uint64_t>::max()}, // 0X versus 0x. - {"0x10000000000000000", false, 0, std::numeric_limits<uint64_t>::max()}, + (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. + (std::numeric_limits<uint64_t>::max)()}, // 0X versus 0x. {"0x1234", true, 16, 0x1234},
diff --git a/absl/strings/internal/pow10_helper.cc b/absl/strings/internal/pow10_helper.cc new file mode 100644 index 0000000..66be163 --- /dev/null +++ b/absl/strings/internal/pow10_helper.cc
@@ -0,0 +1,120 @@ +// 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/pow10_helper.h" + +#include <cmath> + +namespace absl { +namespace strings_internal { + +namespace { + +// The exact value of 1e23 falls precisely halfway between two representable +// doubles. Furthermore, the rounding rules we prefer (break ties by rounding +// to the nearest even) dictate in this case that the number should be rounded +// down, but this is not completely specified for floating-point literals in +// C++. (It just says to use the default rounding mode of the standard +// library.) We ensure the result we want by using a number that has an +// unambiguous correctly rounded answer. +constexpr double k1e23 = 9999999999999999e7; + +constexpr double kPowersOfTen[] = { + 0.0, 1e-323, 1e-322, 1e-321, 1e-320, 1e-319, 1e-318, 1e-317, 1e-316, + 1e-315, 1e-314, 1e-313, 1e-312, 1e-311, 1e-310, 1e-309, 1e-308, 1e-307, + 1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301, 1e-300, 1e-299, 1e-298, + 1e-297, 1e-296, 1e-295, 1e-294, 1e-293, 1e-292, 1e-291, 1e-290, 1e-289, + 1e-288, 1e-287, 1e-286, 1e-285, 1e-284, 1e-283, 1e-282, 1e-281, 1e-280, + 1e-279, 1e-278, 1e-277, 1e-276, 1e-275, 1e-274, 1e-273, 1e-272, 1e-271, + 1e-270, 1e-269, 1e-268, 1e-267, 1e-266, 1e-265, 1e-264, 1e-263, 1e-262, + 1e-261, 1e-260, 1e-259, 1e-258, 1e-257, 1e-256, 1e-255, 1e-254, 1e-253, + 1e-252, 1e-251, 1e-250, 1e-249, 1e-248, 1e-247, 1e-246, 1e-245, 1e-244, + 1e-243, 1e-242, 1e-241, 1e-240, 1e-239, 1e-238, 1e-237, 1e-236, 1e-235, + 1e-234, 1e-233, 1e-232, 1e-231, 1e-230, 1e-229, 1e-228, 1e-227, 1e-226, + 1e-225, 1e-224, 1e-223, 1e-222, 1e-221, 1e-220, 1e-219, 1e-218, 1e-217, + 1e-216, 1e-215, 1e-214, 1e-213, 1e-212, 1e-211, 1e-210, 1e-209, 1e-208, + 1e-207, 1e-206, 1e-205, 1e-204, 1e-203, 1e-202, 1e-201, 1e-200, 1e-199, + 1e-198, 1e-197, 1e-196, 1e-195, 1e-194, 1e-193, 1e-192, 1e-191, 1e-190, + 1e-189, 1e-188, 1e-187, 1e-186, 1e-185, 1e-184, 1e-183, 1e-182, 1e-181, + 1e-180, 1e-179, 1e-178, 1e-177, 1e-176, 1e-175, 1e-174, 1e-173, 1e-172, + 1e-171, 1e-170, 1e-169, 1e-168, 1e-167, 1e-166, 1e-165, 1e-164, 1e-163, + 1e-162, 1e-161, 1e-160, 1e-159, 1e-158, 1e-157, 1e-156, 1e-155, 1e-154, + 1e-153, 1e-152, 1e-151, 1e-150, 1e-149, 1e-148, 1e-147, 1e-146, 1e-145, + 1e-144, 1e-143, 1e-142, 1e-141, 1e-140, 1e-139, 1e-138, 1e-137, 1e-136, + 1e-135, 1e-134, 1e-133, 1e-132, 1e-131, 1e-130, 1e-129, 1e-128, 1e-127, + 1e-126, 1e-125, 1e-124, 1e-123, 1e-122, 1e-121, 1e-120, 1e-119, 1e-118, + 1e-117, 1e-116, 1e-115, 1e-114, 1e-113, 1e-112, 1e-111, 1e-110, 1e-109, + 1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103, 1e-102, 1e-101, 1e-100, + 1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, + 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82, + 1e-81, 1e-80, 1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, + 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64, + 1e-63, 1e-62, 1e-61, 1e-60, 1e-59, 1e-58, 1e-57, 1e-56, 1e-55, + 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, + 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, 1e-39, 1e-38, 1e-37, + 1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, + 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19, + 1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, + 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, + 1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, + 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, + 1e+18, 1e+19, 1e+20, 1e+21, 1e+22, k1e23, 1e+24, 1e+25, 1e+26, + 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, + 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 1e+41, 1e+42, 1e+43, 1e+44, + 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, + 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, 1e+61, 1e+62, + 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, + 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, + 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, + 1e+99, 1e+100, 1e+101, 1e+102, 1e+103, 1e+104, 1e+105, 1e+106, 1e+107, + 1e+108, 1e+109, 1e+110, 1e+111, 1e+112, 1e+113, 1e+114, 1e+115, 1e+116, + 1e+117, 1e+118, 1e+119, 1e+120, 1e+121, 1e+122, 1e+123, 1e+124, 1e+125, + 1e+126, 1e+127, 1e+128, 1e+129, 1e+130, 1e+131, 1e+132, 1e+133, 1e+134, + 1e+135, 1e+136, 1e+137, 1e+138, 1e+139, 1e+140, 1e+141, 1e+142, 1e+143, + 1e+144, 1e+145, 1e+146, 1e+147, 1e+148, 1e+149, 1e+150, 1e+151, 1e+152, + 1e+153, 1e+154, 1e+155, 1e+156, 1e+157, 1e+158, 1e+159, 1e+160, 1e+161, + 1e+162, 1e+163, 1e+164, 1e+165, 1e+166, 1e+167, 1e+168, 1e+169, 1e+170, + 1e+171, 1e+172, 1e+173, 1e+174, 1e+175, 1e+176, 1e+177, 1e+178, 1e+179, + 1e+180, 1e+181, 1e+182, 1e+183, 1e+184, 1e+185, 1e+186, 1e+187, 1e+188, + 1e+189, 1e+190, 1e+191, 1e+192, 1e+193, 1e+194, 1e+195, 1e+196, 1e+197, + 1e+198, 1e+199, 1e+200, 1e+201, 1e+202, 1e+203, 1e+204, 1e+205, 1e+206, + 1e+207, 1e+208, 1e+209, 1e+210, 1e+211, 1e+212, 1e+213, 1e+214, 1e+215, + 1e+216, 1e+217, 1e+218, 1e+219, 1e+220, 1e+221, 1e+222, 1e+223, 1e+224, + 1e+225, 1e+226, 1e+227, 1e+228, 1e+229, 1e+230, 1e+231, 1e+232, 1e+233, + 1e+234, 1e+235, 1e+236, 1e+237, 1e+238, 1e+239, 1e+240, 1e+241, 1e+242, + 1e+243, 1e+244, 1e+245, 1e+246, 1e+247, 1e+248, 1e+249, 1e+250, 1e+251, + 1e+252, 1e+253, 1e+254, 1e+255, 1e+256, 1e+257, 1e+258, 1e+259, 1e+260, + 1e+261, 1e+262, 1e+263, 1e+264, 1e+265, 1e+266, 1e+267, 1e+268, 1e+269, + 1e+270, 1e+271, 1e+272, 1e+273, 1e+274, 1e+275, 1e+276, 1e+277, 1e+278, + 1e+279, 1e+280, 1e+281, 1e+282, 1e+283, 1e+284, 1e+285, 1e+286, 1e+287, + 1e+288, 1e+289, 1e+290, 1e+291, 1e+292, 1e+293, 1e+294, 1e+295, 1e+296, + 1e+297, 1e+298, 1e+299, 1e+300, 1e+301, 1e+302, 1e+303, 1e+304, 1e+305, + 1e+306, 1e+307, 1e+308, +}; + +} // namespace + +double Pow10(int exp) { + if (exp < -324) { + return 0.0; + } else if (exp > 308) { + return INFINITY; + } else { + return kPowersOfTen[exp + 324]; + } +} + +} // namespace strings_internal +} // namespace absl
diff --git a/absl/strings/internal/pow10_helper.h b/absl/strings/internal/pow10_helper.h new file mode 100644 index 0000000..39c1539 --- /dev/null +++ b/absl/strings/internal/pow10_helper.h
@@ -0,0 +1,36 @@ +// +// 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. +// +// This test helper library contains a table of powers of 10, to guarantee +// precise values are computed across the full range of doubles. We can't rely +// on the pow() function, because not all standard libraries ship a version +// that is precise. +#ifndef ABSL_STRINGS_POW10_HELPER_H_ +#define ABSL_STRINGS_POW10_HELPER_H_ + +#include <vector> + +namespace absl { +namespace strings_internal { + +// Computes the precise value of 10^exp. (I.e. the nearest representable +// double to the exact value, rounding to nearest-even in the (single) case of +// being exactly halfway between.) +double Pow10(int exp); + +} // namespace strings_internal +} // namespace absl + +#endif // ABSL_STRINGS_POW10_HELPER_H_
diff --git a/absl/strings/internal/pow10_helper_test.cc b/absl/strings/internal/pow10_helper_test.cc new file mode 100644 index 0000000..9a13d52 --- /dev/null +++ b/absl/strings/internal/pow10_helper_test.cc
@@ -0,0 +1,120 @@ +// 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/pow10_helper.h" + +#include <cmath> + +#include "gtest/gtest.h" +#include "absl/strings/str_format.h" + +namespace absl { +namespace strings_internal { + +namespace { + +struct TestCase { + int power; // Testing Pow10(power) + uint64_t significand; // Raw bits of the expected value + int radix; // significand is adjusted by 2^radix +}; + +TEST(Pow10HelperTest, Works) { + // The logic in pow10_helper.cc is so simple that theoretically we don't even + // need a test. However, we're paranoid and believe that there may be + // compilers that don't round floating-point literals correctly, even though + // it is specified by the standard. We check various edge cases, just to be + // sure. + constexpr TestCase kTestCases[] = { + // Subnormals + {-323, 0x2, -1074}, + {-322, 0x14, -1074}, + {-321, 0xca, -1074}, + {-320, 0x7e8, -1074}, + {-319, 0x4f10, -1074}, + {-318, 0x316a2, -1074}, + {-317, 0x1ee257, -1074}, + {-316, 0x134d761, -1074}, + {-315, 0xc1069cd, -1074}, + {-314, 0x78a42205, -1074}, + {-313, 0x4b6695433, -1074}, + {-312, 0x2f201d49fb, -1074}, + {-311, 0x1d74124e3d1, -1074}, + {-310, 0x12688b70e62b, -1074}, + {-309, 0xb8157268fdaf, -1074}, + {-308, 0x730d67819e8d2, -1074}, + // Values that are very close to rounding the other way. + // Comment shows difference of significand from the true value. + {-307, 0x11fa182c40c60d, -1072}, // -.4588 + {-290, 0x18f2b061aea072, -1016}, // .4854 + {-276, 0x11BA03F5B21000, -969}, // .4709 + {-259, 0x1899C2F6732210, -913}, // .4830 + {-252, 0x1D53844EE47DD1, -890}, // -.4743 + {-227, 0x1E5297287C2F45, -807}, // -.4708 + {-198, 0x1322E220A5B17E, -710}, // -.4714 + {-195, 0x12B010D3E1CF56, -700}, // .4928 + {-192, 0x123FF06EEA847A, -690}, // .4968 + {-163, 0x1708D0F84D3DE7, -594}, // -.4977 + {-145, 0x13FAAC3E3FA1F3, -534}, // -.4785 + {-111, 0x133D4032C2C7F5, -421}, // .4774 + {-106, 0x1D5B561574765B, -405}, // -.4869 + {-104, 0x16EF5B40C2FC77, -398}, // -.4741 + {-88, 0x197683DF2F268D, -345}, // -.4738 + {-86, 0x13E497065CD61F, -338}, // .4736 + {-76, 0x17288E1271F513, -305}, // -.4761 + {-63, 0x1A53FC9631D10D, -262}, // .4929 + {-30, 0x14484BFEEBC2A0, -152}, // .4758 + {-21, 0x12E3B40A0E9B4F, -122}, // -.4916 + {-5, 0x14F8B588E368F1, -69}, // .4829 + {23, 0x152D02C7E14AF6, 24}, // -.5000 (exactly, round-to-even) + {29, 0x1431E0FAE6D721, 44}, // -.4870 + {34, 0x1ED09BEAD87C03, 60}, // -.4721 + {70, 0x172EBAD6DDC73D, 180}, // .4733 + {105, 0x1BE7ABD3781ECA, 296}, // -.4850 + {126, 0x17A2ECC414A03F, 366}, // -.4999 + {130, 0x1CDA62055B2D9E, 379}, // .4855 + {165, 0x115D847AD00087, 496}, // -.4913 + {172, 0x14B378469B6732, 519}, // .4818 + {187, 0x1262DFEEBBB0F9, 569}, // -.4805 + {210, 0x18557F31326BBB, 645}, // -.4992 + {212, 0x1302CB5E6F642A, 652}, // -.4838 + {215, 0x1290BA9A38C7D1, 662}, // -.4881 + {236, 0x1F736F9B3494E9, 731}, // .4707 + {244, 0x176EC98994F489, 758}, // .4924 + {250, 0x1658E3AB795204, 778}, // -.4963 + {252, 0x117571DDF6C814, 785}, // .4873 + {254, 0x1B4781EAD1989E, 791}, // -.4887 + {260, 0x1A03FDE214CAF1, 811}, // .4784 + {284, 0x1585041B2C477F, 891}, // .4798 + {304, 0x1D2A1BE4048F90, 957}, // -.4987 + // Out-of-range values + {-324, 0x0, 0}, + {-325, 0x0, 0}, + {-326, 0x0, 0}, + {309, 1, 2000}, + {310, 1, 2000}, + {311, 1, 2000}, + }; + for (const TestCase& test_case : kTestCases) { + EXPECT_EQ(Pow10(test_case.power), + std::ldexp(test_case.significand, test_case.radix)) + << absl::StrFormat("Failure for Pow10(%d): %a vs %a", test_case.power, + Pow10(test_case.power), + std::ldexp(test_case.significand, test_case.radix)); + } +} + +} // namespace +} // namespace strings_internal +} // namespace absl
diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h index 3376d48..ebd40ad 100644 --- a/absl/strings/internal/str_format/arg.h +++ b/absl/strings/internal/str_format/arg.h
@@ -80,7 +80,7 @@ int precision = conv.precision(); if (precision >= 0) - to_write = std::min(to_write, static_cast<size_t>(precision)); + to_write = (std::min)(to_write, static_cast<size_t>(precision)); space_remaining = Excess(to_write, space_remaining); @@ -335,12 +335,12 @@ using CommonType = typename std::conditional<std::is_signed<T>::value, int64_t, uint64_t>::type; if (static_cast<CommonType>(val) > - static_cast<CommonType>(std::numeric_limits<int>::max())) { - return std::numeric_limits<int>::max(); + static_cast<CommonType>((std::numeric_limits<int>::max)())) { + return (std::numeric_limits<int>::max)(); } else if (std::is_signed<T>::value && static_cast<CommonType>(val) < - static_cast<CommonType>(std::numeric_limits<int>::min())) { - return std::numeric_limits<int>::min(); + static_cast<CommonType>((std::numeric_limits<int>::min)())) { + return (std::numeric_limits<int>::min)(); } return static_cast<int>(val); }
diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index 11b996a..7ce80d4 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h
@@ -409,4 +409,4 @@ } // namespace absl -#endif // ABSL_STRINGS_STR_FORMAT_EXTENSION_H_ +#endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
diff --git a/absl/strings/internal/str_format/output.cc b/absl/strings/internal/str_format/output.cc index 5c3795b..d7fef69 100644 --- a/absl/strings/internal/str_format/output.cc +++ b/absl/strings/internal/str_format/output.cc
@@ -20,6 +20,16 @@ namespace absl { namespace str_format_internal { +namespace { +struct ClearErrnoGuard { + ClearErrnoGuard() : old_value(errno) { errno = 0; } + ~ClearErrnoGuard() { + if (!errno) errno = old_value; + } + int old_value; +}; +} // namespace + void BufferRawSink::Write(string_view v) { size_t to_write = std::min(v.size(), size_); std::memcpy(buffer_, v.data(), to_write); @@ -30,14 +40,27 @@ void FILERawSink::Write(string_view v) { while (!v.empty() && !error_) { + // Reset errno to zero in case the libc implementation doesn't set errno + // when a failure occurs. + ClearErrnoGuard guard; + if (size_t result = std::fwrite(v.data(), 1, v.size(), output_)) { // Some progress was made. count_ += result; v.remove_prefix(result); } else { - // Some error occurred. - if (errno != EINTR) { + if (errno == EINTR) { + continue; + } else if (errno) { error_ = errno; + } else if (std::ferror(output_)) { + // Non-POSIX compliant libc implementations may not set errno, so we + // have check the streams error indicator. + error_ = EBADF; + } else { + // We're likely on a non-POSIX system that encountered EINTR but had no + // way of reporting it. + continue; } } }
diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index 36fc0d6..099326c 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc
@@ -39,6 +39,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/internal/numbers_test_common.h" +#include "absl/strings/internal/pow10_helper.h" namespace { @@ -871,7 +872,7 @@ } for (int exponent = -324; exponent <= 308; ++exponent) { - double powten = pow(10.0, exponent); + double powten = absl::strings_internal::Pow10(exponent); if (powten == 0) powten = 5e-324; if (kFloatNumCases >= 1e9) { // The exhaustive test takes a very long time, so log progress.
diff --git a/absl/strings/str_cat.cc b/absl/strings/str_cat.cc index efa4fd7..b14d571 100644 --- a/absl/strings/str_cat.cc +++ b/absl/strings/str_cat.cc
@@ -80,7 +80,7 @@ // StrCat() // This merges the given strings or integers, with no delimiter. This // is designed to be the fastest possible way to construct a string out -// of a mix of raw C strings, StringPieces, strings, and integer values. +// of a mix of raw C strings, string_views, strings, and integer values. // ---------------------------------------------------------------------- // Append is merely a version of memcpy that returns the address of the byte
diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h index da9ed9a..8ba0592 100644 --- a/absl/strings/str_cat.h +++ b/absl/strings/str_cat.h
@@ -97,6 +97,10 @@ kZeroPad14, kZeroPad15, kZeroPad16, + kZeroPad17, + kZeroPad18, + kZeroPad19, + kZeroPad20, kSpacePad2 = kZeroPad2 + 64, kSpacePad3, @@ -113,6 +117,10 @@ kSpacePad14, kSpacePad15, kSpacePad16, + kSpacePad17, + kSpacePad18, + kSpacePad19, + kSpacePad20, }; // -----------------------------------------------------------------------------
diff --git a/absl/strings/str_cat_test.cc b/absl/strings/str_cat_test.cc index 555d8db..0714107 100644 --- a/absl/strings/str_cat_test.cc +++ b/absl/strings/str_cat_test.cc
@@ -427,7 +427,7 @@ snprintf(expected, sizeof(expected), nopad_format, v); EXPECT_EQ(expected, actual) << " decimal value " << v; - for (int spec = absl::kZeroPad2; spec <= absl::kZeroPad16; ++spec) { + for (int spec = absl::kZeroPad2; spec <= absl::kZeroPad20; ++spec) { std::string actual = absl::StrCat(absl::Hex(v, static_cast<absl::PadSpec>(spec))); snprintf(expected, sizeof(expected), zeropad_format, @@ -435,7 +435,7 @@ EXPECT_EQ(expected, actual) << " decimal value " << v; } - for (int spec = absl::kSpacePad2; spec <= absl::kSpacePad16; ++spec) { + for (int spec = absl::kSpacePad2; spec <= absl::kSpacePad20; ++spec) { std::string actual = absl::StrCat(absl::Hex(v, static_cast<absl::PadSpec>(spec))); snprintf(expected, sizeof(expected), spacepad_format, @@ -453,7 +453,7 @@ snprintf(expected, sizeof(expected), nopad_format, v); EXPECT_EQ(expected, actual) << " decimal value " << v; - for (int spec = absl::kZeroPad2; spec <= absl::kZeroPad16; ++spec) { + for (int spec = absl::kZeroPad2; spec <= absl::kZeroPad20; ++spec) { std::string actual = absl::StrCat(absl::Dec(v, static_cast<absl::PadSpec>(spec))); snprintf(expected, sizeof(expected), zeropad_format, @@ -463,7 +463,7 @@ << "' digits " << (spec - absl::kZeroPad2 + 2); } - for (int spec = absl::kSpacePad2; spec <= absl::kSpacePad16; ++spec) { + for (int spec = absl::kSpacePad2; spec <= absl::kSpacePad20; ++spec) { std::string actual = absl::StrCat(absl::Dec(v, static_cast<absl::PadSpec>(spec))); snprintf(expected, sizeof(expected), spacepad_format,
diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc index aa14e21..87ed234 100644 --- a/absl/strings/str_format_test.cc +++ b/absl/strings/str_format_test.cc
@@ -242,6 +242,7 @@ std::string ReadFile() { std::fseek(file_, 0, SEEK_END); int size = std::ftell(file_); + EXPECT_GT(size, 0); std::rewind(file_); std::string str(2 * size, ' '); int read_bytes = std::fread(&str[0], 1, str.size(), file_); @@ -270,7 +271,7 @@ EXPECT_EQ(errno, EBADF); } -#if __GNUC__ +#if __GLIBC__ TEST_F(FormatEntryPointTest, FprintfTooLarge) { std::FILE* f = std::fopen("/dev/null", "w"); int width = 2000000000; @@ -297,7 +298,7 @@ EXPECT_EQ(result, 30); EXPECT_EQ(tmp.ReadFile(), "STRING: ABC NUMBER: -000000019"); } -#endif // __GNUC__ +#endif // __GLIBC__ TEST_F(FormatEntryPointTest, SNPrintF) { char buffer[16]; @@ -605,35 +606,21 @@ // Some codegen thunks that we can use to easily dump the generated assembly for // different StrFormat calls. -inline std::string CodegenAbslStrFormatInt(int i) { +std::string CodegenAbslStrFormatInt(int i) { // NOLINT return absl::StrFormat("%d", i); } -inline std::string CodegenAbslStrFormatIntStringInt64(int i, const std::string& s, - int64_t i64) { +std::string CodegenAbslStrFormatIntStringInt64(int i, const std::string& s, + int64_t i64) { // NOLINT return absl::StrFormat("%d %s %d", i, s, i64); } -inline void CodegenAbslStrAppendFormatInt(std::string* out, int i) { +void CodegenAbslStrAppendFormatInt(std::string* out, int i) { // NOLINT absl::StrAppendFormat(out, "%d", i); } -inline void CodegenAbslStrAppendFormatIntStringInt64(std::string* out, int i, +void CodegenAbslStrAppendFormatIntStringInt64(std::string* out, int i, const std::string& s, - int64_t i64) { + int64_t i64) { // NOLINT absl::StrAppendFormat(out, "%d %s %d", i, s, i64); } - -auto absl_internal_str_format_force_codegen_funcs = std::make_tuple( - CodegenAbslStrFormatInt, CodegenAbslStrFormatIntStringInt64, - CodegenAbslStrAppendFormatInt, CodegenAbslStrAppendFormatIntStringInt64); - -bool absl_internal_str_format_force_codegen_always_false; -// Force the compiler to generate the functions by making it look like we -// escape the function pointers. -// It can't statically know that -// absl_internal_str_format_force_codegen_always_false is not changed by someone -// else. -bool absl_internal_str_format_force_codegen = - absl_internal_str_format_force_codegen_always_false && - printf("%p", &absl_internal_str_format_force_codegen_funcs) == 0;
diff --git a/absl/strings/str_split_benchmark.cc b/absl/strings/str_split_benchmark.cc index 326ff74..0ac297c 100644 --- a/absl/strings/str_split_benchmark.cc +++ b/absl/strings/str_split_benchmark.cc
@@ -35,16 +35,16 @@ return test; } -void BM_Split2StringPiece(benchmark::State& state) { +void BM_Split2StringView(benchmark::State& state) { std::string test = MakeTestString(state.range(0)); for (auto _ : state) { std::vector<absl::string_view> result = absl::StrSplit(test, ';'); benchmark::DoNotOptimize(result); } } -BENCHMARK_RANGE(BM_Split2StringPiece, 0, 1 << 20); +BENCHMARK_RANGE(BM_Split2StringView, 0, 1 << 20); -void BM_Split2StringPieceLifted(benchmark::State& state) { +void BM_Split2StringViewLifted(benchmark::State& state) { std::string test = MakeTestString(state.range(0)); std::vector<absl::string_view> result; for (auto _ : state) { @@ -52,7 +52,7 @@ } benchmark::DoNotOptimize(result); } -BENCHMARK_RANGE(BM_Split2StringPieceLifted, 0, 1 << 20); +BENCHMARK_RANGE(BM_Split2StringViewLifted, 0, 1 << 20); void BM_Split2String(benchmark::State& state) { std::string test = MakeTestString(state.range(0));
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 6bcd3c4..8cd4fa2 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h
@@ -355,7 +355,7 @@ string_view substr(size_type pos, size_type n = npos) const { if (ABSL_PREDICT_FALSE(pos > length_)) base_internal::ThrowStdOutOfRange("absl::string_view::substr"); - n = std::min(n, length_ - pos); + n = (std::min)(n, length_ - pos); return string_view(ptr_ + pos, n); } @@ -368,7 +368,7 @@ // on the respective sizes of the two `string_view`s to determine which is // smaller, equal, or greater. int compare(string_view x) const noexcept { - auto min_length = std::min(length_, x.length_); + auto min_length = (std::min)(length_, x.length_); if (min_length > 0) { int r = memcmp(ptr_, x.ptr_, min_length); if (r < 0) return -1; @@ -490,7 +490,7 @@ private: static constexpr size_type kMaxSize = - std::numeric_limits<difference_type>::max(); + (std::numeric_limits<difference_type>::max)(); static constexpr size_type CheckLengthInternal(size_type len) { return ABSL_ASSERT(len <= kMaxSize), len; @@ -517,7 +517,7 @@ } inline bool operator<(string_view x, string_view y) noexcept { - auto min_size = std::min(x.size(), y.size()); + auto min_size = (std::min)(x.size(), y.size()); const int r = min_size == 0 ? 0 : memcmp(x.data(), y.data(), min_size); return (r < 0) || (r == 0 && x.size() < y.size()); } @@ -547,7 +547,7 @@ // Provided because std::string_view::substr throws if `pos > size()` inline string_view ClippedSubstr(string_view s, size_t pos, size_t n = string_view::npos) { - pos = std::min(pos, static_cast<size_t>(s.size())); + pos = (std::min)(pos, static_cast<size_t>(s.size())); return s.substr(pos, n); }
diff --git a/absl/strings/string_view_benchmark.cc b/absl/strings/string_view_benchmark.cc index fb46db1..f442032 100644 --- a/absl/strings/string_view_benchmark.cc +++ b/absl/strings/string_view_benchmark.cc
@@ -151,7 +151,7 @@ std::string haystack(state.range(0), '0'); absl::string_view s(haystack); for (auto _ : state) { - s.find("x"); // not present; length 1 + benchmark::DoNotOptimize(s.find("x")); // not present; length 1 } } BENCHMARK(BM_find_string_view_len_one)->Range(1, 1 << 20); @@ -160,7 +160,7 @@ std::string haystack(state.range(0), '0'); absl::string_view s(haystack); for (auto _ : state) { - s.find("xx"); // not present; length 2 + benchmark::DoNotOptimize(s.find("xx")); // not present; length 2 } } BENCHMARK(BM_find_string_view_len_two)->Range(1, 1 << 20); @@ -169,7 +169,7 @@ std::string haystack(state.range(0), '0'); absl::string_view s(haystack); for (auto _ : state) { - s.find('x'); // not present + benchmark::DoNotOptimize(s.find('x')); // not present } } BENCHMARK(BM_find_one_char)->Range(1, 1 << 20); @@ -178,7 +178,7 @@ std::string haystack(state.range(0), '0'); absl::string_view s(haystack); for (auto _ : state) { - s.rfind('x'); // not present + benchmark::DoNotOptimize(s.rfind('x')); // not present } } BENCHMARK(BM_rfind_one_char)->Range(1, 1 << 20); @@ -193,7 +193,7 @@ absl::string_view s(haystack); for (auto _ : state) { - s.find_first_of(needle); + benchmark::DoNotOptimize(s.find_first_of(needle)); } }
diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc index 217fda0..ed34ed8 100644 --- a/absl/strings/string_view_test.cc +++ b/absl/strings/string_view_test.cc
@@ -678,9 +678,9 @@ EXPECT_EQ(a.substr(23, absl::string_view::npos), c); // throw exception #ifdef ABSL_HAVE_EXCEPTIONS - EXPECT_THROW(a.substr(99, 2), std::out_of_range); + EXPECT_THROW((void)a.substr(99, 2), std::out_of_range); #else - EXPECT_DEATH(a.substr(99, 2), "absl::string_view::substr"); + EXPECT_DEATH((void)a.substr(99, 2), "absl::string_view::substr"); #endif }
diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index f52e9d4..53e7988 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel
@@ -15,7 +15,7 @@ # load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", ) @@ -170,18 +170,31 @@ ], ) -cc_test( - name = "mutex_benchmark", +cc_library( + name = "mutex_benchmark_common", + testonly = 1, srcs = ["mutex_benchmark.cc"], - copts = ABSL_TEST_COPTS, - tags = ["benchmark"], - visibility = ["//visibility:private"], + copts = ABSL_DEFAULT_COPTS, + visibility = [ + "//absl/synchronization:__pkg__", + ], deps = [ ":synchronization", ":thread_pool", "//absl/base", "@com_github_google_benchmark//:benchmark_main", ], + alwayslink = 1, +) + +cc_binary( + name = "mutex_benchmark", + testonly = 1, + copts = ABSL_DEFAULT_COPTS, + visibility = ["//visibility:private"], + deps = [ + ":mutex_benchmark_common", + ], ) cc_test(
diff --git a/absl/synchronization/internal/kernel_timeout.h b/absl/synchronization/internal/kernel_timeout.h index bb70800..9e1eed7 100644 --- a/absl/synchronization/internal/kernel_timeout.h +++ b/absl/synchronization/internal/kernel_timeout.h
@@ -76,7 +76,7 @@ if (x <= 0) x = 1; // A time larger than what can be represented to the kernel is treated // as no timeout. - if (x == std::numeric_limits<int64_t>::max()) x = 0; + if (x == (std::numeric_limits<int64_t>::max)()) x = 0; return x; } @@ -90,7 +90,7 @@ ERROR, "Tried to create a timespec from a non-timeout; never do this."); // But we'll try to continue sanely. no-timeout ~= saturated timeout. - n = std::numeric_limits<int64_t>::max(); + n = (std::numeric_limits<int64_t>::max)(); } // Kernel APIs validate timespecs as being at or after the epoch, @@ -100,8 +100,8 @@ if (n < 0) n = 0; struct timespec abstime; - int64_t seconds = std::min(n / kNanosPerSecond, - int64_t{std::numeric_limits<time_t>::max()}); + int64_t seconds = (std::min)(n / kNanosPerSecond, + int64_t{(std::numeric_limits<time_t>::max)()}); abstime.tv_sec = static_cast<time_t>(seconds); abstime.tv_nsec = static_cast<decltype(abstime.tv_nsec)>(n % kNanosPerSecond); @@ -119,7 +119,7 @@ // <intsafe.h> and <WinBase.h>. typedef unsigned long DWord; // NOLINT DWord InMillisecondsFromNow() const { - constexpr DWord kInfinite = std::numeric_limits<DWord>::max(); + constexpr DWord kInfinite = (std::numeric_limits<DWord>::max)(); if (!has_timeout()) { return kInfinite; } @@ -130,7 +130,7 @@ if (ns_ >= now) { // Round up so that Now() + ms_from_now >= ns_. constexpr uint64_t max_nanos = - std::numeric_limits<int64_t>::max() - 999999u; + (std::numeric_limits<int64_t>::max)() - 999999u; uint64_t ms_from_now = (std::min<uint64_t>(max_nanos, ns_ - now) + 999999u) / 1000000u; if (ms_from_now > kInfinite) {
diff --git a/absl/synchronization/lifetime_test.cc b/absl/synchronization/lifetime_test.cc index 90c9009..b7360c2 100644 --- a/absl/synchronization/lifetime_test.cc +++ b/absl/synchronization/lifetime_test.cc
@@ -72,23 +72,19 @@ // Launch thread 1 and thread 2, and block on their completion. // If any of 'mutex', 'condvar', or 'notification' is nullptr, use a locally // constructed instance instead. -void RunTests(absl::Mutex* mutex, absl::CondVar* condvar, - absl::Notification* notification) { +void RunTests(absl::Mutex* mutex, absl::CondVar* condvar) { absl::Mutex default_mutex; absl::CondVar default_condvar; - absl::Notification default_notification; + absl::Notification notification; if (!mutex) { mutex = &default_mutex; } if (!condvar) { condvar = &default_condvar; } - if (!notification) { - notification = &default_notification; - } bool state = false; - std::thread thread_one(ThreadOne, mutex, condvar, notification, &state); - std::thread thread_two(ThreadTwo, mutex, condvar, notification, &state); + std::thread thread_one(ThreadOne, mutex, condvar, ¬ification, &state); + std::thread thread_two(ThreadTwo, mutex, condvar, ¬ification, &state); thread_one.join(); thread_two.join(); } @@ -96,8 +92,7 @@ void TestLocals() { absl::Mutex mutex; absl::CondVar condvar; - absl::Notification notification; - RunTests(&mutex, &condvar, ¬ification); + RunTests(&mutex, &condvar); } // Global variables during start and termination
diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index a378190..aeef3c9 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h
@@ -584,7 +584,7 @@ // ----------------------------------------------------------------------------- // // As noted above, `Mutex` contains a number of member functions which take a -// `Condition` as a argument; clients can wait for conditions to become `true` +// `Condition` as an argument; clients can wait for conditions to become `true` // before attempting to acquire the mutex. These sections are known as // "condition critical" sections. To use a `Condition`, you simply need to // construct it, and use within an appropriate `Mutex` member function;
diff --git a/absl/synchronization/mutex_benchmark.cc b/absl/synchronization/mutex_benchmark.cc index 1e019e0..2652bb9 100644 --- a/absl/synchronization/mutex_benchmark.cc +++ b/absl/synchronization/mutex_benchmark.cc
@@ -12,16 +12,154 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include <cstdint> +#include <mutex> // NOLINT(build/c++11) #include <vector> -#include "benchmark/benchmark.h" -#include "absl/base/internal/sysinfo.h" +#include "absl/base/internal/cycleclock.h" +#include "absl/base/internal/spinlock.h" #include "absl/synchronization/blocking_counter.h" #include "absl/synchronization/internal/thread_pool.h" #include "absl/synchronization/mutex.h" +#include "benchmark/benchmark.h" namespace { +void BM_Mutex(benchmark::State& state) { + static absl::Mutex* mu = new absl::Mutex; + for (auto _ : state) { + absl::MutexLock lock(mu); + } +} +BENCHMARK(BM_Mutex)->UseRealTime()->Threads(1)->ThreadPerCpu(); + +static void DelayNs(int64_t ns, int* data) { + int64_t end = absl::base_internal::CycleClock::Now() + + ns * absl::base_internal::CycleClock::Frequency() / 1e9; + while (absl::base_internal::CycleClock::Now() < end) { + ++(*data); + benchmark::DoNotOptimize(*data); + } +} + +template <typename MutexType> +class RaiiLocker { + public: + explicit RaiiLocker(MutexType* mu) : mu_(mu) { mu_->Lock(); } + ~RaiiLocker() { mu_->Unlock(); } + private: + MutexType* mu_; +}; + +template <> +class RaiiLocker<std::mutex> { + public: + explicit RaiiLocker(std::mutex* mu) : mu_(mu) { mu_->lock(); } + ~RaiiLocker() { mu_->unlock(); } + private: + std::mutex* mu_; +}; + +template <typename MutexType> +void BM_Contended(benchmark::State& state) { + struct Shared { + MutexType mu; + int data = 0; + }; + static auto* shared = new Shared; + int local = 0; + for (auto _ : state) { + // Here we model both local work outside of the critical section as well as + // some work inside of the critical section. The idea is to capture some + // more or less realisitic contention levels. + // If contention is too low, the benchmark won't measure anything useful. + // If contention is unrealistically high, the benchmark will favor + // bad mutex implementations that block and otherwise distract threads + // from the mutex and shared state for as much as possible. + // To achieve this amount of local work is multiplied by number of threads + // to keep ratio between local work and critical section approximately + // equal regardless of number of threads. + DelayNs(100 * state.threads, &local); + RaiiLocker<MutexType> locker(&shared->mu); + DelayNs(state.range(0), &shared->data); + } +} + +BENCHMARK_TEMPLATE(BM_Contended, absl::Mutex) + ->UseRealTime() + // ThreadPerCpu poorly handles non-power-of-two CPU counts. + ->Threads(1) + ->Threads(2) + ->Threads(4) + ->Threads(6) + ->Threads(8) + ->Threads(12) + ->Threads(16) + ->Threads(24) + ->Threads(32) + ->Threads(48) + ->Threads(64) + ->Threads(96) + ->Threads(128) + ->Threads(192) + ->Threads(256) + // Some empirically chosen amounts of work in critical section. + // 1 is low contention, 200 is high contention and few values in between. + ->Arg(1) + ->Arg(20) + ->Arg(50) + ->Arg(200); + +BENCHMARK_TEMPLATE(BM_Contended, absl::base_internal::SpinLock) + ->UseRealTime() + // ThreadPerCpu poorly handles non-power-of-two CPU counts. + ->Threads(1) + ->Threads(2) + ->Threads(4) + ->Threads(6) + ->Threads(8) + ->Threads(12) + ->Threads(16) + ->Threads(24) + ->Threads(32) + ->Threads(48) + ->Threads(64) + ->Threads(96) + ->Threads(128) + ->Threads(192) + ->Threads(256) + // Some empirically chosen amounts of work in critical section. + // 1 is low contention, 200 is high contention and few values in between. + ->Arg(1) + ->Arg(20) + ->Arg(50) + ->Arg(200); + +BENCHMARK_TEMPLATE(BM_Contended, std::mutex) + ->UseRealTime() + // ThreadPerCpu poorly handles non-power-of-two CPU counts. + ->Threads(1) + ->Threads(2) + ->Threads(4) + ->Threads(6) + ->Threads(8) + ->Threads(12) + ->Threads(16) + ->Threads(24) + ->Threads(32) + ->Threads(48) + ->Threads(64) + ->Threads(96) + ->Threads(128) + ->Threads(192) + ->Threads(256) + // Some empirically chosen amounts of work in critical section. + // 1 is low contention, 200 is high contention and few values in between. + ->Arg(1) + ->Arg(20) + ->Arg(50) + ->Arg(200); + // Measure the overhead of conditions on mutex release (when they must be // evaluated). Mutex has (some) support for equivalence classes allowing // Conditions with the same function/argument to potentially not be multiply @@ -82,13 +220,4 @@ #endif BENCHMARK(BM_ConditionWaiters)->RangePair(0, 2, 1, kMaxConditionWaiters); -void BM_ContendedMutex(benchmark::State& state) { - static absl::Mutex* mu = new absl::Mutex; - for (auto _ : state) { - absl::MutexLock lock(mu); - } -} -BENCHMARK(BM_ContendedMutex)->Threads(1); -BENCHMARK(BM_ContendedMutex)->ThreadPerCpu(); - } // namespace
diff --git a/absl/synchronization/notification.cc b/absl/synchronization/notification.cc index ed8cc90..cdcbc13 100644 --- a/absl/synchronization/notification.cc +++ b/absl/synchronization/notification.cc
@@ -22,6 +22,7 @@ #include "absl/time/time.h" namespace absl { + void Notification::Notify() { MutexLock l(&this->mutex_);
diff --git a/absl/synchronization/notification.h b/absl/synchronization/notification.h index 107932f..f95f4d1 100644 --- a/absl/synchronization/notification.h +++ b/absl/synchronization/notification.h
@@ -52,6 +52,7 @@ #include <atomic> +#include "absl/base/macros.h" #include "absl/synchronization/mutex.h" #include "absl/time/time.h"
diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel index c7c16d4..2082f52 100644 --- a/absl/time/BUILD.bazel +++ b/absl/time/BUILD.bazel
@@ -15,7 +15,7 @@ # load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", ) @@ -27,6 +27,7 @@ cc_library( name = "time", srcs = [ + "civil_time.cc", "clock.cc", "duration.cc", "format.cc", @@ -35,6 +36,7 @@ "time.cc", ], hdrs = [ + "civil_time.h", "clock.h", "time.h", ], @@ -72,10 +74,10 @@ cc_test( name = "time_test", srcs = [ + "civil_time_test.cc", "clock_test.cc", "duration_test.cc", "format_test.cc", - "time_norm_test.cc", "time_test.cc", "time_zone_test.cc", ], @@ -94,6 +96,7 @@ cc_test( name = "time_benchmark", srcs = [ + "civil_time_benchmark.cc", "clock_benchmark.cc", "duration_benchmark.cc", "format_benchmark.cc", @@ -107,6 +110,7 @@ ":test_util", ":time", "//absl/base", + "//absl/hash", "@com_github_google_benchmark//:benchmark_main", ], )
diff --git a/absl/time/CMakeLists.txt b/absl/time/CMakeLists.txt index 0627236..53216cd 100644 --- a/absl/time/CMakeLists.txt +++ b/absl/time/CMakeLists.txt
@@ -15,6 +15,7 @@ # list(APPEND TIME_PUBLIC_HEADERS + "civil_time.h" "clock.h" "time.h" ) @@ -29,6 +30,7 @@ ) list(APPEND TIME_SRC + "civil_time.cc" "time.cc" "clock.cc" "duration.cc" @@ -74,11 +76,11 @@ # test time_test list(APPEND TIME_TEST_SRC + "civil_time_test.cc" "time_test.cc" "clock_test.cc" "duration_test.cc" "format_test.cc" - "time_norm_test.cc" "time_test.cc" "time_zone_test.cc" "internal/test_util.cc"
diff --git a/absl/time/civil_time.cc b/absl/time/civil_time.cc new file mode 100644 index 0000000..5654179 --- /dev/null +++ b/absl/time/civil_time.cc
@@ -0,0 +1,88 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/time/civil_time.h" + +#include <cstdlib> +#include <string> + +#include "absl/strings/str_cat.h" +#include "absl/time/time.h" + +namespace absl { + +namespace { + +// Since a civil time has a larger year range than absl::Time (64-bit years vs +// 64-bit seconds, respectively) we normalize years to roughly +/- 400 years +// around the year 2400, which will produce an equivalent year in a range that +// absl::Time can handle. +inline civil_year_t NormalizeYear(civil_year_t year) { + return 2400 + year % 400; +} + +// Formats the given CivilSecond according to the given format. +std::string FormatYearAnd(string_view fmt, CivilSecond cs) { + const CivilSecond ncs(NormalizeYear(cs.year()), cs.month(), cs.day(), + cs.hour(), cs.minute(), cs.second()); + const TimeZone utc = UTCTimeZone(); + // TODO(absl-team): Avoid conversion of fmt std::string. + return StrCat(cs.year(), FormatTime(std::string(fmt), FromCivil(ncs, utc), utc)); +} + +} // namespace + +std::string FormatCivilTime(CivilSecond c) { + return FormatYearAnd("-%m-%dT%H:%M:%S", c); +} +std::string FormatCivilTime(CivilMinute c) { + return FormatYearAnd("-%m-%dT%H:%M", c); +} +std::string FormatCivilTime(CivilHour c) { + return FormatYearAnd("-%m-%dT%H", c); +} +std::string FormatCivilTime(CivilDay c) { + return FormatYearAnd("-%m-%d", c); +} +std::string FormatCivilTime(CivilMonth c) { + return FormatYearAnd("-%m", c); +} +std::string FormatCivilTime(CivilYear c) { + return FormatYearAnd("", c); +} + +namespace time_internal { + +std::ostream& operator<<(std::ostream& os, CivilYear y) { + return os << FormatCivilTime(y); +} +std::ostream& operator<<(std::ostream& os, CivilMonth m) { + return os << FormatCivilTime(m); +} +std::ostream& operator<<(std::ostream& os, CivilDay d) { + return os << FormatCivilTime(d); +} +std::ostream& operator<<(std::ostream& os, CivilHour h) { + return os << FormatCivilTime(h); +} +std::ostream& operator<<(std::ostream& os, CivilMinute m) { + return os << FormatCivilTime(m); +} +std::ostream& operator<<(std::ostream& os, CivilSecond s) { + return os << FormatCivilTime(s); +} + +} // namespace time_internal + +} // namespace absl
diff --git a/absl/time/civil_time.h b/absl/time/civil_time.h new file mode 100644 index 0000000..30d73c8 --- /dev/null +++ b/absl/time/civil_time.h
@@ -0,0 +1,486 @@ +// 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. +// +// ----------------------------------------------------------------------------- +// File: civil_time.h +// ----------------------------------------------------------------------------- +// +// This header file defines abstractions for computing with "civil time". +// The term "civil time" refers to the legally recognized human-scale time +// that is represented by the six fields `YYYY-MM-DD hh:mm:ss`. A "date" +// is perhaps the most common example of a civil time (represented here as +// an `absl::CivilDay`). +// +// Modern-day civil time follows the Gregorian Calendar and is a +// time-zone-independent concept: a civil time of "2015-06-01 12:00:00", for +// example, is not tied to a time zone. Put another way, a civil time does not +// map to a unique point in time; a civil time must be mapped to an absolute +// time *through* a time zone. +// +// Because a civil time is what most people think of as "time," it is common to +// map absolute times to civil times to present to users. +// +// Time zones define the relationship between absolute and civil times. Given an +// absolute or civil time and a time zone, you can compute the other time: +// +// Civil Time = F(Absolute Time, Time Zone) +// Absolute Time = G(Civil Time, Time Zone) +// +// The Abseil time library allows you to construct such civil times from +// absolute times; consult time.h for such functionality. +// +// This library provides six classes for constructing civil-time objects, and +// provides several helper functions for rounding, iterating, and performing +// arithmetic on civil-time objects, while avoiding complications like +// daylight-saving time (DST): +// +// * `absl::CivilSecond` +// * `absl::CivilMinute` +// * `absl::CivilHour` +// * `absl::CivilDay` +// * `absl::CivilMonth` +// * `absl::CivilYear` +// +// Example: +// +// // Construct a civil-time object for a specific day +// const absl::CivilDay cd(1969, 07, 20); +// +// // Construct a civil-time object for a specific second +// const absl::CivilSecond cd(2018, 8, 1, 12, 0, 1); +// +// Note: In C++14 and later, this library is usable in a constexpr context. +// +// Example: +// +// // Valid in C++14 +// constexpr absl::CivilDay cd(1969, 07, 20); +// + +#ifndef ABSL_TIME_CIVIL_TIME_H_ +#define ABSL_TIME_CIVIL_TIME_H_ + +#include <string> + +#include "absl/strings/string_view.h" +#include "absl/time/internal/cctz/include/cctz/civil_time.h" + +namespace absl { + +namespace time_internal { +struct second_tag : cctz::detail::second_tag {}; +struct minute_tag : second_tag, cctz::detail::minute_tag {}; +struct hour_tag : minute_tag, cctz::detail::hour_tag {}; +struct day_tag : hour_tag, cctz::detail::day_tag {}; +struct month_tag : day_tag, cctz::detail::month_tag {}; +struct year_tag : month_tag, cctz::detail::year_tag {}; +} // namespace time_internal + +// ----------------------------------------------------------------------------- +// CivilSecond, CivilMinute, CivilHour, CivilDay, CivilMonth, CivilYear +// ----------------------------------------------------------------------------- +// +// Each of these civil-time types is a simple value type with the same +// interface for construction and the same six accessors for each of the civil +// time fields (year, month, day, hour, minute, and second, aka YMDHMS). These +// classes differ only in their alignment, which is indicated by the type name +// and specifies the field on which arithmetic operates. +// +// CONSTRUCTION +// +// Each of the civil-time types can be constructed in two ways: by directly +// passing to the constructor up to six integers representing the YMDHMS fields, +// or by copying the YMDHMS fields from a differently aligned civil-time type. +// Omitted fields are assigned their minimum valid value. Hours, minutes, and +// seconds will be set to 0, month and day will be set to 1. Since there is no +// minimum year, the default is 1970. +// +// Examples: +// +// absl::CivilDay default_value; // 1970-01-01 00:00:00 +// +// absl::CivilDay a(2015, 2, 3); // 2015-02-03 00:00:00 +// absl::CivilDay b(2015, 2, 3, 4, 5, 6); // 2015-02-03 00:00:00 +// absl::CivilDay c(2015); // 2015-01-01 00:00:00 +// +// absl::CivilSecond ss(2015, 2, 3, 4, 5, 6); // 2015-02-03 04:05:06 +// absl::CivilMinute mm(ss); // 2015-02-03 04:05:00 +// absl::CivilHour hh(mm); // 2015-02-03 04:00:00 +// absl::CivilDay d(hh); // 2015-02-03 00:00:00 +// absl::CivilMonth m(d); // 2015-02-01 00:00:00 +// absl::CivilYear y(m); // 2015-01-01 00:00:00 +// +// m = absl::CivilMonth(y); // 2015-01-01 00:00:00 +// d = absl::CivilDay(m); // 2015-01-01 00:00:00 +// hh = absl::CivilHour(d); // 2015-01-01 00:00:00 +// mm = absl::CivilMinute(hh); // 2015-01-01 00:00:00 +// ss = absl::CivilSecond(mm); // 2015-01-01 00:00:00 +// +// Each civil-time class is aligned to the civil-time field indicated in the +// class's name after normalization. Alignment is performed by setting all the +// inferior fields to their minimum valid value (as described above). The +// following are examples of how each of the six types would align the fields +// representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the +// string format used here is not important; it's just a shorthand way of +// showing the six YMDHMS fields.) +// +// absl::CivilSecond : 2015-11-22 12:34:56 +// absl::CivilMinute : 2015-11-22 12:34:00 +// absl::CivilHour : 2015-11-22 12:00:00 +// absl::CivilDay : 2015-11-22 00:00:00 +// absl::CivilMonth : 2015-11-01 00:00:00 +// absl::CivilYear : 2015-01-01 00:00:00 +// +// Each civil-time type performs arithmetic on the field to which it is +// aligned. This means that adding 1 to an absl::CivilDay increments the day +// field (normalizing as necessary), and subtracting 7 from an absl::CivilMonth +// operates on the month field (normalizing as necessary). All arithmetic +// produces a valid civil time. Difference requires two similarly aligned +// civil-time objects and returns the scalar answer in units of the objects' +// alignment. For example, the difference between two absl::CivilHour objects +// will give an answer in units of civil hours. +// +// ALIGNMENT CONVERSION +// +// The alignment of a civil-time object cannot change, but the object may be +// used to construct a new object with a different alignment. This is referred +// to as "realigning". When realigning to a type with the same or more +// precision (e.g., absl::CivilDay -> absl::CivilSecond), the conversion may be +// performed implicitly since no information is lost. However, if information +// could be discarded (e.g., CivilSecond -> CivilDay), the conversion must +// be explicit at the call site. +// +// Examples: +// +// void UseDay(absl::CivilDay day); +// +// absl::CivilSecond cs; +// UseDay(cs); // Won't compile because data may be discarded +// UseDay(absl::CivilDay(cs)); // OK: explicit conversion +// +// absl::CivilDay cd; +// UseDay(cd); // OK: no conversion needed +// +// absl::CivilMonth cm; +// UseDay(cm); // OK: implicit conversion to absl::CivilDay +// +// NORMALIZATION +// +// Normalization takes invalid values and adjusts them to produce valid values. +// Within the civil-time library, integer arguments passed to the Civil* +// constructors may be out-of-range, in which case they are normalized by +// carrying overflow into a field of courser granularity to produce valid +// civil-time objects. This normalization enables natural arithmetic on +// constructor arguments without worrying about the field's range. +// +// Examples: +// +// // Out-of-range; normalized to 2016-11-01 +// absl::CivilDay d(2016, 10, 32); +// // Out-of-range, negative: normalized to 2016-10-30T23 +// absl::CivilHour h1(2016, 10, 31, -1); +// // Normalization is cumulative: normalized to 2016-10-30T23 +// absl::CivilHour h2(2016, 10, 32, -25); +// +// Note: If normalization is undesired, you can signal an error by comparing +// the constructor arguments to the normalized values returned by the YMDHMS +// properties. +// +// COMPARISON +// +// Comparison between civil-time objects considers all six YMDHMS fields, +// regardless of the type's alignment. Comparison between differently aligned +// civil-time types is allowed. +// +// Examples: +// +// absl::CivilDay feb_3(2015, 2, 3); // 2015-02-03 00:00:00 +// absl::CivilDay mar_4(2015, 3, 4); // 2015-03-04 00:00:00 +// // feb_3 < mar_4 +// // absl::CivilYear(feb_3) == absl::CivilYear(mar_4) +// +// absl::CivilSecond feb_3_noon(2015, 2, 3, 12, 0, 0); // 2015-02-03 12:00:00 +// // feb_3 < feb_3_noon +// // feb_3 == absl::CivilDay(feb_3_noon) +// +// // Iterates all the days of February 2015. +// for (absl::CivilDay d(2015, 2, 1); d < absl::CivilMonth(2015, 3); ++d) { +// // ... +// } +// +// ARITHMETIC +// +// Civil-time types support natural arithmetic operators such as addition, +// subtraction, and difference. Arithmetic operates on the civil-time field +// indicated in the type's name. Difference operators require arguments with +// the same alignment and return the answer in units of the alignment. +// +// Example: +// +// absl::CivilDay a(2015, 2, 3); +// ++a; // 2015-02-04 00:00:00 +// --a; // 2015-02-03 00:00:00 +// absl::CivilDay b = a + 1; // 2015-02-04 00:00:00 +// absl::CivilDay c = 1 + b; // 2015-02-05 00:00:00 +// int n = c - a; // n = 2 (civil days) +// int m = c - absl::CivilMonth(c); // Won't compile: different types. +// +// ACCESSORS +// +// Each civil-time type has accessors for all six of the civil-time fields: +// year, month, day, hour, minute, and second. +// +// civil_year_t year() +// int month() +// int day() +// int hour() +// int minute() +// int second() +// +// Recall that fields inferior to the type's aligment will be set to their +// minimum valid value. +// +// Example: +// +// absl::CivilDay d(2015, 6, 28); +// // d.year() == 2015 +// // d.month() == 6 +// // d.day() == 28 +// // d.hour() == 0 +// // d.minute() == 0 +// // d.second() == 0 +// +// CASE STUDY: Adding a month to January 31. +// +// One of the classic questions that arises when considering a civil time +// library (or a date library or a date/time library) is this: +// "What is the result of adding a month to January 31?" +// This is an interesting question because it is unclear what is meant by a +// "month", and several different answers are possible, depending on context: +// +// 1. March 3 (or 2 if a leap year), if "add a month" means to add a month to +// the current month, and adjust the date to overflow the extra days into +// March. In this case the result of "February 31" would be normalized as +// within the civil-time library. +// 2. February 28 (or 29 if a leap year), if "add a month" means to add a +// month, and adjust the date while holding the resulting month constant. +// In this case, the result of "February 31" would be truncated to the last +// day in February. +// 3. An error. The caller may get some error, an exception, an invalid date +// object, or perhaps return `false`. This may make sense because there is +// no single unambiguously correct answer to the question. +// +// Practically speaking, any answer that is not what the programmer intended +// is the wrong answer. +// +// The Abseil time library avoids this problem by making it impossible to +// ask ambiguous questions. All civil-time objects are aligned to a particular +// civil-field boundary (such as aligned to a year, month, day, hour, minute, +// or second), and arithmetic operates on the field to which the object is +// aligned. This means that in order to "add a month" the object must first be +// aligned to a month boundary, which is equivalent to the first day of that +// month. +// +// Of course, there are ways to compute an answer the question at hand using +// this Abseil time library, but they require the programmer to be explicit +// about the answer they expect. To illustrate, let's see how to compute all +// three of the above possible answers to the question of "Jan 31 plus 1 +// month": +// +// Example: +// +// const absl::CivilDay d(2015, 1, 31); +// +// // Answer 1: +// // Add 1 to the month field in the constructor, and rely on normalization. +// const auto normalized = absl::CivilDay(d.year(), d.month() + 1, d.day()); +// // normalized == 2015-03-03 (aka Feb 31) +// +// // Answer 2: +// // Add 1 to month field, capping to the end of next month. +// const auto next_month = absl::CivilMonth(d) + 1; +// const auto last_day_of_next_month = absl::CivilDay(next_month + 1) - 1; +// const auto capped = std::min(normalized, last_day_of_next_month); +// // capped == 2015-02-28 +// +// // Answer 3: +// // Signal an error if the normalized answer is not in next month. +// if (absl::CivilMonth(normalized) != next_month) { +// // error, month overflow +// } +// +using CivilSecond = + time_internal::cctz::detail::civil_time<time_internal::second_tag>; +using CivilMinute = + time_internal::cctz::detail::civil_time<time_internal::minute_tag>; +using CivilHour = + time_internal::cctz::detail::civil_time<time_internal::hour_tag>; +using CivilDay = + time_internal::cctz::detail::civil_time<time_internal::day_tag>; +using CivilMonth = + time_internal::cctz::detail::civil_time<time_internal::month_tag>; +using CivilYear = + time_internal::cctz::detail::civil_time<time_internal::year_tag>; + +// civil_year_t +// +// Type alias of a civil-time year value. This type is guaranteed to (at least) +// support any year value supported by `time_t`. +// +// Example: +// +// absl::CivilSecond cs = ...; +// absl::civil_year_t y = cs.year(); +// cs = absl::CivilSecond(y, 1, 1, 0, 0, 0); // CivilSecond(CivilYear(cs)) +// +using civil_year_t = time_internal::cctz::year_t; + +// civil_diff_t +// +// Type alias of the difference between two civil-time values. +// This type is used to indicate arguments that are not +// normalized (such as parameters to the civil-time constructors), the results +// of civil-time subtraction, or the operand to civil-time addition. +// +// Example: +// +// absl::civil_diff_t n_sec = cs1 - cs2; // cs1 == cs2 + n_sec; +// +using civil_diff_t = time_internal::cctz::diff_t; + +// Weekday::monday, Weekday::tuesday, Weekday::wednesday, Weekday::thursday, +// Weekday::friday, Weekday::saturday, Weekday::sunday +// +// The Weekday enum class represents the civil-time concept of a "weekday" with +// members for all days of the week. +// +// absl::Weekday wd = absl::Weekday::thursday; +// +using Weekday = time_internal::cctz::weekday; + +// GetWeekday() +// +// Returns the absl::Weekday for the given absl::CivilDay. +// +// Example: +// +// absl::CivilDay a(2015, 8, 13); +// absl::Weekday wd = absl::GetWeekday(a); // wd == absl::Weekday::thursday +// +inline Weekday GetWeekday(CivilDay cd) { + return time_internal::cctz::get_weekday(cd); +} + +// NextWeekday() +// PrevWeekday() +// +// Returns the absl::CivilDay that strictly follows or precedes a given +// absl::CivilDay, and that falls on the given absl::Weekday. +// +// Example, given the following month: +// +// August 2015 +// Su Mo Tu We Th Fr Sa +// 1 +// 2 3 4 5 6 7 8 +// 9 10 11 12 13 14 15 +// 16 17 18 19 20 21 22 +// 23 24 25 26 27 28 29 +// 30 31 +// +// absl::CivilDay a(2015, 8, 13); +// // absl::GetWeekday(a) == absl::Weekday::thursday +// absl::CivilDay b = absl::NextWeekday(a, absl::Weekday::thursday); +// // b = 2015-08-20 +// absl::CivilDay c = absl::PrevWeekday(a, absl::Weekday::thursday); +// // c = 2015-08-06 +// +// absl::CivilDay d = ... +// // Gets the following Thursday if d is not already Thursday +// absl::CivilDay thurs1 = absl::PrevWeekday(d, absl::Weekday::thursday) + 7; +// // Gets the previous Thursday if d is not already Thursday +// absl::CivilDay thurs2 = absl::NextWeekday(d, absl::Weekday::thursday) - 7; +// +inline CivilDay NextWeekday(CivilDay cd, Weekday wd) { + return CivilDay(time_internal::cctz::next_weekday(cd, wd)); +} +inline CivilDay PrevWeekday(CivilDay cd, Weekday wd) { + return CivilDay(time_internal::cctz::prev_weekday(cd, wd)); +} + +// GetYearDay() +// +// Returns the day-of-year for the given absl::CivilDay. +// +// Example: +// +// absl::CivilDay a(2015, 1, 1); +// int yd_jan_1 = absl::GetYearDay(a); // yd_jan_1 = 1 +// absl::CivilDay b(2015, 12, 31); +// int yd_dec_31 = absl::GetYearDay(b); // yd_dec_31 = 365 +// +inline int GetYearDay(CivilDay cd) { + return time_internal::cctz::get_yearday(cd); +} + +// FormatCivilTime() +// +// Formats the given civil-time value into a string value of the following +// format: +// +// Type | Format +// --------------------------------- +// CivilSecond | YYYY-MM-DDTHH:MM:SS +// CivilMinute | YYYY-MM-DDTHH:MM +// CivilHour | YYYY-MM-DDTHH +// CivilDay | YYYY-MM-DD +// CivilMonth | YYYY-MM +// CivilYear | YYYY +// +// Example: +// +// absl::CivilDay d = absl::CivilDay(1969, 7, 20); +// string day_string = absl::FormatCivilTime(d); // "1969-07-20" +// +std::string FormatCivilTime(CivilSecond c); +std::string FormatCivilTime(CivilMinute c); +std::string FormatCivilTime(CivilHour c); +std::string FormatCivilTime(CivilDay c); +std::string FormatCivilTime(CivilMonth c); +std::string FormatCivilTime(CivilYear c); + +namespace time_internal { // For functions found via ADL on civil-time tags. + +// Streaming Operators +// +// Each civil-time type may be sent to an output stream using operator<<(). +// The result matches the string produced by `FormatCivilTime()`. +// +// Example: +// +// absl::CivilDay d = absl::CivilDay("1969-07-20"); +// std::cout << "Date is: " << d << "\n"; +// +std::ostream& operator<<(std::ostream& os, CivilYear y); +std::ostream& operator<<(std::ostream& os, CivilMonth m); +std::ostream& operator<<(std::ostream& os, CivilDay d); +std::ostream& operator<<(std::ostream& os, CivilHour h); +std::ostream& operator<<(std::ostream& os, CivilMinute m); +std::ostream& operator<<(std::ostream& os, CivilSecond s); + +} // namespace time_internal + +} // namespace absl + +#endif // ABSL_TIME_CIVIL_TIME_H_
diff --git a/absl/time/civil_time_benchmark.cc b/absl/time/civil_time_benchmark.cc new file mode 100644 index 0000000..f30f636 --- /dev/null +++ b/absl/time/civil_time_benchmark.cc
@@ -0,0 +1,107 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/time/civil_time.h" + +#include <numeric> +#include <vector> + +#include "absl/hash/hash.h" +#include "benchmark/benchmark.h" + +namespace { + +// Run on (12 X 3492 MHz CPUs); 2018-11-05T13:44:29.814239103-08:00 +// CPU: Intel Haswell with HyperThreading (6 cores) dL1:32KB dL2:256KB dL3:15MB +// Benchmark Time(ns) CPU(ns) Iterations +// ---------------------------------------------------------------- +// BM_Difference_Days 14.5 14.5 48531105 +// BM_Step_Days 12.6 12.6 54876006 +// BM_Format 587 587 1000000 +// BM_Parse 692 692 1000000 +// BM_RoundTripFormatParse 1309 1309 532075 +// BM_CivilYearAbslHash 0.710 0.710 976400000 +// BM_CivilMonthAbslHash 1.13 1.13 619500000 +// BM_CivilDayAbslHash 1.70 1.70 426000000 +// BM_CivilHourAbslHash 2.45 2.45 287600000 +// BM_CivilMinuteAbslHash 3.21 3.21 226200000 +// BM_CivilSecondAbslHash 4.10 4.10 171800000 + +void BM_Difference_Days(benchmark::State& state) { + const absl::CivilDay c(2014, 8, 22); + const absl::CivilDay epoch(1970, 1, 1); + while (state.KeepRunning()) { + const absl::civil_diff_t n = c - epoch; + benchmark::DoNotOptimize(n); + } +} +BENCHMARK(BM_Difference_Days); + +void BM_Step_Days(benchmark::State& state) { + const absl::CivilDay kStart(2014, 8, 22); + absl::CivilDay c = kStart; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(++c); + } +} +BENCHMARK(BM_Step_Days); + +void BM_Format(benchmark::State& state) { + const absl::CivilSecond c(2014, 1, 2, 3, 4, 5); + while (state.KeepRunning()) { + const std::string s = absl::FormatCivilTime(c); + benchmark::DoNotOptimize(s); + } +} +BENCHMARK(BM_Format); + +template <typename T> +void BM_CivilTimeAbslHash(benchmark::State& state) { + const int kSize = 100000; + std::vector<T> civil_times(kSize); + std::iota(civil_times.begin(), civil_times.end(), T(2018)); + + absl::Hash<T> absl_hasher; + while (state.KeepRunningBatch(kSize)) { + for (const T civil_time : civil_times) { + benchmark::DoNotOptimize(absl_hasher(civil_time)); + } + } +} +void BM_CivilYearAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilYear>(state); +} +void BM_CivilMonthAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilMonth>(state); +} +void BM_CivilDayAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilDay>(state); +} +void BM_CivilHourAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilHour>(state); +} +void BM_CivilMinuteAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilMinute>(state); +} +void BM_CivilSecondAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilSecond>(state); +} +BENCHMARK(BM_CivilYearAbslHash); +BENCHMARK(BM_CivilMonthAbslHash); +BENCHMARK(BM_CivilDayAbslHash); +BENCHMARK(BM_CivilHourAbslHash); +BENCHMARK(BM_CivilMinuteAbslHash); +BENCHMARK(BM_CivilSecondAbslHash); + +} // namespace
diff --git a/absl/time/civil_time_test.cc b/absl/time/civil_time_test.cc new file mode 100644 index 0000000..dc83d7a --- /dev/null +++ b/absl/time/civil_time_test.cc
@@ -0,0 +1,1073 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/time/civil_time.h" + +#include <limits> +#include <sstream> +#include <type_traits> + +#include "absl/base/macros.h" +#include "gtest/gtest.h" + +namespace { + +TEST(CivilTime, DefaultConstruction) { + absl::CivilSecond ss; + EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss)); + + absl::CivilMinute mm; + EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm)); + + absl::CivilHour hh; + EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh)); + + absl::CivilDay d; + EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d)); + + absl::CivilMonth m; + EXPECT_EQ("1970-01", absl::FormatCivilTime(m)); + + absl::CivilYear y; + EXPECT_EQ("1970", absl::FormatCivilTime(y)); +} + +TEST(CivilTime, StructMember) { + struct S { + absl::CivilDay day; + }; + S s = {}; + EXPECT_EQ(absl::CivilDay{}, s.day); +} + +TEST(CivilTime, FieldsConstruction) { + EXPECT_EQ("2015-01-02T03:04:05", + absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015-01-02T03:04:00", + absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015-01-02T03:00:00", + absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3))); + EXPECT_EQ("2015-01-02T00:00:00", + absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2))); + EXPECT_EQ("2015-01-01T00:00:00", + absl::FormatCivilTime(absl::CivilSecond(2015, 1))); + EXPECT_EQ("2015-01-01T00:00:00", + absl::FormatCivilTime(absl::CivilSecond(2015))); + + EXPECT_EQ("2015-01-02T03:04", + absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015-01-02T03:04", + absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015-01-02T03:00", + absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3))); + EXPECT_EQ("2015-01-02T00:00", + absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2))); + EXPECT_EQ("2015-01-01T00:00", + absl::FormatCivilTime(absl::CivilMinute(2015, 1))); + EXPECT_EQ("2015-01-01T00:00", + absl::FormatCivilTime(absl::CivilMinute(2015))); + + EXPECT_EQ("2015-01-02T03", + absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015-01-02T03", + absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015-01-02T03", + absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3))); + EXPECT_EQ("2015-01-02T00", + absl::FormatCivilTime(absl::CivilHour(2015, 1, 2))); + EXPECT_EQ("2015-01-01T00", + absl::FormatCivilTime(absl::CivilHour(2015, 1))); + EXPECT_EQ("2015-01-01T00", + absl::FormatCivilTime(absl::CivilHour(2015))); + + EXPECT_EQ("2015-01-02", + absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015-01-02", + absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015-01-02", + absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3))); + EXPECT_EQ("2015-01-02", + absl::FormatCivilTime(absl::CivilDay(2015, 1, 2))); + EXPECT_EQ("2015-01-01", + absl::FormatCivilTime(absl::CivilDay(2015, 1))); + EXPECT_EQ("2015-01-01", + absl::FormatCivilTime(absl::CivilDay(2015))); + + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3))); + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2))); + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015, 1))); + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015))); + + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3))); + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015, 1, 2))); + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015, 1))); + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015))); +} + +TEST(CivilTime, FieldsConstructionLimits) { + const int kIntMax = std::numeric_limits<int>::max(); + EXPECT_EQ("2038-01-19T03:14:07", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, 0, kIntMax))); + EXPECT_EQ("6121-02-11T05:21:07", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, kIntMax, kIntMax))); + EXPECT_EQ("251104-11-20T12:21:07", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, kIntMax, kIntMax, kIntMax))); + EXPECT_EQ("6130715-05-30T12:21:07", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, kIntMax, kIntMax, kIntMax, kIntMax))); + EXPECT_EQ("185087685-11-26T12:21:07", + absl::FormatCivilTime(absl::CivilSecond( + 1970, kIntMax, kIntMax, kIntMax, kIntMax, kIntMax))); + + const int kIntMin = std::numeric_limits<int>::min(); + EXPECT_EQ("1901-12-13T20:45:52", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, 0, kIntMin))); + EXPECT_EQ("-2182-11-20T18:37:52", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, kIntMin, kIntMin))); + EXPECT_EQ("-247165-02-11T10:37:52", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, kIntMin, kIntMin, kIntMin))); + EXPECT_EQ("-6126776-08-01T10:37:52", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, kIntMin, kIntMin, kIntMin, kIntMin))); + EXPECT_EQ("-185083747-10-31T10:37:52", + absl::FormatCivilTime(absl::CivilSecond( + 1970, kIntMin, kIntMin, kIntMin, kIntMin, kIntMin))); +} + +TEST(CivilTime, RangeLimits) { + const absl::civil_year_t kYearMax = + std::numeric_limits<absl::civil_year_t>::max(); + EXPECT_EQ(absl::CivilYear(kYearMax), + absl::CivilYear::max()); + EXPECT_EQ(absl::CivilMonth(kYearMax, 12), + absl::CivilMonth::max()); + EXPECT_EQ(absl::CivilDay(kYearMax, 12, 31), + absl::CivilDay::max()); + EXPECT_EQ(absl::CivilHour(kYearMax, 12, 31, 23), + absl::CivilHour::max()); + EXPECT_EQ(absl::CivilMinute(kYearMax, 12, 31, 23, 59), + absl::CivilMinute::max()); + EXPECT_EQ(absl::CivilSecond(kYearMax, 12, 31, 23, 59, 59), + absl::CivilSecond::max()); + + const absl::civil_year_t kYearMin = + std::numeric_limits<absl::civil_year_t>::min(); + EXPECT_EQ(absl::CivilYear(kYearMin), + absl::CivilYear::min()); + EXPECT_EQ(absl::CivilMonth(kYearMin, 1), + absl::CivilMonth::min()); + EXPECT_EQ(absl::CivilDay(kYearMin, 1, 1), + absl::CivilDay::min()); + EXPECT_EQ(absl::CivilHour(kYearMin, 1, 1, 0), + absl::CivilHour::min()); + EXPECT_EQ(absl::CivilMinute(kYearMin, 1, 1, 0, 0), + absl::CivilMinute::min()); + EXPECT_EQ(absl::CivilSecond(kYearMin, 1, 1, 0, 0, 0), + absl::CivilSecond::min()); +} + +TEST(CivilTime, ImplicitCrossAlignment) { + absl::CivilYear year(2015); + absl::CivilMonth month = year; + absl::CivilDay day = month; + absl::CivilHour hour = day; + absl::CivilMinute minute = hour; + absl::CivilSecond second = minute; + + second = year; + EXPECT_EQ(second, year); + second = month; + EXPECT_EQ(second, month); + second = day; + EXPECT_EQ(second, day); + second = hour; + EXPECT_EQ(second, hour); + second = minute; + EXPECT_EQ(second, minute); + + minute = year; + EXPECT_EQ(minute, year); + minute = month; + EXPECT_EQ(minute, month); + minute = day; + EXPECT_EQ(minute, day); + minute = hour; + EXPECT_EQ(minute, hour); + + hour = year; + EXPECT_EQ(hour, year); + hour = month; + EXPECT_EQ(hour, month); + hour = day; + EXPECT_EQ(hour, day); + + day = year; + EXPECT_EQ(day, year); + day = month; + EXPECT_EQ(day, month); + + month = year; + EXPECT_EQ(month, year); + + // Ensures unsafe conversions are not allowed. + EXPECT_FALSE( + (std::is_convertible<absl::CivilSecond, absl::CivilMinute>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilSecond, absl::CivilHour>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilSecond, absl::CivilDay>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilSecond, absl::CivilMonth>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilSecond, absl::CivilYear>::value)); + + EXPECT_FALSE( + (std::is_convertible<absl::CivilMinute, absl::CivilHour>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilMinute, absl::CivilDay>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilMinute, absl::CivilMonth>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilMinute, absl::CivilYear>::value)); + + EXPECT_FALSE( + (std::is_convertible<absl::CivilHour, absl::CivilDay>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilHour, absl::CivilMonth>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilHour, absl::CivilYear>::value)); + + EXPECT_FALSE( + (std::is_convertible<absl::CivilDay, absl::CivilMonth>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilDay, absl::CivilYear>::value)); + + EXPECT_FALSE( + (std::is_convertible<absl::CivilMonth, absl::CivilYear>::value)); +} + +TEST(CivilTime, ExplicitCrossAlignment) { + // + // Assign from smaller units -> larger units + // + + absl::CivilSecond second(2015, 1, 2, 3, 4, 5); + EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second)); + + absl::CivilMinute minute(second); + EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute)); + + absl::CivilHour hour(minute); + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour)); + + absl::CivilDay day(hour); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day)); + + absl::CivilMonth month(day); + EXPECT_EQ("2015-01", absl::FormatCivilTime(month)); + + absl::CivilYear year(month); + EXPECT_EQ("2015", absl::FormatCivilTime(year)); + + // + // Now assign from larger units -> smaller units + // + + month = absl::CivilMonth(year); + EXPECT_EQ("2015-01", absl::FormatCivilTime(month)); + + day = absl::CivilDay(month); + EXPECT_EQ("2015-01-01", absl::FormatCivilTime(day)); + + hour = absl::CivilHour(day); + EXPECT_EQ("2015-01-01T00", absl::FormatCivilTime(hour)); + + minute = absl::CivilMinute(hour); + EXPECT_EQ("2015-01-01T00:00", absl::FormatCivilTime(minute)); + + second = absl::CivilSecond(minute); + EXPECT_EQ("2015-01-01T00:00:00", absl::FormatCivilTime(second)); +} + +// Metafunction to test whether difference is allowed between two types. +template <typename T1, typename T2> +struct HasDiff { + template <typename U1, typename U2> + static std::false_type test(...); + template <typename U1, typename U2> + static std::true_type test(decltype(std::declval<U1>() - std::declval<U2>())); + static constexpr bool value = decltype(test<T1, T2>(0))::value; +}; + +TEST(CivilTime, DisallowCrossAlignedDifference) { + // Difference is allowed between types with the same alignment. + static_assert(HasDiff<absl::CivilSecond, absl::CivilSecond>::value, ""); + static_assert(HasDiff<absl::CivilMinute, absl::CivilMinute>::value, ""); + static_assert(HasDiff<absl::CivilHour, absl::CivilHour>::value, ""); + static_assert(HasDiff<absl::CivilDay, absl::CivilDay>::value, ""); + static_assert(HasDiff<absl::CivilMonth, absl::CivilMonth>::value, ""); + static_assert(HasDiff<absl::CivilYear, absl::CivilYear>::value, ""); + + // Difference is disallowed between types with different alignments. + static_assert(!HasDiff<absl::CivilSecond, absl::CivilMinute>::value, ""); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilHour>::value, ""); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilDay>::value, ""); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilMonth>::value, ""); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilYear>::value, ""); + + static_assert(!HasDiff<absl::CivilMinute, absl::CivilHour>::value, ""); + static_assert(!HasDiff<absl::CivilMinute, absl::CivilDay>::value, ""); + static_assert(!HasDiff<absl::CivilMinute, absl::CivilMonth>::value, ""); + static_assert(!HasDiff<absl::CivilMinute, absl::CivilYear>::value, ""); + + static_assert(!HasDiff<absl::CivilHour, absl::CivilDay>::value, ""); + static_assert(!HasDiff<absl::CivilHour, absl::CivilMonth>::value, ""); + static_assert(!HasDiff<absl::CivilHour, absl::CivilYear>::value, ""); + + static_assert(!HasDiff<absl::CivilDay, absl::CivilMonth>::value, ""); + static_assert(!HasDiff<absl::CivilDay, absl::CivilYear>::value, ""); + + static_assert(!HasDiff<absl::CivilMonth, absl::CivilYear>::value, ""); +} + +TEST(CivilTime, ValueSemantics) { + const absl::CivilHour a(2015, 1, 2, 3); + const absl::CivilHour b = a; + const absl::CivilHour c(b); + absl::CivilHour d; + d = c; + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(d)); +} + +TEST(CivilTime, Relational) { + // Tests that the alignment unit is ignored in comparison. + const absl::CivilYear year(2014); + const absl::CivilMonth month(year); + EXPECT_EQ(year, month); + +#define TEST_RELATIONAL(OLDER, YOUNGER) \ + do { \ + EXPECT_FALSE(OLDER < OLDER); \ + EXPECT_FALSE(OLDER > OLDER); \ + EXPECT_TRUE(OLDER >= OLDER); \ + EXPECT_TRUE(OLDER <= OLDER); \ + EXPECT_FALSE(YOUNGER < YOUNGER); \ + EXPECT_FALSE(YOUNGER > YOUNGER); \ + EXPECT_TRUE(YOUNGER >= YOUNGER); \ + EXPECT_TRUE(YOUNGER <= YOUNGER); \ + EXPECT_EQ(OLDER, OLDER); \ + EXPECT_NE(OLDER, YOUNGER); \ + EXPECT_LT(OLDER, YOUNGER); \ + EXPECT_LE(OLDER, YOUNGER); \ + EXPECT_GT(YOUNGER, OLDER); \ + EXPECT_GE(YOUNGER, OLDER); \ + } while (0) + + // Alignment is ignored in comparison (verified above), so CivilSecond is + // used to test comparison in all field positions. + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0), + absl::CivilSecond(2015, 1, 1, 0, 0, 0)); + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0), + absl::CivilSecond(2014, 2, 1, 0, 0, 0)); + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0), + absl::CivilSecond(2014, 1, 2, 0, 0, 0)); + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0), + absl::CivilSecond(2014, 1, 1, 1, 0, 0)); + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 1, 0, 0), + absl::CivilSecond(2014, 1, 1, 1, 1, 0)); + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 1, 1, 0), + absl::CivilSecond(2014, 1, 1, 1, 1, 1)); + + // Tests the relational operators of two different civil-time types. + TEST_RELATIONAL(absl::CivilDay(2014, 1, 1), + absl::CivilMinute(2014, 1, 1, 1, 1)); + TEST_RELATIONAL(absl::CivilDay(2014, 1, 1), + absl::CivilMonth(2014, 2)); + +#undef TEST_RELATIONAL +} + +TEST(CivilTime, Arithmetic) { + absl::CivilSecond second(2015, 1, 2, 3, 4, 5); + EXPECT_EQ("2015-01-02T03:04:06", absl::FormatCivilTime(second += 1)); + EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(second + 1)); + EXPECT_EQ("2015-01-02T03:04:08", absl::FormatCivilTime(2 + second)); + EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second - 1)); + EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second -= 1)); + EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second++)); + EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(++second)); + EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(second--)); + EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(--second)); + + absl::CivilMinute minute(2015, 1, 2, 3, 4); + EXPECT_EQ("2015-01-02T03:05", absl::FormatCivilTime(minute += 1)); + EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(minute + 1)); + EXPECT_EQ("2015-01-02T03:07", absl::FormatCivilTime(2 + minute)); + EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute - 1)); + EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute -= 1)); + EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute++)); + EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(++minute)); + EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(minute--)); + EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(--minute)); + + absl::CivilHour hour(2015, 1, 2, 3); + EXPECT_EQ("2015-01-02T04", absl::FormatCivilTime(hour += 1)); + EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(hour + 1)); + EXPECT_EQ("2015-01-02T06", absl::FormatCivilTime(2 + hour)); + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour - 1)); + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour -= 1)); + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour++)); + EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(++hour)); + EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(hour--)); + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(--hour)); + + absl::CivilDay day(2015, 1, 2); + EXPECT_EQ("2015-01-03", absl::FormatCivilTime(day += 1)); + EXPECT_EQ("2015-01-04", absl::FormatCivilTime(day + 1)); + EXPECT_EQ("2015-01-05", absl::FormatCivilTime(2 + day)); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day - 1)); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day -= 1)); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day++)); + EXPECT_EQ("2015-01-04", absl::FormatCivilTime(++day)); + EXPECT_EQ("2015-01-04", absl::FormatCivilTime(day--)); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(--day)); + + absl::CivilMonth month(2015, 1); + EXPECT_EQ("2015-02", absl::FormatCivilTime(month += 1)); + EXPECT_EQ("2015-03", absl::FormatCivilTime(month + 1)); + EXPECT_EQ("2015-04", absl::FormatCivilTime(2 + month)); + EXPECT_EQ("2015-01", absl::FormatCivilTime(month - 1)); + EXPECT_EQ("2015-01", absl::FormatCivilTime(month -= 1)); + EXPECT_EQ("2015-01", absl::FormatCivilTime(month++)); + EXPECT_EQ("2015-03", absl::FormatCivilTime(++month)); + EXPECT_EQ("2015-03", absl::FormatCivilTime(month--)); + EXPECT_EQ("2015-01", absl::FormatCivilTime(--month)); + + absl::CivilYear year(2015); + EXPECT_EQ("2016", absl::FormatCivilTime(year += 1)); + EXPECT_EQ("2017", absl::FormatCivilTime(year + 1)); + EXPECT_EQ("2018", absl::FormatCivilTime(2 + year)); + EXPECT_EQ("2015", absl::FormatCivilTime(year - 1)); + EXPECT_EQ("2015", absl::FormatCivilTime(year -= 1)); + EXPECT_EQ("2015", absl::FormatCivilTime(year++)); + EXPECT_EQ("2017", absl::FormatCivilTime(++year)); + EXPECT_EQ("2017", absl::FormatCivilTime(year--)); + EXPECT_EQ("2015", absl::FormatCivilTime(--year)); +} + +TEST(CivilTime, ArithmeticLimits) { + const int kIntMax = std::numeric_limits<int>::max(); + const int kIntMin = std::numeric_limits<int>::min(); + + absl::CivilSecond second(1970, 1, 1, 0, 0, 0); + second += kIntMax; + EXPECT_EQ("2038-01-19T03:14:07", absl::FormatCivilTime(second)); + second -= kIntMax; + EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(second)); + second += kIntMin; + EXPECT_EQ("1901-12-13T20:45:52", absl::FormatCivilTime(second)); + second -= kIntMin; + EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(second)); + + absl::CivilMinute minute(1970, 1, 1, 0, 0); + minute += kIntMax; + EXPECT_EQ("6053-01-23T02:07", absl::FormatCivilTime(minute)); + minute -= kIntMax; + EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(minute)); + minute += kIntMin; + EXPECT_EQ("-2114-12-08T21:52", absl::FormatCivilTime(minute)); + minute -= kIntMin; + EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(minute)); + + absl::CivilHour hour(1970, 1, 1, 0); + hour += kIntMax; + EXPECT_EQ("246953-10-09T07", absl::FormatCivilTime(hour)); + hour -= kIntMax; + EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hour)); + hour += kIntMin; + EXPECT_EQ("-243014-03-24T16", absl::FormatCivilTime(hour)); + hour -= kIntMin; + EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hour)); + + absl::CivilDay day(1970, 1, 1); + day += kIntMax; + EXPECT_EQ("5881580-07-11", absl::FormatCivilTime(day)); + day -= kIntMax; + EXPECT_EQ("1970-01-01", absl::FormatCivilTime(day)); + day += kIntMin; + EXPECT_EQ("-5877641-06-23", absl::FormatCivilTime(day)); + day -= kIntMin; + EXPECT_EQ("1970-01-01", absl::FormatCivilTime(day)); + + absl::CivilMonth month(1970, 1); + month += kIntMax; + EXPECT_EQ("178958940-08", absl::FormatCivilTime(month)); + month -= kIntMax; + EXPECT_EQ("1970-01", absl::FormatCivilTime(month)); + month += kIntMin; + EXPECT_EQ("-178955001-05", absl::FormatCivilTime(month)); + month -= kIntMin; + EXPECT_EQ("1970-01", absl::FormatCivilTime(month)); + + absl::CivilYear year(0); + year += kIntMax; + EXPECT_EQ("2147483647", absl::FormatCivilTime(year)); + year -= kIntMax; + EXPECT_EQ("0", absl::FormatCivilTime(year)); + year += kIntMin; + EXPECT_EQ("-2147483648", absl::FormatCivilTime(year)); + year -= kIntMin; + EXPECT_EQ("0", absl::FormatCivilTime(year)); +} + +TEST(CivilTime, Difference) { + absl::CivilSecond second(2015, 1, 2, 3, 4, 5); + EXPECT_EQ(0, second - second); + EXPECT_EQ(10, (second + 10) - second); + EXPECT_EQ(-10, (second - 10) - second); + + absl::CivilMinute minute(2015, 1, 2, 3, 4); + EXPECT_EQ(0, minute - minute); + EXPECT_EQ(10, (minute + 10) - minute); + EXPECT_EQ(-10, (minute - 10) - minute); + + absl::CivilHour hour(2015, 1, 2, 3); + EXPECT_EQ(0, hour - hour); + EXPECT_EQ(10, (hour + 10) - hour); + EXPECT_EQ(-10, (hour - 10) - hour); + + absl::CivilDay day(2015, 1, 2); + EXPECT_EQ(0, day - day); + EXPECT_EQ(10, (day + 10) - day); + EXPECT_EQ(-10, (day - 10) - day); + + absl::CivilMonth month(2015, 1); + EXPECT_EQ(0, month - month); + EXPECT_EQ(10, (month + 10) - month); + EXPECT_EQ(-10, (month - 10) - month); + + absl::CivilYear year(2015); + EXPECT_EQ(0, year - year); + EXPECT_EQ(10, (year + 10) - year); + EXPECT_EQ(-10, (year - 10) - year); +} + +TEST(CivilTime, DifferenceLimits) { + const absl::civil_diff_t kDiffMax = + std::numeric_limits<absl::civil_diff_t>::max(); + const absl::civil_diff_t kDiffMin = + std::numeric_limits<absl::civil_diff_t>::min(); + + // Check day arithmetic at the end of the year range. + const absl::CivilDay max_day(kDiffMax, 12, 31); + EXPECT_EQ(1, max_day - (max_day - 1)); + EXPECT_EQ(-1, (max_day - 1) - max_day); + + // Check day arithmetic at the start of the year range. + const absl::CivilDay min_day(kDiffMin, 1, 1); + EXPECT_EQ(1, (min_day + 1) - min_day); + EXPECT_EQ(-1, min_day - (min_day + 1)); + + // Check the limits of the return value. + const absl::CivilDay d1(1970, 1, 1); + const absl::CivilDay d2(25252734927768524, 7, 27); + EXPECT_EQ(kDiffMax, d2 - d1); + EXPECT_EQ(kDiffMin, d1 - (d2 + 1)); +} + +TEST(CivilTime, Properties) { + absl::CivilSecond ss(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, ss.year()); + EXPECT_EQ(2, ss.month()); + EXPECT_EQ(3, ss.day()); + EXPECT_EQ(4, ss.hour()); + EXPECT_EQ(5, ss.minute()); + EXPECT_EQ(6, ss.second()); + + absl::CivilMinute mm(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, mm.year()); + EXPECT_EQ(2, mm.month()); + EXPECT_EQ(3, mm.day()); + EXPECT_EQ(4, mm.hour()); + EXPECT_EQ(5, mm.minute()); + EXPECT_EQ(0, mm.second()); + + absl::CivilHour hh(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, hh.year()); + EXPECT_EQ(2, hh.month()); + EXPECT_EQ(3, hh.day()); + EXPECT_EQ(4, hh.hour()); + EXPECT_EQ(0, hh.minute()); + EXPECT_EQ(0, hh.second()); + + absl::CivilDay d(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, d.year()); + EXPECT_EQ(2, d.month()); + EXPECT_EQ(3, d.day()); + EXPECT_EQ(0, d.hour()); + EXPECT_EQ(0, d.minute()); + EXPECT_EQ(0, d.second()); + + absl::CivilMonth m(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, m.year()); + EXPECT_EQ(2, m.month()); + EXPECT_EQ(1, m.day()); + EXPECT_EQ(0, m.hour()); + EXPECT_EQ(0, m.minute()); + EXPECT_EQ(0, m.second()); + + absl::CivilYear y(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, y.year()); + EXPECT_EQ(1, y.month()); + EXPECT_EQ(1, y.day()); + EXPECT_EQ(0, y.hour()); + EXPECT_EQ(0, y.minute()); + EXPECT_EQ(0, y.second()); +} + +TEST(CivilTime, Format) { + absl::CivilSecond ss; + EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss)); + + absl::CivilMinute mm; + EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm)); + + absl::CivilHour hh; + EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh)); + + absl::CivilDay d; + EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d)); + + absl::CivilMonth m; + EXPECT_EQ("1970-01", absl::FormatCivilTime(m)); + + absl::CivilYear y; + EXPECT_EQ("1970", absl::FormatCivilTime(y)); +} + +TEST(CivilTime, FormatAndParseLenient) { + absl::CivilSecond ss; + EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss)); + + absl::CivilMinute mm; + EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm)); + + absl::CivilHour hh; + EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh)); + + absl::CivilDay d; + EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d)); + + absl::CivilMonth m; + EXPECT_EQ("1970-01", absl::FormatCivilTime(m)); + + absl::CivilYear y; + EXPECT_EQ("1970", absl::FormatCivilTime(y)); +} + +TEST(CivilTime, OutputStream) { + absl::CivilSecond cs(2016, 2, 3, 4, 5, 6); + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilYear(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016.................X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilMonth(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016-02..............X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilDay(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016-02-03...........X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilHour(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016-02-03T04........X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilMinute(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016-02-03T04:05.....X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilSecond(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016-02-03T04:05:06..X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::Weekday::wednesday; + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..Wednesday............X..", ss.str()); + } +} + +TEST(CivilTime, Weekday) { + absl::CivilDay d(1970, 1, 1); + EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(d)) << d; + + // We used to get this wrong for years < -30. + d = absl::CivilDay(-31, 12, 24); + EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(d)) << d; +} + +TEST(CivilTime, NextPrevWeekday) { + // Jan 1, 1970 was a Thursday. + const absl::CivilDay thursday(1970, 1, 1); + + // Thursday -> Thursday + absl::CivilDay d = absl::NextWeekday(thursday, absl::Weekday::thursday); + EXPECT_EQ(7, d - thursday) << d; + EXPECT_EQ(d - 14, absl::PrevWeekday(thursday, absl::Weekday::thursday)); + + // Thursday -> Friday + d = absl::NextWeekday(thursday, absl::Weekday::friday); + EXPECT_EQ(1, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::friday)); + + // Thursday -> Saturday + d = absl::NextWeekday(thursday, absl::Weekday::saturday); + EXPECT_EQ(2, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::saturday)); + + // Thursday -> Sunday + d = absl::NextWeekday(thursday, absl::Weekday::sunday); + EXPECT_EQ(3, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::sunday)); + + // Thursday -> Monday + d = absl::NextWeekday(thursday, absl::Weekday::monday); + EXPECT_EQ(4, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::monday)); + + // Thursday -> Tuesday + d = absl::NextWeekday(thursday, absl::Weekday::tuesday); + EXPECT_EQ(5, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::tuesday)); + + // Thursday -> Wednesday + d = absl::NextWeekday(thursday, absl::Weekday::wednesday); + EXPECT_EQ(6, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::wednesday)); +} + +// NOTE: Run this with --copt=-ftrapv to detect overflow problems. +TEST(CivilTime, DifferenceWithHugeYear) { + absl::CivilDay d1(9223372036854775807, 1, 1); + absl::CivilDay d2(9223372036854775807, 12, 31); + EXPECT_EQ(364, d2 - d1); + + d1 = absl::CivilDay(-9223372036854775807 - 1, 1, 1); + d2 = absl::CivilDay(-9223372036854775807 - 1, 12, 31); + EXPECT_EQ(365, d2 - d1); + + // Check the limits of the return value at the end of the year range. + d1 = absl::CivilDay(9223372036854775807, 1, 1); + d2 = absl::CivilDay(9198119301927009252, 6, 6); + EXPECT_EQ(9223372036854775807, d1 - d2); + d2 = d2 - 1; + EXPECT_EQ(-9223372036854775807 - 1, d2 - d1); + + // Check the limits of the return value at the start of the year range. + d1 = absl::CivilDay(-9223372036854775807 - 1, 1, 1); + d2 = absl::CivilDay(-9198119301927009254, 7, 28); + EXPECT_EQ(9223372036854775807, d2 - d1); + d2 = d2 + 1; + EXPECT_EQ(-9223372036854775807 - 1, d1 - d2); + + // Check the limits of the return value from either side of year 0. + d1 = absl::CivilDay(-12626367463883278, 9, 3); + d2 = absl::CivilDay(12626367463883277, 3, 28); + EXPECT_EQ(9223372036854775807, d2 - d1); + d2 = d2 + 1; + EXPECT_EQ(-9223372036854775807 - 1, d1 - d2); +} + +// NOTE: Run this with --copt=-ftrapv to detect overflow problems. +TEST(CivilTime, DifferenceNoIntermediateOverflow) { + // The difference up to the minute field would be below the minimum + // int64_t, but the 52 extra seconds brings us back to the minimum. + absl::CivilSecond s1(-292277022657, 1, 27, 8, 29 - 1, 52); + absl::CivilSecond s2(1970, 1, 1, 0, 0 - 1, 0); + EXPECT_EQ(-9223372036854775807 - 1, s1 - s2); + + // The difference up to the minute field would be above the maximum + // int64_t, but the -53 extra seconds brings us back to the maximum. + s1 = absl::CivilSecond(292277026596, 12, 4, 15, 30, 7 - 7); + s2 = absl::CivilSecond(1970, 1, 1, 0, 0, 0 - 7); + EXPECT_EQ(9223372036854775807, s1 - s2); +} + +TEST(CivilTime, NormalizeSimpleOverflow) { + absl::CivilSecond cs; + cs = absl::CivilSecond(2013, 11, 15, 16, 32, 59 + 1); + EXPECT_EQ("2013-11-15T16:33:00", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16, 59 + 1, 14); + EXPECT_EQ("2013-11-15T17:00:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 23 + 1, 32, 14); + EXPECT_EQ("2013-11-16T00:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 30 + 1, 16, 32, 14); + EXPECT_EQ("2013-12-01T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 12 + 1, 15, 16, 32, 14); + EXPECT_EQ("2014-01-15T16:32:14", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeSimpleUnderflow) { + absl::CivilSecond cs; + cs = absl::CivilSecond(2013, 11, 15, 16, 32, 0 - 1); + EXPECT_EQ("2013-11-15T16:31:59", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16, 0 - 1, 14); + EXPECT_EQ("2013-11-15T15:59:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 0 - 1, 32, 14); + EXPECT_EQ("2013-11-14T23:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 1 - 1, 16, 32, 14); + EXPECT_EQ("2013-10-31T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 1 - 1, 15, 16, 32, 14); + EXPECT_EQ("2012-12-15T16:32:14", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeMultipleOverflow) { + absl::CivilSecond cs(2013, 12, 31, 23, 59, 59 + 1); + EXPECT_EQ("2014-01-01T00:00:00", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeMultipleUnderflow) { + absl::CivilSecond cs(2014, 1, 1, 0, 0, 0 - 1); + EXPECT_EQ("2013-12-31T23:59:59", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeOverflowLimits) { + absl::CivilSecond cs; + + const int kintmax = std::numeric_limits<int>::max(); + cs = absl::CivilSecond(0, kintmax, kintmax, kintmax, kintmax, kintmax); + EXPECT_EQ("185085715-11-27T12:21:07", absl::FormatCivilTime(cs)); + + const int kintmin = std::numeric_limits<int>::min(); + cs = absl::CivilSecond(0, kintmin, kintmin, kintmin, kintmin, kintmin); + EXPECT_EQ("-185085717-10-31T10:37:52", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeComplexOverflow) { + absl::CivilSecond cs; + cs = absl::CivilSecond(2013, 11, 15, 16, 32, 14 + 123456789); + EXPECT_EQ("2017-10-14T14:05:23", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16, 32 + 1234567, 14); + EXPECT_EQ("2016-03-22T00:39:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16 + 123456, 32, 14); + EXPECT_EQ("2027-12-16T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15 + 1234, 16, 32, 14); + EXPECT_EQ("2017-04-02T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11 + 123, 15, 16, 32, 14); + EXPECT_EQ("2024-02-15T16:32:14", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeComplexUnderflow) { + absl::CivilSecond cs; + cs = absl::CivilSecond(1999, 3, 0, 0, 0, 0); // year 400 + EXPECT_EQ("1999-02-28T00:00:00", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16, 32, 14 - 123456789); + EXPECT_EQ("2009-12-17T18:59:05", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16, 32 - 1234567, 14); + EXPECT_EQ("2011-07-12T08:25:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16 - 123456, 32, 14); + EXPECT_EQ("1999-10-16T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15 - 1234, 16, 32, 14); + EXPECT_EQ("2010-06-30T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11 - 123, 15, 16, 32, 14); + EXPECT_EQ("2003-08-15T16:32:14", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeMishmash) { + absl::CivilSecond cs; + cs = absl::CivilSecond(2013, 11 - 123, 15 + 1234, 16 - 123456, 32 + 1234567, + 14 - 123456789); + EXPECT_EQ("1991-05-09T03:06:05", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11 + 123, 15 - 1234, 16 + 123456, 32 - 1234567, + 14 + 123456789); + EXPECT_EQ("2036-05-24T05:58:23", absl::FormatCivilTime(cs)); + + cs = absl::CivilSecond(2013, 11, -146097 + 1, 16, 32, 14); + EXPECT_EQ("1613-11-01T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11 + 400 * 12, -146097 + 1, 16, 32, 14); + EXPECT_EQ("2013-11-01T16:32:14", absl::FormatCivilTime(cs)); +} + +// Convert all the days from 1970-1-1 to 1970-1-146097 (aka 2369-12-31) +// and check that they normalize to the expected time. 146097 days span +// the 400-year Gregorian cycle used during normalization. +TEST(CivilTime, NormalizeAllTheDays) { + absl::CivilDay expected(1970, 1, 1); + for (int day = 1; day <= 146097; ++day) { + absl::CivilSecond cs(1970, 1, day, 0, 0, 0); + EXPECT_EQ(expected, cs); + ++expected; + } +} + +TEST(CivilTime, NormalizeWithHugeYear) { + absl::CivilMonth c(9223372036854775807, 1); + EXPECT_EQ("9223372036854775807-01", absl::FormatCivilTime(c)); + c = c - 1; // Causes normalization + EXPECT_EQ("9223372036854775806-12", absl::FormatCivilTime(c)); + + c = absl::CivilMonth(-9223372036854775807 - 1, 1); + EXPECT_EQ("-9223372036854775808-01", absl::FormatCivilTime(c)); + c = c + 12; // Causes normalization + EXPECT_EQ("-9223372036854775807-01", absl::FormatCivilTime(c)); +} + +TEST(CivilTime, LeapYears) { + const absl::CivilSecond s1(2013, 2, 28 + 1, 0, 0, 0); + EXPECT_EQ("2013-03-01T00:00:00", absl::FormatCivilTime(s1)); + + const absl::CivilSecond s2(2012, 2, 28 + 1, 0, 0, 0); + EXPECT_EQ("2012-02-29T00:00:00", absl::FormatCivilTime(s2)); + + const absl::CivilSecond s3(1900, 2, 28 + 1, 0, 0, 0); + EXPECT_EQ("1900-03-01T00:00:00", absl::FormatCivilTime(s3)); + + const struct { + int year; + int days; + struct { + int month; + int day; + } leap_day; // The date of the day after Feb 28. + } kLeapYearTable[]{ + {1900, 365, {3, 1}}, + {1999, 365, {3, 1}}, + {2000, 366, {2, 29}}, // leap year + {2001, 365, {3, 1}}, + {2002, 365, {3, 1}}, + {2003, 365, {3, 1}}, + {2004, 366, {2, 29}}, // leap year + {2005, 365, {3, 1}}, + {2006, 365, {3, 1}}, + {2007, 365, {3, 1}}, + {2008, 366, {2, 29}}, // leap year + {2009, 365, {3, 1}}, + {2100, 365, {3, 1}}, + }; + + for (int i = 0; i < ABSL_ARRAYSIZE(kLeapYearTable); ++i) { + const int y = kLeapYearTable[i].year; + const int m = kLeapYearTable[i].leap_day.month; + const int d = kLeapYearTable[i].leap_day.day; + const int n = kLeapYearTable[i].days; + + // Tests incrementing through the leap day. + const absl::CivilDay feb28(y, 2, 28); + const absl::CivilDay next_day = feb28 + 1; + EXPECT_EQ(m, next_day.month()); + EXPECT_EQ(d, next_day.day()); + + // Tests difference in days of leap years. + const absl::CivilYear year(feb28); + const absl::CivilYear next_year = year + 1; + EXPECT_EQ(n, absl::CivilDay(next_year) - absl::CivilDay(year)); + } +} + +TEST(CivilTime, FirstThursdayInMonth) { + const absl::CivilDay nov1(2014, 11, 1); + const absl::CivilDay thursday = + absl::PrevWeekday(nov1, absl::Weekday::thursday) + 7; + EXPECT_EQ("2014-11-06", absl::FormatCivilTime(thursday)); + + // Bonus: Date of Thanksgiving in the United States + // Rule: Fourth Thursday of November + const absl::CivilDay thanksgiving = thursday + 7 * 3; + EXPECT_EQ("2014-11-27", absl::FormatCivilTime(thanksgiving)); +} + +TEST(CivilTime, DocumentationExample) { + absl::CivilSecond second(2015, 6, 28, 1, 2, 3); // 2015-06-28 01:02:03 + absl::CivilMinute minute(second); // 2015-06-28 01:02:00 + absl::CivilDay day(minute); // 2015-06-28 00:00:00 + + second -= 1; // 2015-06-28 01:02:02 + --second; // 2015-06-28 01:02:01 + EXPECT_EQ(minute, second - 1); // Comparison between types + EXPECT_LT(minute, second); + + // int diff = second - minute; // ERROR: Mixed types, won't compile + + absl::CivilDay june_1(2015, 6, 1); // Pass fields to c'tor. + int diff = day - june_1; // Num days between 'day' and June 1 + EXPECT_EQ(27, diff); + + // Fields smaller than alignment are floored to their minimum value. + absl::CivilDay day_floor(2015, 1, 2, 9, 9, 9); + EXPECT_EQ(0, day_floor.hour()); // 09:09:09 is floored + EXPECT_EQ(absl::CivilDay(2015, 1, 2), day_floor); + + // Unspecified fields default to their minium value + absl::CivilDay day_default(2015); // Defaults to Jan 1 + EXPECT_EQ(absl::CivilDay(2015, 1, 1), day_default); + + // Iterates all the days of June. + absl::CivilMonth june(day); // CivilDay -> CivilMonth + absl::CivilMonth july = june + 1; + for (absl::CivilDay day = june_1; day < july; ++day) { + // ... + } +} + +} // namespace
diff --git a/absl/time/duration.cc b/absl/time/duration.cc index 2950c7c..b77d5ec 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc
@@ -78,10 +78,16 @@ // Can't use std::isinfinite() because it doesn't exist on windows. inline bool IsFinite(double d) { + if (std::isnan(d)) return false; return d != std::numeric_limits<double>::infinity() && d != -std::numeric_limits<double>::infinity(); } +inline bool IsValidDivisor(double d) { + if (std::isnan(d)) return false; + return d != 0.0; +} + // Can't use std::round() because it is only available in C++11. // Note that we ignore the possibility of floating-point over/underflow. template <typename Double> @@ -455,7 +461,7 @@ } Duration& Duration::operator/=(double r) { - if (time_internal::IsInfiniteDuration(*this) || r == 0.0) { + if (time_internal::IsInfiniteDuration(*this) || !IsValidDivisor(r)) { const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0); return *this = is_neg ? -InfiniteDuration() : InfiniteDuration(); }
diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc index 7ae25dc..61f3c5c 100644 --- a/absl/time/duration_test.cc +++ b/absl/time/duration_test.cc
@@ -56,6 +56,17 @@ return false; } +TEST(Duration, ConstExpr) { + constexpr absl::Duration d0 = absl::ZeroDuration(); + static_assert(d0 == absl::ZeroDuration(), "ZeroDuration()"); + constexpr absl::Duration d1 = absl::Seconds(1); + static_assert(d1 == absl::Seconds(1), "Seconds(1)"); + static_assert(d1 != absl::ZeroDuration(), "Seconds(1)"); + constexpr absl::Duration d2 = absl::InfiniteDuration(); + static_assert(d2 == absl::InfiniteDuration(), "InfiniteDuration()"); + static_assert(d2 != absl::ZeroDuration(), "InfiniteDuration()"); +} + TEST(Duration, ValueSemantics) { // If this compiles, the test passes. constexpr absl::Duration a; // Default construction @@ -792,6 +803,40 @@ EXPECT_EQ(-dbl_inf, absl::FDivDuration(-any_dur, zero)); } +TEST(Duration, NaN) { + // Note that IEEE 754 does not define the behavior of a nan's sign when it is + // copied, so the code below allows for either + or - InfiniteDuration. +#define TEST_NAN_HANDLING(NAME, NAN) \ + do { \ + const auto inf = absl::InfiniteDuration(); \ + auto x = NAME(NAN); \ + EXPECT_TRUE(x == inf || x == -inf); \ + auto y = NAME(42); \ + y *= NAN; \ + EXPECT_TRUE(y == inf || y == -inf); \ + auto z = NAME(42); \ + z /= NAN; \ + EXPECT_TRUE(z == inf || z == -inf); \ + } while (0) + + const double nan = std::numeric_limits<double>::quiet_NaN(); + TEST_NAN_HANDLING(absl::Nanoseconds, nan); + TEST_NAN_HANDLING(absl::Microseconds, nan); + TEST_NAN_HANDLING(absl::Milliseconds, nan); + TEST_NAN_HANDLING(absl::Seconds, nan); + TEST_NAN_HANDLING(absl::Minutes, nan); + TEST_NAN_HANDLING(absl::Hours, nan); + + TEST_NAN_HANDLING(absl::Nanoseconds, -nan); + TEST_NAN_HANDLING(absl::Microseconds, -nan); + TEST_NAN_HANDLING(absl::Milliseconds, -nan); + TEST_NAN_HANDLING(absl::Seconds, -nan); + TEST_NAN_HANDLING(absl::Minutes, -nan); + TEST_NAN_HANDLING(absl::Hours, -nan); + +#undef TEST_NAN_HANDLING +} + TEST(Duration, Range) { const absl::Duration range = ApproxYears(100 * 1e9); const absl::Duration range_future = range;
diff --git a/absl/time/format_benchmark.cc b/absl/time/format_benchmark.cc index ee53d71..766f1b3 100644 --- a/absl/time/format_benchmark.cc +++ b/absl/time/format_benchmark.cc
@@ -38,7 +38,8 @@ const absl::TimeZone lax = absl::time_internal::LoadTimeZone("America/Los_Angeles"); const absl::Time t = - absl::FromDateTime(1977, 6, 28, 9, 8, 7, lax) + absl::Nanoseconds(1); + absl::FromCivil(absl::CivilSecond(1977, 6, 28, 9, 8, 7), lax) + + absl::Nanoseconds(1); while (state.KeepRunning()) { benchmark::DoNotOptimize(absl::FormatTime(fmt, t, lax).length()); } @@ -50,8 +51,8 @@ state.SetLabel(fmt); const absl::TimeZone lax = absl::time_internal::LoadTimeZone("America/Los_Angeles"); - absl::Time t = - absl::FromDateTime(1977, 6, 28, 9, 8, 7, lax) + absl::Nanoseconds(1); + absl::Time t = absl::FromCivil(absl::CivilSecond(1977, 6, 28, 9, 8, 7), lax) + + absl::Nanoseconds(1); const std::string when = absl::FormatTime(fmt, t, lax); std::string err; while (state.KeepRunning()) {
diff --git a/absl/time/format_test.cc b/absl/time/format_test.cc index 7c84c33..ac8d5ea 100644 --- a/absl/time/format_test.cc +++ b/absl/time/format_test.cc
@@ -118,7 +118,7 @@ absl::TimeZone tz = absl::UTCTimeZone(); // A year of 77 should be padded to 0077. - absl::Time t = absl::FromDateTime(77, 6, 28, 9, 8, 7, tz); + absl::Time t = absl::FromCivil(absl::CivilSecond(77, 6, 28, 9, 8, 7), tz); EXPECT_EQ("Mon, 28 Jun 0077 09:08:07 +0000", absl::FormatTime(absl::RFC1123_full, t, tz)); EXPECT_EQ("28 Jun 0077 09:08:07 +0000", @@ -154,9 +154,9 @@ EXPECT_TRUE(absl::ParseTime("%Y-%m-%d %H:%M:%S %z", "2013-06-28 19:08:09 -0800", &t, &err)) << err; - absl::Time::Breakdown bd = t.In(absl::FixedTimeZone(-8 * 60 * 60)); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 6, 28, 19, 8, 9, -8 * 60 * 60, false); - EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); + const auto ci = absl::FixedTimeZone(-8 * 60 * 60).At(t); + EXPECT_EQ(absl::CivilSecond(2013, 6, 28, 19, 8, 9), ci.cs); + EXPECT_EQ(absl::ZeroDuration(), ci.subsecond); } TEST(ParseTime, NullErrorString) { @@ -177,17 +177,17 @@ EXPECT_TRUE( absl::ParseTime("%Y-%m-%d %H:%M:%S", "2013-06-28 19:08:09", tz, &t, &e)) << e; - absl::Time::Breakdown bd = t.In(tz); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 6, 28, 19, 8, 9, -7 * 60 * 60, true); - EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); + auto ci = tz.At(t); + EXPECT_EQ(absl::CivilSecond(2013, 6, 28, 19, 8, 9), ci.cs); + EXPECT_EQ(absl::ZeroDuration(), ci.subsecond); // But the timezone is ignored when a UTC offset is present. EXPECT_TRUE(absl::ParseTime("%Y-%m-%d %H:%M:%S %z", "2013-06-28 19:08:09 +0800", tz, &t, &e)) << e; - bd = t.In(absl::FixedTimeZone(8 * 60 * 60)); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 6, 28, 19, 8, 9, 8 * 60 * 60, false); - EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); + ci = absl::FixedTimeZone(8 * 60 * 60).At(t); + EXPECT_EQ(absl::CivilSecond(2013, 6, 28, 19, 8, 9), ci.cs); + EXPECT_EQ(absl::ZeroDuration(), ci.subsecond); } TEST(ParseTime, ErrorCases) { @@ -332,15 +332,15 @@ EXPECT_TRUE(absl::ParseTime("infinite-future %H:%M", "infinite-future 03:04", &t, &err)); EXPECT_NE(absl::InfiniteFuture(), t); - EXPECT_EQ(3, t.In(tz).hour); - EXPECT_EQ(4, t.In(tz).minute); + EXPECT_EQ(3, tz.At(t).cs.hour()); + EXPECT_EQ(4, tz.At(t).cs.minute()); // "infinite-past" as literal std::string EXPECT_TRUE( absl::ParseTime("infinite-past %H:%M", "infinite-past 03:04", &t, &err)); EXPECT_NE(absl::InfinitePast(), t); - EXPECT_EQ(3, t.In(tz).hour); - EXPECT_EQ(4, t.In(tz).minute); + EXPECT_EQ(3, tz.At(t).cs.hour()); + EXPECT_EQ(4, tz.At(t).cs.minute()); // The input doesn't match the format. EXPECT_FALSE(absl::ParseTime("infinite-future %H:%M", "03:04", &t, &err)); @@ -365,16 +365,17 @@ // TEST(FormatParse, RoundTrip) { - const absl::TimeZone gst = + const absl::TimeZone lax = absl::time_internal::LoadTimeZone("America/Los_Angeles"); - const absl::Time in = absl::FromDateTime(1977, 6, 28, 9, 8, 7, gst); + const absl::Time in = + absl::FromCivil(absl::CivilSecond(1977, 6, 28, 9, 8, 7), lax); const absl::Duration subseconds = absl::Nanoseconds(654321); std::string err; // RFC3339, which renders subseconds. { absl::Time out; - const std::string s = absl::FormatTime(absl::RFC3339_full, in + subseconds, gst); + const std::string s = absl::FormatTime(absl::RFC3339_full, in + subseconds, lax); EXPECT_TRUE(absl::ParseTime(absl::RFC3339_full, s, &out, &err)) << s << ": " << err; EXPECT_EQ(in + subseconds, out); // RFC3339_full includes %Ez @@ -383,7 +384,7 @@ // RFC1123, which only does whole seconds. { absl::Time out; - const std::string s = absl::FormatTime(absl::RFC1123_full, in, gst); + const std::string s = absl::FormatTime(absl::RFC1123_full, in, lax); EXPECT_TRUE(absl::ParseTime(absl::RFC1123_full, s, &out, &err)) << s << ": " << err; EXPECT_EQ(in, out); // RFC1123_full includes %z @@ -393,7 +394,12 @@ // work. On Windows, `absl::ParseTime()` falls back to std::get_time() which // appears to fail on "%c" (or at least on the "%c" text produced by // `strftime()`). This makes it fail the round-trip test. -#ifndef _MSC_VER + // + // Under the emscripten compiler `absl::ParseTime() falls back to + // `strptime()`, but that ends up using a different definition for "%c" + // compared to `strftime()`, also causing the round-trip test to fail + // (see https://github.com/kripken/emscripten/pull/7491). +#if !defined(_MSC_VER) && !defined(__EMSCRIPTEN__) // Even though we don't know what %c will produce, it should roundtrip, // but only in the 0-offset timezone. { @@ -402,7 +408,7 @@ EXPECT_TRUE(absl::ParseTime("%c", s, &out, &err)) << s << ": " << err; EXPECT_EQ(in, out); } -#endif // _MSC_VER +#endif // !_MSC_VER && !__EMSCRIPTEN__ } TEST(FormatParse, RoundTripDistantFuture) {
diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel index 9f1ba21..e2cfe80 100644 --- a/absl/time/internal/cctz/BUILD.bazel +++ b/absl/time/internal/cctz/BUILD.bazel
@@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +package(features = ["-parse_headers"]) + licenses(["notice"]) # Apache License ### libraries @@ -102,6 +104,7 @@ "no_test_android_arm", "no_test_android_arm64", "no_test_android_x86", + "no_test_wasm", ], deps = [ ":civil_time",
diff --git a/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/absl/time/internal/cctz/include/cctz/civil_time_detail.h index d7f7271..1c5d097 100644 --- a/absl/time/internal/cctz/include/cctz/civil_time_detail.h +++ b/absl/time/internal/cctz/include/cctz/civil_time_detail.h
@@ -326,6 +326,37 @@ //////////////////////////////////////////////////////////////////////// +namespace impl { + +template <typename H> +H AbslHashValueImpl(second_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm, f.ss); +} +template <typename H> +H AbslHashValueImpl(minute_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm); +} +template <typename H> +H AbslHashValueImpl(hour_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d, f.hh); +} +template <typename H> +H AbslHashValueImpl(day_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d); +} +template <typename H> +H AbslHashValueImpl(month_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m); +} +template <typename H> +H AbslHashValueImpl(year_tag, H h, fields f) { + return H::combine(std::move(h), f.y); +} + +} // namespace impl + +//////////////////////////////////////////////////////////////////////// + template <typename T> class civil_time { public: @@ -355,12 +386,12 @@ : civil_time(ct.f_) {} // Factories for the maximum/minimum representable civil_time. - static CONSTEXPR_F civil_time max() { - const auto max_year = std::numeric_limits<std::int_least64_t>::max(); + static CONSTEXPR_F civil_time (max)() { + const auto max_year = (std::numeric_limits<std::int_least64_t>::max)(); return civil_time(max_year, 12, 31, 23, 59, 59); } - static CONSTEXPR_F civil_time min() { - const auto min_year = std::numeric_limits<std::int_least64_t>::min(); + static CONSTEXPR_F civil_time (min)() { + const auto min_year = (std::numeric_limits<std::int_least64_t>::min)(); return civil_time(min_year, 1, 1, 0, 0, 0); } @@ -378,7 +409,7 @@ return *this; } CONSTEXPR_M civil_time& operator-=(diff_t n) noexcept { - if (n != std::numeric_limits<diff_t>::min()) { + if (n != (std::numeric_limits<diff_t>::min)()) { f_ = step(T{}, f_, -n); } else { f_ = step(T{}, step(T{}, f_, -(n + 1)), 1); @@ -418,8 +449,7 @@ template <typename H> friend H AbslHashValue(H h, civil_time a) { - return H::combine(std::move(h), a.f_.y, a.f_.m, a.f_.d, - a.f_.hh, a.f_.mm, a.f_.ss); + return impl::AbslHashValueImpl(T{}, std::move(h), a.f_); } private: @@ -506,9 +536,11 @@ }; CONSTEXPR_F weekday get_weekday(const civil_day& cd) noexcept { - CONSTEXPR_D weekday k_weekday_by_sun_off[7] = { - weekday::sunday, weekday::monday, weekday::tuesday, - weekday::wednesday, weekday::thursday, weekday::friday, + CONSTEXPR_D weekday k_weekday_by_mon_off[13] = { + weekday::monday, weekday::tuesday, weekday::wednesday, + weekday::thursday, weekday::friday, weekday::saturday, + weekday::sunday, weekday::monday, weekday::tuesday, + weekday::wednesday, weekday::thursday, weekday::friday, weekday::saturday, }; CONSTEXPR_D int k_weekday_offsets[1 + 12] = { @@ -517,7 +549,7 @@ year_t wd = 2400 + (cd.year() % 400) - (cd.month() < 3); wd += wd / 4 - wd / 100 + wd / 400; wd += k_weekday_offsets[cd.month()] + cd.day(); - return k_weekday_by_sun_off[(wd % 7 + 7) % 7]; + return k_weekday_by_mon_off[wd % 7 + 6]; } ////////////////////////////////////////////////////////////////////////
diff --git a/absl/time/internal/cctz/src/time_zone_libc.cc b/absl/time/internal/cctz/src/time_zone_libc.cc index 074c8d0..6db519e 100644 --- a/absl/time/internal/cctz/src/time_zone_libc.cc +++ b/absl/time/internal/cctz/src/time_zone_libc.cc
@@ -20,6 +20,7 @@ #include <chrono> #include <ctime> +#include <limits> #include <tuple> #include <utility> @@ -85,6 +86,76 @@ #endif // !defined(__tm_gmtoff) && !defined(__tm_zone) #endif +inline std::tm* gm_time(const std::time_t *timep, std::tm *result) { +#if defined(_WIN32) || defined(_WIN64) + return gmtime_s(result, timep) ? nullptr : result; +#else + return gmtime_r(timep, result); +#endif +} + +inline std::tm* local_time(const std::time_t *timep, std::tm *result) { +#if defined(_WIN32) || defined(_WIN64) + return localtime_s(result, timep) ? nullptr : result; +#else + return localtime_r(timep, result); +#endif +} + +// Converts a civil second and "dst" flag into a time_t and UTC offset. +// Returns false if time_t cannot represent the requested civil second. +// Caller must have already checked that cs.year() will fit into a tm_year. +bool make_time(const civil_second& cs, int is_dst, std::time_t* t, int* off) { + std::tm tm; + tm.tm_year = static_cast<int>(cs.year() - year_t{1900}); + tm.tm_mon = cs.month() - 1; + tm.tm_mday = cs.day(); + tm.tm_hour = cs.hour(); + tm.tm_min = cs.minute(); + tm.tm_sec = cs.second(); + tm.tm_isdst = is_dst; + *t = std::mktime(&tm); + if (*t == std::time_t{-1}) { + std::tm tm2; + const std::tm* tmp = local_time(t, &tm2); + if (tmp == nullptr || tmp->tm_year != tm.tm_year || + tmp->tm_mon != tm.tm_mon || tmp->tm_mday != tm.tm_mday || + tmp->tm_hour != tm.tm_hour || tmp->tm_min != tm.tm_min || + tmp->tm_sec != tm.tm_sec) { + // A true error (not just one second before the epoch). + return false; + } + } + *off = get_offset_abbr(tm).first; + return true; +} + +// Find the least time_t in [lo:hi] where local time matches offset, given: +// (1) lo doesn't match, (2) hi does, and (3) there is only one transition. +std::time_t find_trans(std::time_t lo, std::time_t hi, int offset) { + std::tm tm; + while (lo + 1 != hi) { + const std::time_t mid = lo + (hi - lo) / 2; + if (std::tm* tmp = local_time(&mid, &tm)) { + if (get_offset_abbr(*tmp).first == offset) { + hi = mid; + } else { + lo = mid; + } + } else { + // If std::tm cannot hold some result we resort to a linear search, + // ignoring all failed conversions. Slow, but never really happens. + while (++lo != hi) { + if (std::tm* tmp = local_time(&lo, &tm)) { + if (get_offset_abbr(*tmp).first == offset) break; + } + } + return lo; + } + } + return hi; +} + } // namespace TimeZoneLibC::TimeZoneLibC(const std::string& name) @@ -93,50 +164,107 @@ time_zone::absolute_lookup TimeZoneLibC::BreakTime( const time_point<seconds>& tp) const { time_zone::absolute_lookup al; - std::time_t t = ToUnixSeconds(tp); - std::tm tm; - if (local_) { -#if defined(_WIN32) || defined(_WIN64) - localtime_s(&tm, &t); -#else - localtime_r(&t, &tm); -#endif - std::tie(al.offset, al.abbr) = get_offset_abbr(tm); - } else { -#if defined(_WIN32) || defined(_WIN64) - gmtime_s(&tm, &t); -#else - gmtime_r(&t, &tm); -#endif - al.offset = 0; - al.abbr = "UTC"; + al.offset = 0; + al.is_dst = false; + al.abbr = "-00"; + + const std::int_fast64_t s = ToUnixSeconds(tp); + + // If std::time_t cannot hold the input we saturate the output. + if (s < std::numeric_limits<std::time_t>::min()) { + al.cs = civil_second::min(); + return al; } - al.cs = civil_second(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); - al.is_dst = tm.tm_isdst > 0; + if (s > std::numeric_limits<std::time_t>::max()) { + al.cs = civil_second::max(); + return al; + } + + const std::time_t t = static_cast<std::time_t>(s); + std::tm tm; + std::tm* tmp = local_ ? local_time(&t, &tm) : gm_time(&t, &tm); + + // If std::tm cannot hold the result we saturate the output. + if (tmp == nullptr) { + al.cs = (s < 0) ? civil_second::min() : civil_second::max(); + return al; + } + + const year_t year = tmp->tm_year + year_t{1900}; + al.cs = civil_second(year, tmp->tm_mon + 1, tmp->tm_mday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + std::tie(al.offset, al.abbr) = get_offset_abbr(*tmp); + if (!local_) al.abbr = "UTC"; // as expected by cctz + al.is_dst = tmp->tm_isdst > 0; return al; } time_zone::civil_lookup TimeZoneLibC::MakeTime(const civil_second& cs) const { - time_zone::civil_lookup cl; - std::time_t t; - if (local_) { - // Does not handle SKIPPED/AMBIGUOUS or huge years. - std::tm tm; - tm.tm_year = static_cast<int>(cs.year() - 1900); - tm.tm_mon = cs.month() - 1; - tm.tm_mday = cs.day(); - tm.tm_hour = cs.hour(); - tm.tm_min = cs.minute(); - tm.tm_sec = cs.second(); - tm.tm_isdst = -1; - t = std::mktime(&tm); - } else { - t = cs - civil_second(); + if (!local_) { + // If time_point<seconds> cannot hold the result we saturate. + static const civil_second min_tp_cs = + civil_second() + ToUnixSeconds(time_point<seconds>::min()); + static const civil_second max_tp_cs = + civil_second() + ToUnixSeconds(time_point<seconds>::max()); + const time_point<seconds> tp = + (cs < min_tp_cs) + ? time_point<seconds>::min() + : (cs > max_tp_cs) ? time_point<seconds>::max() + : FromUnixSeconds(cs - civil_second()); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; } - cl.kind = time_zone::civil_lookup::UNIQUE; - cl.pre = cl.trans = cl.post = FromUnixSeconds(t); - return cl; + + // If tm_year cannot hold the requested year we saturate the result. + if (cs.year() < 0) { + if (cs.year() < std::numeric_limits<int>::min() + year_t{1900}) { + const time_point<seconds> tp = time_point<seconds>::min(); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + } + } else { + if (cs.year() - year_t{1900} > std::numeric_limits<int>::max()) { + const time_point<seconds> tp = time_point<seconds>::max(); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + } + } + + // We probe with "is_dst" values of 0 and 1 to try to distinguish unique + // civil seconds from skipped or repeated ones. This is not always possible + // however, as the "dst" flag does not change over some offset transitions. + // We are also subject to the vagaries of mktime() implementations. + std::time_t t0, t1; + int offset0, offset1; + if (make_time(cs, 0, &t0, &offset0) && make_time(cs, 1, &t1, &offset1)) { + if (t0 == t1) { + // The civil time was singular (pre == trans == post). + const time_point<seconds> tp = FromUnixSeconds(t0); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + } + + if (t0 > t1) { + std::swap(t0, t1); + std::swap(offset0, offset1); + } + const std::time_t tt = find_trans(t0, t1, offset1); + const time_point<seconds> trans = FromUnixSeconds(tt); + + if (offset0 < offset1) { + // The civil time did not exist (pre >= trans > post). + const time_point<seconds> pre = FromUnixSeconds(t1); + const time_point<seconds> post = FromUnixSeconds(t0); + return {time_zone::civil_lookup::SKIPPED, pre, trans, post}; + } + + // The civil time was ambiguous (pre < trans <= post). + const time_point<seconds> pre = FromUnixSeconds(t0); + const time_point<seconds> post = FromUnixSeconds(t1); + return {time_zone::civil_lookup::REPEATED, pre, trans, post}; + } + + // make_time() failed somehow so we saturate the result. + const time_point<seconds> tp = (cs < civil_second()) + ? time_point<seconds>::min() + : time_point<seconds>::max(); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; } bool TimeZoneLibC::NextTransition(const time_point<seconds>& tp,
diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc index 551292f..e84b946 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
@@ -16,7 +16,9 @@ #include <chrono> #include <cstddef> +#include <cstdlib> #include <future> +#include <limits> #include <string> #include <thread> #include <vector> @@ -925,7 +927,7 @@ EXPECT_EQ(tp, convert(civil_second(2009, 2, 13, 18, 30, 90), tz)); // second } -// NOTE: Run this with --copt=-ftrapv to detect overflow problems. +// NOTE: Run this with -ftrapv to detect overflow problems. TEST(MakeTime, SysSecondsLimits) { const char RFC3339[] = "%Y-%m-%dT%H:%M:%S%Ez"; const time_zone utc = utc_time_zone(); @@ -990,6 +992,106 @@ EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); tp = convert(civil_second::min(), west); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); + + // Some similar checks for the "libc" time-zone implementation. + if (sizeof(std::time_t) >= 8) { + // Checks that "tm_year + 1900", as used by the "libc" implementation, + // can produce year values beyond the range on an int without overflow. +#if defined(_WIN32) || defined(_WIN64) + // localtime_s() and gmtime_s() don't believe in years outside [1970:3000]. +#else + const time_zone utc = LoadZone("libc:UTC"); + const year_t max_tm_year = year_t{std::numeric_limits<int>::max()} + 1900; + tp = convert(civil_second(max_tm_year, 12, 31, 23, 59, 59), utc); + EXPECT_EQ("2147485547-12-31T23:59:59+00:00", format(RFC3339, tp, utc)); + const year_t min_tm_year = year_t{std::numeric_limits<int>::min()} + 1900; + tp = convert(civil_second(min_tm_year, 1, 1, 0, 0, 0), utc); + EXPECT_EQ("-2147481748-01-01T00:00:00+00:00", format(RFC3339, tp, utc)); +#endif + } +} + +TEST(MakeTime, LocalTimeLibC) { + // Checks that cctz and libc agree on transition points in [1970:2037]. + // + // We limit this test case to environments where: + // 1) we know how to change the time zone used by localtime()/mktime(), + // 2) cctz and localtime()/mktime() will use similar-enough tzdata, and + // 3) we have some idea about how mktime() behaves during transitions. +#if defined(__linux__) + const char* const ep = getenv("TZ"); + std::string tz_name = (ep != nullptr) ? ep : ""; + for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) { + ASSERT_EQ(0, setenv("TZ", *np, 1)); // change what "localtime" means + const auto zi = local_time_zone(); + const auto lc = LoadZone("libc:localtime"); + time_zone::civil_transition trans; + for (auto tp = zi.lookup(civil_second()).trans; + zi.next_transition(tp, &trans); + tp = zi.lookup(trans.to).trans) { + const auto fcl = zi.lookup(trans.from); + const auto tcl = zi.lookup(trans.to); + civil_second cs; // compare cs in zi and lc + if (fcl.kind == time_zone::civil_lookup::UNIQUE) { + if (tcl.kind == time_zone::civil_lookup::UNIQUE) { + // Both unique; must be an is_dst or abbr change. + ASSERT_EQ(trans.from, trans.to); + const auto trans = fcl.trans; + const auto tal = zi.lookup(trans); + const auto tprev = trans - absl::time_internal::cctz::seconds(1); + const auto pal = zi.lookup(tprev); + if (pal.is_dst == tal.is_dst) { + ASSERT_STRNE(pal.abbr, tal.abbr); + } + continue; + } + ASSERT_EQ(time_zone::civil_lookup::REPEATED, tcl.kind); + cs = trans.to; + } else { + ASSERT_EQ(time_zone::civil_lookup::UNIQUE, tcl.kind); + ASSERT_EQ(time_zone::civil_lookup::SKIPPED, fcl.kind); + cs = trans.from; + } + if (cs.year() > 2037) break; // limit test time (and to 32-bit time_t) + const auto cl_zi = zi.lookup(cs); + if (zi.lookup(cl_zi.pre).is_dst == zi.lookup(cl_zi.post).is_dst) { + // The "libc" implementation cannot correctly classify transitions + // that don't change the "tm_isdst" flag. In Europe/Volgograd, for + // example, there is a SKIPPED transition from +03 to +04 with dst=F + // on both sides ... + // 1540681199 = 2018-10-28 01:59:59 +03:00:00 [dst=F off=10800] + // 1540681200 = 2018-10-28 03:00:00 +04:00:00 [dst=F off=14400] + // but std::mktime(2018-10-28 02:00:00, tm_isdst=0) fails, unlike, + // say, the similar Europe/Chisinau transition from +02 to +03 ... + // 1521935999 = 2018-03-25 01:59:59 +02:00:00 [dst=F off=7200] + // 1521936000 = 2018-03-25 03:00:00 +03:00:00 [dst=T off=10800] + // where std::mktime(2018-03-25 02:00:00, tm_isdst=0) succeeds and + // returns 1521936000. + continue; + } + if (cs == civil_second(2037, 10, 4, 2, 0, 0)) { + const std::string tzname = *np; + if (tzname == "Africa/Casablanca" || tzname == "Africa/El_Aaiun") { + // The "libc" implementation gets this transition wrong (at least + // until 2018g when it was removed), returning an offset of 3600 + // instead of 0. TODO: Revert this when 2018g is ubiquitous. + continue; + } + } + const auto cl_lc = lc.lookup(cs); + SCOPED_TRACE(testing::Message() << "For " << cs << " in " << *np); + EXPECT_EQ(cl_zi.kind, cl_lc.kind); + EXPECT_EQ(cl_zi.pre, cl_lc.pre); + EXPECT_EQ(cl_zi.trans, cl_lc.trans); + EXPECT_EQ(cl_zi.post, cl_lc.post); + } + } + if (ep == nullptr) { + ASSERT_EQ(0, unsetenv("TZ")); + } else { + ASSERT_EQ(0, setenv("TZ", tz_name.c_str(), 1)); + } +#endif } TEST(NextTransition, UTC) {
diff --git a/absl/time/internal/cctz/src/time_zone_posix.h b/absl/time/internal/cctz/src/time_zone_posix.h index 9ccd4a8..ef2a8c1 100644 --- a/absl/time/internal/cctz/src/time_zone_posix.h +++ b/absl/time/internal/cctz/src/time_zone_posix.h
@@ -68,25 +68,35 @@ // it would take us to another day, and perhaps week, or even month. struct PosixTransition { enum DateFormat { J, N, M }; - struct { - DateFormat fmt; - union { - struct { - std::int_fast16_t day; // day of non-leap year [1:365] - } j; - struct { - std::int_fast16_t day; // day of year [0:365] - } n; - struct { - std::int_fast8_t month; // month of year [1:12] - std::int_fast8_t week; // week of month [1:5] (5==last) - std::int_fast8_t weekday; // 0==Sun, ..., 6=Sat - } m; + + struct Date { + struct NonLeapDay { + std::int_fast16_t day; // day of non-leap year [1:365] }; - } date; - struct { + struct Day { + std::int_fast16_t day; // day of year [0:365] + }; + struct MonthWeekWeekday { + std::int_fast8_t month; // month of year [1:12] + std::int_fast8_t week; // week of month [1:5] (5==last) + std::int_fast8_t weekday; // 0==Sun, ..., 6=Sat + }; + + DateFormat fmt; + + union { + NonLeapDay j; + Day n; + MonthWeekWeekday m; + }; + }; + + struct Time { std::int_fast32_t offset; // seconds before/after 00:00:00 - } time; + }; + + Date date; + Time time; }; // The entirety of a POSIX-string specified time-zone rule. The standard
diff --git a/absl/time/internal/cctz/src/tzfile.h b/absl/time/internal/cctz/src/tzfile.h index 90cfc0c..4485ba5 100644 --- a/absl/time/internal/cctz/src/tzfile.h +++ b/absl/time/internal/cctz/src/tzfile.h
@@ -1,3 +1,5 @@ +/* Layout and location of TZif files. */ + #ifndef TZFILE_H #define TZFILE_H
diff --git a/absl/time/internal/cctz/testdata/version b/absl/time/internal/cctz/testdata/version index fe86b5c..ac954d7 100644 --- a/absl/time/internal/cctz/testdata/version +++ b/absl/time/internal/cctz/testdata/version
@@ -1 +1 @@ -2018e-2-g99dd695 +2018g-9-gf0d2759
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Abidjan b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Abidjan index 6fd1af3..65d19ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Abidjan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Abidjan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra index 8726e80..eaaa818 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Addis_Ababa b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Addis_Ababa index 39631f2..6e19601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Addis_Ababa +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Addis_Ababa Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Algiers b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Algiers index 2a25f3a..a5867a6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Algiers +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Algiers Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmara b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmara index 39631f2..6e19601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmara +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmara Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmera b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmera index 39631f2..6e19601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmera +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmera Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bamako b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bamako index 6fd1af3..65d19ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bamako +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bamako Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bangui b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bangui index b1c97cc..cbdc045 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bangui +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bangui Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Banjul b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Banjul index 6fd1af3..65d19ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Banjul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Banjul Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bissau b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bissau index 8e32be3..82ea5aa 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bissau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bissau Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Blantyre b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Blantyre index 5b871db..31cfad7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Blantyre +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Blantyre Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Brazzaville b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Brazzaville index b1c97cc..cbdc045 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Brazzaville +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Brazzaville Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bujumbura b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bujumbura index 5b871db..31cfad7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bujumbura +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bujumbura Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Cairo b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Cairo index ba09750..0272fa1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Cairo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Cairo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca index 65de344..4c57054 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ceuta b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ceuta index aaa657f..dd75e3e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ceuta +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ceuta Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Conakry b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Conakry index 6fd1af3..65d19ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Conakry +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Conakry Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dakar b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dakar index 6fd1af3..65d19ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dakar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dakar Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dar_es_Salaam b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dar_es_Salaam index 39631f2..6e19601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dar_es_Salaam +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dar_es_Salaam Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Djibouti b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Djibouti index 39631f2..6e19601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Djibouti +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Djibouti Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Douala b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Douala index b1c97cc..cbdc045 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Douala +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Douala Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun b/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun index f5f8ffb..0ea0253 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Freetown b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Freetown index 6fd1af3..65d19ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Freetown +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Freetown Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Gaborone b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Gaborone index 5b871db..31cfad7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Gaborone +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Gaborone Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Harare b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Harare index 5b871db..31cfad7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Harare +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Harare Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Johannesburg b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Johannesburg index ddf3652..b8b9270 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Johannesburg +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Johannesburg Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba index 9fa7119..83eca03 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kampala b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kampala index 39631f2..6e19601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kampala +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kampala Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Khartoum b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Khartoum index f2c9e30..549dae2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Khartoum +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Khartoum Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kigali b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kigali index 5b871db..31cfad7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kigali +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kigali Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kinshasa b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kinshasa index b1c97cc..cbdc045 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kinshasa +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kinshasa Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lagos b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lagos index b1c97cc..cbdc045 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lagos +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lagos Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Libreville b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Libreville index b1c97cc..cbdc045 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Libreville +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Libreville Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lome b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lome index 6fd1af3..65d19ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lome +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lome Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Luanda b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Luanda index b1c97cc..cbdc045 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Luanda +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Luanda Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lubumbashi b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lubumbashi index 5b871db..31cfad7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lubumbashi +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lubumbashi Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lusaka b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lusaka index 5b871db..31cfad7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lusaka +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lusaka Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Malabo b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Malabo index b1c97cc..cbdc045 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Malabo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Malabo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maputo b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maputo index 5b871db..31cfad7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maputo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maputo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maseru b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maseru index ddf3652..b8b9270 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maseru +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maseru Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mbabane b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mbabane index ddf3652..b8b9270 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mbabane +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mbabane Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mogadishu b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mogadishu index 39631f2..6e19601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mogadishu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mogadishu Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Monrovia b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Monrovia index b434c67..2a154f4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Monrovia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Monrovia Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nairobi b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nairobi index 39631f2..6e19601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nairobi +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nairobi Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ndjamena b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ndjamena index bbfe19d..8779590 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ndjamena +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ndjamena Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Niamey b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Niamey index b1c97cc..cbdc045 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Niamey +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Niamey Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nouakchott b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nouakchott index 6fd1af3..65d19ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nouakchott +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nouakchott Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ouagadougou b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ouagadougou index 6fd1af3..65d19ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ouagadougou +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ouagadougou Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Porto-Novo b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Porto-Novo index b1c97cc..cbdc045 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Porto-Novo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Porto-Novo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome index a4ece7f..d2a64bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Timbuktu b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Timbuktu index 6fd1af3..65d19ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Timbuktu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Timbuktu Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tripoli b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tripoli index b32e220..bd88531 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tripoli +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tripoli Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tunis b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tunis index 4bd3885..0cd8ffb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tunis +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tunis Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Windhoek b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Windhoek index f5d40ba..6766185 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Windhoek +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Windhoek Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Adak b/absl/time/internal/cctz/testdata/zoneinfo/America/Adak index 5696e0f..4323649 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Adak +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Adak Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Anchorage b/absl/time/internal/cctz/testdata/zoneinfo/America/Anchorage index 6c8bdf2..9bbb2fd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Anchorage +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Anchorage Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla b/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua b/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Araguaina b/absl/time/internal/cctz/testdata/zoneinfo/America/Araguaina index 8b295a9..bc9a522 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Araguaina +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Araguaina Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Buenos_Aires b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Buenos_Aires index e4866ce..dfebfb9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Buenos_Aires +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Buenos_Aires Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Catamarca b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Catamarca index 9fe9ad6..b798105 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Catamarca +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Catamarca Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/ComodRivadavia b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/ComodRivadavia index 9fe9ad6..b798105 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/ComodRivadavia +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/ComodRivadavia Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Cordoba b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Cordoba index 8c58f8c..5df3cf6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Cordoba +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Cordoba Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Jujuy b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Jujuy index a74ba04..7d2ba91 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Jujuy +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Jujuy Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/La_Rioja b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/La_Rioja index cb184d6..7654aeb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/La_Rioja +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/La_Rioja Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Mendoza b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Mendoza index 5e8c44c..1032356 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Mendoza +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Mendoza Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Rio_Gallegos b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Rio_Gallegos index 966a529..3c849fc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Rio_Gallegos +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Rio_Gallegos Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Salta b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Salta index b19aa22..a4b71c1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Salta +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Salta Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Juan b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Juan index 9e5ade6..948a390 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Juan +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Juan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Luis b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Luis index af8aa99..acfbbe4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Luis +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Luis Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Tucuman b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Tucuman index bbb03a0..085fc9c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Tucuman +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Tucuman Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Ushuaia b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Ushuaia index 07e4e9f..1fc3256 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Ushuaia +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Ushuaia Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba b/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba index d308336..d3b318d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Asuncion b/absl/time/internal/cctz/testdata/zoneinfo/America/Asuncion index 3c61ddb..831bf84 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Asuncion +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Asuncion Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan b/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan index 5708b55..629ed42 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Atka b/absl/time/internal/cctz/testdata/zoneinfo/America/Atka index 5696e0f..4323649 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Atka +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Atka Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia b/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia index 6008a57..143eafc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia_Banderas b/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia_Banderas index 21e2b71..cd53107 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia_Banderas +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia_Banderas Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados b/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados index 6339936..7bb7ac4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Belem b/absl/time/internal/cctz/testdata/zoneinfo/America/Belem index b8e13b0..ab3c8a6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Belem +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Belem Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Belize b/absl/time/internal/cctz/testdata/zoneinfo/America/Belize index 7dcc4fc..fd69321 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Belize +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Belize Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon b/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon index abcde7d..f9f13a1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Boa_Vista b/absl/time/internal/cctz/testdata/zoneinfo/America/Boa_Vista index f776904..69e17a0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Boa_Vista +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Boa_Vista Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Bogota b/absl/time/internal/cctz/testdata/zoneinfo/America/Bogota index d893446..b7ded8e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Bogota +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Bogota Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Boise b/absl/time/internal/cctz/testdata/zoneinfo/America/Boise index ada6d64..f8d54e2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Boise +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Boise Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Buenos_Aires b/absl/time/internal/cctz/testdata/zoneinfo/America/Buenos_Aires index e4866ce..dfebfb9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Buenos_Aires +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Buenos_Aires Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cambridge_Bay b/absl/time/internal/cctz/testdata/zoneinfo/America/Cambridge_Bay index d322f01..f8db4b6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cambridge_Bay +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cambridge_Bay Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Campo_Grande b/absl/time/internal/cctz/testdata/zoneinfo/America/Campo_Grande index de52bb6..495ef45 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Campo_Grande +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Campo_Grande Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cancun b/absl/time/internal/cctz/testdata/zoneinfo/America/Cancun index 7e69f73..de6930c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cancun +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cancun Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Caracas b/absl/time/internal/cctz/testdata/zoneinfo/America/Caracas index c8cab1a..9abd028 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Caracas +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Caracas Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Catamarca b/absl/time/internal/cctz/testdata/zoneinfo/America/Catamarca index 9fe9ad6..b798105 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Catamarca +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Catamarca Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cayenne b/absl/time/internal/cctz/testdata/zoneinfo/America/Cayenne index 6db6409..ff59657 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cayenne +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cayenne Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cayman b/absl/time/internal/cctz/testdata/zoneinfo/America/Cayman index 5c1c063..55b0834 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cayman +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cayman Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Chicago b/absl/time/internal/cctz/testdata/zoneinfo/America/Chicago index 3dd8f0f..a5b1617 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Chicago +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Chicago Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Chihuahua b/absl/time/internal/cctz/testdata/zoneinfo/America/Chihuahua index e3adbdb..b268724 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Chihuahua +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Chihuahua Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour b/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour index 5708b55..629ed42 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cordoba b/absl/time/internal/cctz/testdata/zoneinfo/America/Cordoba index 8c58f8c..5df3cf6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cordoba +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cordoba Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Costa_Rica b/absl/time/internal/cctz/testdata/zoneinfo/America/Costa_Rica index c247133..525a67e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Costa_Rica +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Costa_Rica Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Creston b/absl/time/internal/cctz/testdata/zoneinfo/America/Creston index 798f627..0fba741 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Creston +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Creston Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cuiaba b/absl/time/internal/cctz/testdata/zoneinfo/America/Cuiaba index 145c89e..8a4ee7d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cuiaba +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cuiaba Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao b/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao index d308336..d3b318d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Danmarkshavn b/absl/time/internal/cctz/testdata/zoneinfo/America/Danmarkshavn index ad68c72..9549adc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Danmarkshavn +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Danmarkshavn Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson b/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson index 61c9688..db9cead 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson_Creek b/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson_Creek index 78f9076..db9e339 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson_Creek +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson_Creek Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Denver b/absl/time/internal/cctz/testdata/zoneinfo/America/Denver index 7fc6691..5fbe26b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Denver +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Denver Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Detroit b/absl/time/internal/cctz/testdata/zoneinfo/America/Detroit index e3ea5c3..5e02260 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Detroit +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Detroit Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica b/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton b/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton index d02fbcd..3fa0579 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Eirunepe b/absl/time/internal/cctz/testdata/zoneinfo/America/Eirunepe index 41047f2..99b7d06 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Eirunepe +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Eirunepe Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/El_Salvador b/absl/time/internal/cctz/testdata/zoneinfo/America/El_Salvador index 9b8bc7a..ac774e8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/El_Salvador +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/El_Salvador Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Ensenada b/absl/time/internal/cctz/testdata/zoneinfo/America/Ensenada index 29c83e7..ada6bf7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Ensenada +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Ensenada Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Nelson b/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Nelson index 5923cc6..5a0b7f1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Nelson +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Nelson Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Wayne b/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Wayne index 4a92c06..09511cc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Wayne +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Wayne Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Fortaleza b/absl/time/internal/cctz/testdata/zoneinfo/America/Fortaleza index 22396bb..e637170 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Fortaleza +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Fortaleza Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Glace_Bay b/absl/time/internal/cctz/testdata/zoneinfo/America/Glace_Bay index f58522b..48412a4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Glace_Bay +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Glace_Bay Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Godthab b/absl/time/internal/cctz/testdata/zoneinfo/America/Godthab index ea293cc..0160308 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Godthab +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Godthab Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Goose_Bay b/absl/time/internal/cctz/testdata/zoneinfo/America/Goose_Bay index b4b945e..a3f2990 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Goose_Bay +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Goose_Bay Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Grand_Turk b/absl/time/internal/cctz/testdata/zoneinfo/America/Grand_Turk index 4c8ca6f..4597a62 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Grand_Turk +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Grand_Turk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada b/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe b/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guatemala b/absl/time/internal/cctz/testdata/zoneinfo/America/Guatemala index abf943b..6118b5c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guatemala +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guatemala Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guayaquil b/absl/time/internal/cctz/testdata/zoneinfo/America/Guayaquil index 92de38b..bf087a0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guayaquil +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guayaquil Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana b/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana index 7d29876..d1dd2fa 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Halifax b/absl/time/internal/cctz/testdata/zoneinfo/America/Halifax index f86ece4..756099a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Halifax +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Halifax Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Havana b/absl/time/internal/cctz/testdata/zoneinfo/America/Havana index 1a58fcd..8186060 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Havana +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Havana Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Hermosillo b/absl/time/internal/cctz/testdata/zoneinfo/America/Hermosillo index ec435c2..26c269d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Hermosillo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Hermosillo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Indianapolis b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Indianapolis index 4a92c06..09511cc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Indianapolis +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Indianapolis Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Knox b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Knox index cc785da..fcd408d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Knox +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Knox Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Marengo b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Marengo index a23d7b7..1abf75e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Marengo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Marengo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Petersburg b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Petersburg index f16cb30..0133548 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Petersburg +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Petersburg Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Tell_City b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Tell_City index 0250bf9..4ce95c1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Tell_City +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Tell_City Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vevay b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vevay index e934de6..d236b7c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vevay +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vevay Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vincennes b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vincennes index adbdbee..c818929 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vincennes +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vincennes Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Winamac b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Winamac index b34f7b2..630935c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Winamac +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Winamac Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indianapolis b/absl/time/internal/cctz/testdata/zoneinfo/America/Indianapolis index 4a92c06..09511cc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indianapolis +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indianapolis Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Inuvik b/absl/time/internal/cctz/testdata/zoneinfo/America/Inuvik index 1388e8a..e107dc4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Inuvik +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Inuvik Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Iqaluit b/absl/time/internal/cctz/testdata/zoneinfo/America/Iqaluit index 0785ac5..c8138bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Iqaluit +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Iqaluit Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Jamaica b/absl/time/internal/cctz/testdata/zoneinfo/America/Jamaica index 7aedd26..162306f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Jamaica +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Jamaica Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Jujuy b/absl/time/internal/cctz/testdata/zoneinfo/America/Jujuy index a74ba04..7d2ba91 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Jujuy +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Jujuy Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Juneau b/absl/time/internal/cctz/testdata/zoneinfo/America/Juneau index d00668a..451f349 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Juneau +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Juneau Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Louisville b/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Louisville index fdf2e88..f4c4cf9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Louisville +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Louisville Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Monticello b/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Monticello index 60991aa..438e3ea 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Monticello +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Monticello Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Knox_IN b/absl/time/internal/cctz/testdata/zoneinfo/America/Knox_IN index cc785da..fcd408d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Knox_IN +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Knox_IN Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk b/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk index d308336..d3b318d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/La_Paz b/absl/time/internal/cctz/testdata/zoneinfo/America/La_Paz index bc3df52..5e5fec5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/La_Paz +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/La_Paz Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Lima b/absl/time/internal/cctz/testdata/zoneinfo/America/Lima index 44280a5..d9fec37 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Lima +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Lima Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Los_Angeles b/absl/time/internal/cctz/testdata/zoneinfo/America/Los_Angeles index c0ce440..9dad4f4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Los_Angeles +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Los_Angeles Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Louisville b/absl/time/internal/cctz/testdata/zoneinfo/America/Louisville index fdf2e88..f4c4cf9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Louisville +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Louisville Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes b/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes index d308336..d3b318d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Maceio b/absl/time/internal/cctz/testdata/zoneinfo/America/Maceio index 54442dc..fec8a8b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Maceio +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Maceio Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Managua b/absl/time/internal/cctz/testdata/zoneinfo/America/Managua index c543ffd..69256c6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Managua +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Managua Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Manaus b/absl/time/internal/cctz/testdata/zoneinfo/America/Manaus index 855cb02..b10241e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Manaus +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Manaus Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot b/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Martinique b/absl/time/internal/cctz/testdata/zoneinfo/America/Martinique index f9e2399..79716de 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Martinique +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Martinique Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Matamoros b/absl/time/internal/cctz/testdata/zoneinfo/America/Matamoros index 5671d25..5c59984 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Matamoros +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Matamoros Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Mazatlan b/absl/time/internal/cctz/testdata/zoneinfo/America/Mazatlan index afa94c2..43ee12d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Mazatlan +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Mazatlan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Mendoza b/absl/time/internal/cctz/testdata/zoneinfo/America/Mendoza index 5e8c44c..1032356 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Mendoza +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Mendoza Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Menominee b/absl/time/internal/cctz/testdata/zoneinfo/America/Menominee index 55d6e32..3146138 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Menominee +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Menominee Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Merida b/absl/time/internal/cctz/testdata/zoneinfo/America/Merida index ecc1856..b46298e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Merida +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Merida Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla b/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla index c033597..2635607 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Mexico_City b/absl/time/internal/cctz/testdata/zoneinfo/America/Mexico_City index f11e3d2..1434ab0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Mexico_City +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Mexico_City Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Miquelon b/absl/time/internal/cctz/testdata/zoneinfo/America/Miquelon index 75bbcf2..06ceaad 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Miquelon +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Miquelon Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Moncton b/absl/time/internal/cctz/testdata/zoneinfo/America/Moncton index 51cb1ba..9df8d0f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Moncton +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Moncton Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Monterrey b/absl/time/internal/cctz/testdata/zoneinfo/America/Monterrey index dcac92b..7dc5057 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Monterrey +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Monterrey Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Montevideo b/absl/time/internal/cctz/testdata/zoneinfo/America/Montevideo index f524fd2..0d1e565 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Montevideo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Montevideo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Montreal b/absl/time/internal/cctz/testdata/zoneinfo/America/Montreal index 7b4682a..6752c5b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Montreal +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Montreal Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat b/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau b/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau index e5d0289..5091eb5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/New_York b/absl/time/internal/cctz/testdata/zoneinfo/America/New_York index 7553fee..2f75480 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/New_York +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/New_York Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Nipigon b/absl/time/internal/cctz/testdata/zoneinfo/America/Nipigon index f8a0292..f6a856e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Nipigon +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Nipigon Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Nome b/absl/time/internal/cctz/testdata/zoneinfo/America/Nome index c886c9b..10998df 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Nome +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Nome Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Noronha b/absl/time/internal/cctz/testdata/zoneinfo/America/Noronha index 6d91f91..95ff8a2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Noronha +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Noronha Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Beulah b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Beulah index 8174c88..246345d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Beulah +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Beulah Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Center b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Center index 8035b24..1fa0703 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Center +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Center Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/New_Salem b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/New_Salem index 5b630ee..123f2ae 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/New_Salem +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/New_Salem Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Ojinaga b/absl/time/internal/cctz/testdata/zoneinfo/America/Ojinaga index 190c5c8..37d7830 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Ojinaga +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Ojinaga Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Panama b/absl/time/internal/cctz/testdata/zoneinfo/America/Panama index 5c1c063..55b0834 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Panama +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Panama Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Pangnirtung b/absl/time/internal/cctz/testdata/zoneinfo/America/Pangnirtung index df78b62..3e4e0db 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Pangnirtung +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Pangnirtung Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Paramaribo b/absl/time/internal/cctz/testdata/zoneinfo/America/Paramaribo index 1b608b3..b95c784 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Paramaribo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Paramaribo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Phoenix b/absl/time/internal/cctz/testdata/zoneinfo/America/Phoenix index adf2823..4d51271 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Phoenix +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Phoenix Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Port-au-Prince b/absl/time/internal/cctz/testdata/zoneinfo/America/Port-au-Prince index 7306cae..d959010 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Port-au-Prince +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Port-au-Prince Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain b/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Acre b/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Acre index b612ac2..16b7f92 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Acre +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Acre Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Velho b/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Velho index 2423fc1..10cb02b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Velho +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Velho Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Puerto_Rico b/absl/time/internal/cctz/testdata/zoneinfo/America/Puerto_Rico index d4525a6..a662a57 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Puerto_Rico +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Puerto_Rico Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas b/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas index 4d84eed..a5a8af5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Rainy_River b/absl/time/internal/cctz/testdata/zoneinfo/America/Rainy_River index 70dcd2d..ea66099 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Rainy_River +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Rainy_River Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Rankin_Inlet b/absl/time/internal/cctz/testdata/zoneinfo/America/Rankin_Inlet index 9f50f36..61ff6fc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Rankin_Inlet +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Rankin_Inlet Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Recife b/absl/time/internal/cctz/testdata/zoneinfo/America/Recife index fe55739..c6d99b3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Recife +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Recife Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Regina b/absl/time/internal/cctz/testdata/zoneinfo/America/Regina index 5fe8d6b..20c9c84 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Regina +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Regina Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Resolute b/absl/time/internal/cctz/testdata/zoneinfo/America/Resolute index 884b1f6..4365a5c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Resolute +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Resolute Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Rio_Branco b/absl/time/internal/cctz/testdata/zoneinfo/America/Rio_Branco index b612ac2..16b7f92 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Rio_Branco +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Rio_Branco Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Rosario b/absl/time/internal/cctz/testdata/zoneinfo/America/Rosario index 8c58f8c..5df3cf6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Rosario +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Rosario Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Santa_Isabel b/absl/time/internal/cctz/testdata/zoneinfo/America/Santa_Isabel index 29c83e7..ada6bf7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Santa_Isabel +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Santa_Isabel Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Santarem b/absl/time/internal/cctz/testdata/zoneinfo/America/Santarem index d776a43..8080efa 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Santarem +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Santarem Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago b/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago index ab766a4..816a042 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Santo_Domingo b/absl/time/internal/cctz/testdata/zoneinfo/America/Santo_Domingo index cc2cbf2..4e5eba5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Santo_Domingo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Santo_Domingo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Sao_Paulo b/absl/time/internal/cctz/testdata/zoneinfo/America/Sao_Paulo index 308a545..c417ba1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Sao_Paulo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Sao_Paulo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Scoresbysund b/absl/time/internal/cctz/testdata/zoneinfo/America/Scoresbysund index 8e1366c..e20e9e1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Scoresbysund +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Scoresbysund Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Shiprock b/absl/time/internal/cctz/testdata/zoneinfo/America/Shiprock index 7fc6691..5fbe26b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Shiprock +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Shiprock Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Sitka b/absl/time/internal/cctz/testdata/zoneinfo/America/Sitka index 662b8b6..31f7061 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Sitka +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Sitka Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Johns b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Johns index a1d1485..65a5b0c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Johns +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Johns Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Swift_Current b/absl/time/internal/cctz/testdata/zoneinfo/America/Swift_Current index 4db1300..8e9ef25 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Swift_Current +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Swift_Current Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Tegucigalpa b/absl/time/internal/cctz/testdata/zoneinfo/America/Tegucigalpa index 7aea8f9..477e939 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Tegucigalpa +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Tegucigalpa Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Thule b/absl/time/internal/cctz/testdata/zoneinfo/America/Thule index deefcc8..2969ebe 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Thule +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Thule Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Thunder_Bay b/absl/time/internal/cctz/testdata/zoneinfo/America/Thunder_Bay index aa1d486..e504c9a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Thunder_Bay +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Thunder_Bay Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Tijuana b/absl/time/internal/cctz/testdata/zoneinfo/America/Tijuana index 29c83e7..ada6bf7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Tijuana +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Tijuana Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Toronto b/absl/time/internal/cctz/testdata/zoneinfo/America/Toronto index 7b4682a..6752c5b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Toronto +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Toronto Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola b/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver b/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver index 9b5d924..0f9f832 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin b/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin index 447efbe..bdedd1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Whitehorse b/absl/time/internal/cctz/testdata/zoneinfo/America/Whitehorse index 6b62e2d..fb3cd71 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Whitehorse +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Whitehorse Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Winnipeg b/absl/time/internal/cctz/testdata/zoneinfo/America/Winnipeg index 2ffe3d8..3718d47 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Winnipeg +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Winnipeg Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Yakutat b/absl/time/internal/cctz/testdata/zoneinfo/America/Yakutat index 523b0a1..da209f9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Yakutat +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Yakutat Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife b/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife index d9d6eff..e6afa39 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Casey b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Casey index d0bbacc..f100f47 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Casey +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Casey Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Davis b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Davis index 40a9926..916f2c2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Davis +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Davis Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville index 0686353..bd6563e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Macquarie b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Macquarie index aea2be7..83c308a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Macquarie +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Macquarie Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Mawson b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Mawson index 5197dd9..e1f0b09 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Mawson +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Mawson Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/McMurdo b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/McMurdo index a5f5b6d..60bcef6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/McMurdo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/McMurdo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Palmer b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Palmer index 43a01d3..3dd85f8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Palmer +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Palmer Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Rothera b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Rothera index 56913f8..7940e6e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Rothera +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Rothera Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/South_Pole b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/South_Pole index a5f5b6d..60bcef6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/South_Pole +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/South_Pole Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa index 94a9d5a..4bb041a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Troll b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Troll index 3757fac..5e565da 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Troll +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Troll Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Vostok b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Vostok index 9fa335c..5696abf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Vostok +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Vostok Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Arctic/Longyearbyen b/absl/time/internal/cctz/testdata/zoneinfo/Arctic/Longyearbyen index 239c017..c6842af 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Arctic/Longyearbyen +++ b/absl/time/internal/cctz/testdata/zoneinfo/Arctic/Longyearbyen Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aden b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aden index e71bc4e..b2f9a25 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aden +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aden Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Almaty b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Almaty index 49a4b4d..d93201c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Almaty +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Almaty Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman index c3f0994..281b304 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Anadyr b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Anadyr index 0e623cf..6a96601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Anadyr +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Anadyr Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtau b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtau index 5803a3d..78cbcf0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtau Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtobe b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtobe index 808a502..7504052 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtobe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtobe Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashgabat b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashgabat index 046c472..8d9e03c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashgabat +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashgabat Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashkhabad b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashkhabad index 046c472..8d9e03c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashkhabad +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashkhabad Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Atyrau b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Atyrau index 27072eb..317466d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Atyrau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Atyrau Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baghdad b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baghdad index 3aacd78..97fa6c7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baghdad +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baghdad Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bahrain b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bahrain index a0c5f66..f514092 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bahrain +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bahrain Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baku b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baku index a17d1ad..8a090d7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baku +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baku Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bangkok b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bangkok index 8db5e8a..7249640 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bangkok +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bangkok Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Barnaul b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Barnaul index 60efb41..82cc49c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Barnaul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Barnaul Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Beirut b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Beirut index 72f0896..efb24c2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Beirut +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Beirut Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bishkek b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bishkek index e3f81ee..f7a7d54 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bishkek +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bishkek Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Brunei b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Brunei index cad16b0..8624c7a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Brunei +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Brunei Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Calcutta b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Calcutta index b57972d..e1cfcb8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Calcutta +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Calcutta Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chita b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chita index 95f5645..3baf752 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chita +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chita Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Choibalsan b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Choibalsan index 15b358f..79b9d3c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Choibalsan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Choibalsan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chongqing b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chongqing index dbd132f..ce9e00a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chongqing +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chongqing Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chungking b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chungking index dbd132f..ce9e00a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chungking +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chungking Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Colombo b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Colombo index 28fe430..4fc96c8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Colombo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Colombo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dacca b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dacca index 98881f0..776f27d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dacca +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dacca Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Damascus b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Damascus index ac45764..4b610b5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Damascus +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Damascus Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dhaka b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dhaka index 98881f0..776f27d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dhaka +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dhaka Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dili b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dili index c94fa61..f6ce91a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dili +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dili Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dubai b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dubai index c12f31a..7880d5d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dubai +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dubai Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dushanbe b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dushanbe index 67c772b..694f6e6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dushanbe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dushanbe Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Famagusta b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Famagusta index 021f8a2..653b146 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Famagusta +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Famagusta Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza index 60d0de0..cf54deb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Harbin b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Harbin index dbd132f..ce9e00a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Harbin +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Harbin Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron index a2e1b36..09c876a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh index 9264267..eab94fe 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong index dc9058e..8e5c581 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hovd b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hovd index f367a55..8eb5f64 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hovd +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hovd Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Irkutsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Irkutsk index 8413636..e8c53c0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Irkutsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Irkutsk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Istanbul b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Istanbul index 9a53b3a..833d4eb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Istanbul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Istanbul Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jakarta b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jakarta index 37b4edd..673d480 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jakarta +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jakarta Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jayapura b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jayapura index 39ddc84..a4c0829 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jayapura +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jayapura Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem index df51199..2d14c99 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kabul b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kabul index 80429ec..a22cf59 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kabul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kabul Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kamchatka b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kamchatka index fab27de..b9ed49c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kamchatka +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kamchatka Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Karachi b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Karachi index b7dcaab..337e1d5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Karachi +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Karachi Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kashgar b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kashgar index b44a1e1..0342b43 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kashgar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kashgar Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kathmandu b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kathmandu index 0cbd295..2f810b1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kathmandu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kathmandu Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Katmandu b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Katmandu index 0cbd295..2f810b1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Katmandu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Katmandu Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Khandyga b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Khandyga index 9183695..2b2f5bf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Khandyga +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Khandyga Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kolkata b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kolkata index b57972d..e1cfcb8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kolkata +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kolkata Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Krasnoyarsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Krasnoyarsk index faec35d..59efd24 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Krasnoyarsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Krasnoyarsk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuala_Lumpur b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuala_Lumpur index 5c95ebc..6d7d47b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuala_Lumpur +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuala_Lumpur Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuching b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuching index 62b5389..4878622 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuching +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuching Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuwait b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuwait index e71bc4e..b2f9a25 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuwait +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuwait Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macao b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macao index 2c20a32..d801000 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macao +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macao Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macau b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macau index 2c20a32..d801000 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macau Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Magadan b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Magadan index 2db0635..b20cc57 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Magadan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Magadan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Makassar b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Makassar index 3a5dcb2..ed55442 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Makassar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Makassar Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Manila b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Manila index 06859a7..2c9220c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Manila +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Manila Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Muscat b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Muscat index c12f31a..7880d5d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Muscat +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Muscat Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Nicosia b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Nicosia index 3e663b2..f7f10ab 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Nicosia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Nicosia Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novokuznetsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novokuznetsk index ed4b248..2576a3b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novokuznetsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novokuznetsk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novosibirsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novosibirsk index a5d39df..95e3c73 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novosibirsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novosibirsk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Omsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Omsk index 5e0d9b6..d805e4f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Omsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Omsk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Oral b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Oral index b8eb58d..e36aec4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Oral +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Oral Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh index 8db5e8a..7249640 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pontianak b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pontianak index ec98c62..9377d03 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pontianak +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pontianak Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pyongyang b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pyongyang index dc24926..dd54989 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pyongyang +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pyongyang Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qatar b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qatar index a0c5f66..f514092 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qatar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qatar Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda index 0fc7fad..00b2784 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Rangoon b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Rangoon index 3cc2aaf..a00282d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Rangoon +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Rangoon Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Riyadh b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Riyadh index e71bc4e..b2f9a25 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Riyadh +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Riyadh Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon index 9264267..eab94fe 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Sakhalin b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Sakhalin index 8d6b4df..9c94900 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Sakhalin +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Sakhalin Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Samarkand b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Samarkand index 10c7af7..a5d1e97 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Samarkand +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Samarkand Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Seoul b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Seoul index 312ec40..fa1cbd3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Seoul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Seoul Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Shanghai b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Shanghai index dbd132f..ce9e00a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Shanghai +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Shanghai Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Singapore b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Singapore index 7858366..ebc4b0d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Singapore +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Singapore Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Srednekolymsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Srednekolymsk index 16b1cd8..f8b7bb2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Srednekolymsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Srednekolymsk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Taipei b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Taipei index 748873b..f9cbe67 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Taipei +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Taipei Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tashkent b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tashkent index 6f7dea4..e75bb36 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tashkent +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tashkent Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi index 4b2d2e2..09bb06e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran index 3157f80..ad9058b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv index df51199..2d14c99 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimbu b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimbu index a8bddb9..06d3324 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimbu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimbu Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimphu b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimphu index a8bddb9..06d3324 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimphu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimphu Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tokyo b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tokyo index 8ad44ba..26f4d34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tokyo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tokyo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tomsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tomsk index 919b003..28da9c9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tomsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tomsk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ujung_Pandang b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ujung_Pandang index 3a5dcb2..ed55442 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ujung_Pandang +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ujung_Pandang Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulaanbaatar b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulaanbaatar index 94ddfea..82fd476 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulaanbaatar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulaanbaatar Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulan_Bator b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulan_Bator index 94ddfea..82fd476 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulan_Bator +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulan_Bator Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Urumqi b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Urumqi index b44a1e1..0342b43 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Urumqi +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Urumqi Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ust-Nera b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ust-Nera index 7431eb9..c0c3767 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ust-Nera +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ust-Nera Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane index 8db5e8a..7249640 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vladivostok b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vladivostok index 80b170b..15731ab 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vladivostok +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vladivostok Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yakutsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yakutsk index 220ad3d..1f86e77 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yakutsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yakutsk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yangon b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yangon index 3cc2aaf..a00282d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yangon +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yangon Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yekaterinburg b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yekaterinburg index c1abb93..fff9f3b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yekaterinburg +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yekaterinburg Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yerevan b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yerevan index 4c4e045..409c3b1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yerevan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yerevan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores index 1895e1b..56593db 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Bermuda b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Bermuda index 548d979..3a5c6db 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Bermuda +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Bermuda Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Canary b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Canary index 544f443..f319215 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Canary +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Canary Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Cape_Verde b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Cape_Verde index 6bda6db..e2a49d2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Cape_Verde +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Cape_Verde Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faeroe b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faeroe index c486518..4dab7ef 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faeroe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faeroe Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faroe b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faroe index c486518..4dab7ef 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faroe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faroe Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Jan_Mayen b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Jan_Mayen index 239c017..c6842af 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Jan_Mayen +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Jan_Mayen Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira index e25f8a5..5213761 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Reykjavik b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Reykjavik index dc49c32..ac6bd69 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Reykjavik +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Reykjavik Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/South_Georgia b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/South_Georgia index 56b383b..b3311b6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/South_Georgia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/South_Georgia Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/St_Helena b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/St_Helena index 6fd1af3..65d19ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/St_Helena +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/St_Helena Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Stanley b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Stanley index 3649415..2fd42a2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Stanley +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Stanley Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/ACT b/absl/time/internal/cctz/testdata/zoneinfo/Australia/ACT index aaed12c..4ed4467 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/ACT +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/ACT Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Adelaide b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Adelaide index 4f331a8..190b0e3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Adelaide +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Adelaide Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Brisbane b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Brisbane index a327d83..26ffd9a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Brisbane +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Brisbane Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Broken_Hill b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Broken_Hill index 768b167..874c865 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Broken_Hill +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Broken_Hill Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Canberra b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Canberra index aaed12c..4ed4467 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Canberra +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Canberra Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Currie b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Currie index a3f6f29..865801e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Currie +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Currie Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Darwin b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Darwin index c6ae9a7..cf42d1d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Darwin +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Darwin Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Eucla b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Eucla index 99f07a9..c49d499 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Eucla +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Eucla Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Hobart b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Hobart index 07784ce..92d1215 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Hobart +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Hobart Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/LHI b/absl/time/internal/cctz/testdata/zoneinfo/Australia/LHI index 57597b0..8c6c7dd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/LHI +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/LHI Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lindeman b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lindeman index 71ca143..8ee1a6f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lindeman +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lindeman Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lord_Howe b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lord_Howe index 57597b0..8c6c7dd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lord_Howe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lord_Howe Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Melbourne b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Melbourne index ec8dfe0..3f2d3d7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Melbourne +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Melbourne Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/NSW b/absl/time/internal/cctz/testdata/zoneinfo/Australia/NSW index aaed12c..4ed4467 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/NSW +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/NSW Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/North b/absl/time/internal/cctz/testdata/zoneinfo/Australia/North index c6ae9a7..cf42d1d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/North +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/North Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Perth b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Perth index 85c26d5..d38b67e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Perth +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Perth Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Queensland b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Queensland index a327d83..26ffd9a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Queensland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Queensland Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/South b/absl/time/internal/cctz/testdata/zoneinfo/Australia/South index 4f331a8..190b0e3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/South +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/South Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Sydney b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Sydney index aaed12c..4ed4467 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Sydney +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Sydney Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Tasmania b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Tasmania index 07784ce..92d1215 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Tasmania +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Tasmania Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Victoria b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Victoria index ec8dfe0..3f2d3d7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Victoria +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Victoria Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/West b/absl/time/internal/cctz/testdata/zoneinfo/Australia/West index 85c26d5..d38b67e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/West +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/West Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Yancowinna b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Yancowinna index 768b167..874c865 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Yancowinna +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Yancowinna Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/Acre b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/Acre index b612ac2..16b7f92 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/Acre +++ b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/Acre Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/DeNoronha b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/DeNoronha index 6d91f91..95ff8a2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/DeNoronha +++ b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/DeNoronha Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/East b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/East index 308a545..c417ba1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/East +++ b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/East Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/West b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/West index 855cb02..b10241e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/West +++ b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/West Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/CET b/absl/time/internal/cctz/testdata/zoneinfo/CET index 4c4f8ef..d585656 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/CET +++ b/absl/time/internal/cctz/testdata/zoneinfo/CET Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/CST6CDT b/absl/time/internal/cctz/testdata/zoneinfo/CST6CDT index 5c8a1d9..41c4136 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/CST6CDT +++ b/absl/time/internal/cctz/testdata/zoneinfo/CST6CDT Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Atlantic b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Atlantic index f86ece4..756099a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Atlantic +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Atlantic Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Central b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Central index 2ffe3d8..3718d47 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Central +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Central Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Eastern b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Eastern index 7b4682a..6752c5b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Eastern +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Eastern Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain index d02fbcd..3fa0579 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Newfoundland b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Newfoundland index a1d1485..65a5b0c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Newfoundland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Newfoundland Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific index 9b5d924..0f9f832 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Saskatchewan b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Saskatchewan index 5fe8d6b..20c9c84 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Saskatchewan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Saskatchewan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Yukon b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Yukon index 6b62e2d..fb3cd71 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Yukon +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Yukon Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental b/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental index ab766a4..816a042 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental +++ b/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Chile/EasterIsland b/absl/time/internal/cctz/testdata/zoneinfo/Chile/EasterIsland index 060bef8..cae3744 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Chile/EasterIsland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Chile/EasterIsland Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Cuba b/absl/time/internal/cctz/testdata/zoneinfo/Cuba index 1a58fcd..8186060 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Cuba +++ b/absl/time/internal/cctz/testdata/zoneinfo/Cuba Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/EET b/absl/time/internal/cctz/testdata/zoneinfo/EET index beb273a..d2f54c9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/EET +++ b/absl/time/internal/cctz/testdata/zoneinfo/EET Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/EST b/absl/time/internal/cctz/testdata/zoneinfo/EST index ae34663..074a4fc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/EST +++ b/absl/time/internal/cctz/testdata/zoneinfo/EST Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/EST5EDT b/absl/time/internal/cctz/testdata/zoneinfo/EST5EDT index 54541fc..087b641 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/EST5EDT +++ b/absl/time/internal/cctz/testdata/zoneinfo/EST5EDT Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Egypt b/absl/time/internal/cctz/testdata/zoneinfo/Egypt index ba09750..0272fa1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Egypt +++ b/absl/time/internal/cctz/testdata/zoneinfo/Egypt Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Eire b/absl/time/internal/cctz/testdata/zoneinfo/Eire index 655daf3..5c5a7a3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Eire +++ b/absl/time/internal/cctz/testdata/zoneinfo/Eire Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT index c05e45f..2ee1429 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+0 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+0 index c05e45f..2ee1429 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+0 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+1 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+1 index 082986e..087d1f9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+1 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+1 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+10 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+10 index 23276cd..6437c68 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+10 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+10 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+11 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+11 index 28c579d..72a912e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+11 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+11 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+12 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+12 index c740603..6938a1a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+12 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+12 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+2 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+2 index 721cde2..a315577 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+2 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+2 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+3 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+3 index ae06bcb..ee77619 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+3 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+3 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+4 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+4 index 5a7f878..1ea7da2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+4 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+4 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+5 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+5 index 18cbf1f..dda1a9e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+5 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+5 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+6 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+6 index 1aa4be8..f4a0385 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+6 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+6 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+7 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+7 index cd8ed49..2d2ccd0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+7 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+7 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+8 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+8 index e0ba6b8..826c770 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+8 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+8 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+9 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+9 index eee1bcb..b125ad2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+9 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+9 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-0 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-0 index c05e45f..2ee1429 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-0 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-1 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-1 index 4ff8701..dde682d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-1 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-1 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-10 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-10 index e12e461..352ec08 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-10 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-10 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-11 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-11 index 37f2739..dfa27fe 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-11 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-11 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-12 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-12 index 09297f1..eef949d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-12 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-12 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-13 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-13 index 97ae1e1..f9363b2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-13 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-13 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-14 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-14 index 58d6d1b..35add05 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-14 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-14 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-2 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-2 index f0dc706..315cae4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-2 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-2 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-3 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-3 index a0790fe..7489a15 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-3 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-3 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-4 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-4 index a75a173..560243e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-4 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-4 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-5 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-5 index 85ebf22..b2bbe97 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-5 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-5 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-6 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-6 index 95def1f..b979dbb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-6 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-6 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-7 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-7 index c6a776e..365ab1f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-7 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-7 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-8 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-8 index f74a16f..742082f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-8 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-8 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-9 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-9 index 9b647c0..abc0b27 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-9 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-9 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT0 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT0 index c05e45f..2ee1429 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT0 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Greenwich b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Greenwich index c05e45f..2ee1429 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Greenwich +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Greenwich Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT b/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT index 40147b9..a88c4b6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/UTC b/absl/time/internal/cctz/testdata/zoneinfo/Etc/UTC index c3b97f1..5583f5b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/UTC +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/UTC Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Universal b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Universal index c3b97f1..5583f5b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Universal +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Universal Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Zulu b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Zulu index c3b97f1..5583f5b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Zulu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Zulu Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Amsterdam b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Amsterdam index 6dae5e4..ed064ed 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Amsterdam +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Amsterdam Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Andorra b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Andorra index b06de7a..5962550 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Andorra +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Andorra Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Astrakhan b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Astrakhan index 90d7c2a..5e069ea 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Astrakhan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Astrakhan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Athens b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Athens index 0001602..9f3a067 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Athens +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Athens Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belfast b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belfast index 4527515..a340326 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belfast +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belfast Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belgrade b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belgrade index 79c25d7..32a5722 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belgrade +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belgrade Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Berlin b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Berlin index b4f2a2a..7ddd510 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Berlin +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Berlin Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bratislava b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bratislava index ba82f31..85036de 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bratislava +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bratislava Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Brussels b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Brussels index d8f19a6..d0d0a08 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Brussels +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Brussels Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bucharest b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bucharest index e0eac4c..4eb7ed0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bucharest +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bucharest Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Budapest b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Budapest index 3ddf6a5..dfdc6d2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Budapest +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Budapest Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Busingen b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Busingen index 9c2b600..ad6cf59 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Busingen +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Busingen Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau index 2109b52..5bc1bfe 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Copenhagen b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Copenhagen index be87cf1..cb2ec06 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Copenhagen +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Copenhagen Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Dublin b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Dublin index 655daf3..5c5a7a3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Dublin +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Dublin Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Gibraltar b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Gibraltar index a7105fa..117aadb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Gibraltar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Gibraltar Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Guernsey b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Guernsey index 4527515..a340326 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Guernsey +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Guernsey Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Helsinki b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Helsinki index 29b3c81..b4f8f9c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Helsinki +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Helsinki Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Isle_of_Man b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Isle_of_Man index 4527515..a340326 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Isle_of_Man +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Isle_of_Man Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Istanbul b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Istanbul index 9a53b3a..833d4eb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Istanbul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Istanbul Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Jersey b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Jersey index 4527515..a340326 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Jersey +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Jersey Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kaliningrad b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kaliningrad index 37280d0..982d82a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kaliningrad +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kaliningrad Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev index b3e20a7..9337c9e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kirov b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kirov index 40b558f..a3b5320 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kirov +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kirov Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon index a856530..355817b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ljubljana b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ljubljana index 79c25d7..32a5722 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ljubljana +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ljubljana Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/London b/absl/time/internal/cctz/testdata/zoneinfo/Europe/London index 4527515..a340326 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/London +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/London Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Luxembourg b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Luxembourg index 6fae86c..6c194a5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Luxembourg +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Luxembourg Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Madrid b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Madrid index 9b51a73..ccc9d85 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Madrid +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Madrid Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Malta b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Malta index c1208e2..bf2452d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Malta +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Malta Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Mariehamn b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Mariehamn index 29b3c81..b4f8f9c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Mariehamn +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Mariehamn Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Minsk b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Minsk index 60041a4..801aead 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Minsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Minsk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Monaco b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Monaco index 0b40f1e..686ae88 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Monaco +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Monaco Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Moscow b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Moscow index 906bd05..ddb3f4e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Moscow +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Moscow Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Nicosia b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Nicosia index 3e663b2..f7f10ab 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Nicosia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Nicosia Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Oslo b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Oslo index 239c017..c6842af 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Oslo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Oslo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Paris b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Paris index cf6e2e2..ca85435 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Paris +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Paris Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Podgorica b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Podgorica index 79c25d7..32a5722 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Podgorica +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Podgorica Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Prague b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Prague index ba82f31..85036de 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Prague +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Prague Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Riga b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Riga index b729ee8..8495c50 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Riga +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Riga Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Rome b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Rome index bdd3449..78a131b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Rome +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Rome Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Samara b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Samara index 0539acf..97d5dd9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Samara +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Samara Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/San_Marino b/absl/time/internal/cctz/testdata/zoneinfo/Europe/San_Marino index bdd3449..78a131b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/San_Marino +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/San_Marino Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sarajevo b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sarajevo index 79c25d7..32a5722 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sarajevo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sarajevo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Saratov b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Saratov index e8cd6b1..8fd5f6d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Saratov +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Saratov Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol index f3b42b0..e82dbbc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Skopje b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Skopje index 79c25d7..32a5722 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Skopje +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Skopje Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sofia b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sofia index 763e074..dcfdd08 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sofia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sofia Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Stockholm b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Stockholm index 43c7f2e..f3e0c7f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Stockholm +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Stockholm Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tallinn b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tallinn index 18f903f..3a744cc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tallinn +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tallinn Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tirane b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tirane index 52c16a4..0b86017 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tirane +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tirane Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol index 2109b52..5bc1bfe 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ulyanovsk b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ulyanovsk index c280f43..7b61bdc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ulyanovsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ulyanovsk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod index 8ddba90..677f088 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vaduz b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vaduz index 9c2b600..ad6cf59 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vaduz +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vaduz Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vatican b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vatican index bdd3449..78a131b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vatican +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vatican Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vienna b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vienna index 9c0fac5..9e2d0c9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vienna +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vienna Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vilnius b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vilnius index da380af..46ce484 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vilnius +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vilnius Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Volgograd b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Volgograd index f4cb64f..8f170dd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Volgograd +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Volgograd Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Warsaw b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Warsaw index 5cbba41..d6bb156 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Warsaw +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Warsaw Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zagreb b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zagreb index 79c25d7..32a5722 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zagreb +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zagreb Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye index 6f14850..e42edfc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zurich b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zurich index 9c2b600..ad6cf59 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zurich +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zurich Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Factory b/absl/time/internal/cctz/testdata/zoneinfo/Factory index afeeb88..95bc3a3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Factory +++ b/absl/time/internal/cctz/testdata/zoneinfo/Factory Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GB b/absl/time/internal/cctz/testdata/zoneinfo/GB index 4527515..a340326 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GB +++ b/absl/time/internal/cctz/testdata/zoneinfo/GB Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GB-Eire b/absl/time/internal/cctz/testdata/zoneinfo/GB-Eire index 4527515..a340326 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GB-Eire +++ b/absl/time/internal/cctz/testdata/zoneinfo/GB-Eire Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GMT b/absl/time/internal/cctz/testdata/zoneinfo/GMT index c05e45f..2ee1429 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GMT +++ b/absl/time/internal/cctz/testdata/zoneinfo/GMT Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GMT+0 b/absl/time/internal/cctz/testdata/zoneinfo/GMT+0 index c05e45f..2ee1429 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GMT+0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/GMT+0 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GMT-0 b/absl/time/internal/cctz/testdata/zoneinfo/GMT-0 index c05e45f..2ee1429 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GMT-0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/GMT-0 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GMT0 b/absl/time/internal/cctz/testdata/zoneinfo/GMT0 index c05e45f..2ee1429 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GMT0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/GMT0 Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Greenwich b/absl/time/internal/cctz/testdata/zoneinfo/Greenwich index c05e45f..2ee1429 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Greenwich +++ b/absl/time/internal/cctz/testdata/zoneinfo/Greenwich Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/HST b/absl/time/internal/cctz/testdata/zoneinfo/HST index 03e4db0..616c31b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/HST +++ b/absl/time/internal/cctz/testdata/zoneinfo/HST Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Hongkong b/absl/time/internal/cctz/testdata/zoneinfo/Hongkong index dc9058e..8e5c581 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Hongkong +++ b/absl/time/internal/cctz/testdata/zoneinfo/Hongkong Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Iceland b/absl/time/internal/cctz/testdata/zoneinfo/Iceland index dc49c32..ac6bd69 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Iceland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Iceland Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Antananarivo b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Antananarivo index 39631f2..6e19601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Antananarivo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Antananarivo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Chagos b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Chagos index 0e5e719..f609611 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Chagos +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Chagos Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Christmas b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Christmas index 066c1e9..6babdee 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Christmas +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Christmas Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Cocos b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Cocos index 34a2457..58f8051 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Cocos +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Cocos Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Comoro b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Comoro index 39631f2..6e19601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Comoro +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Comoro Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Kerguelen b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Kerguelen index e7d4d3d..2cb6f3e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Kerguelen +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Kerguelen Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mahe b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mahe index db8ac68..49e23e5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mahe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mahe Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Maldives b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Maldives index 3f1a76e..ffa3365 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Maldives +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Maldives Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mauritius b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mauritius index fd8d911..b23e2ce 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mauritius +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mauritius Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mayotte b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mayotte index 39631f2..6e19601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mayotte +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mayotte Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Reunion b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Reunion index d5f9aa4..11c6002 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Reunion +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Reunion Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Iran b/absl/time/internal/cctz/testdata/zoneinfo/Iran index 3157f80..ad9058b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Iran +++ b/absl/time/internal/cctz/testdata/zoneinfo/Iran Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Israel b/absl/time/internal/cctz/testdata/zoneinfo/Israel index df51199..2d14c99 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Israel +++ b/absl/time/internal/cctz/testdata/zoneinfo/Israel Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Jamaica b/absl/time/internal/cctz/testdata/zoneinfo/Jamaica index 7aedd26..162306f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Jamaica +++ b/absl/time/internal/cctz/testdata/zoneinfo/Jamaica Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Japan b/absl/time/internal/cctz/testdata/zoneinfo/Japan index 8ad44ba..26f4d34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Japan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Japan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein b/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein index 1a27122..54bd71f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein +++ b/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Libya b/absl/time/internal/cctz/testdata/zoneinfo/Libya index b32e220..bd88531 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Libya +++ b/absl/time/internal/cctz/testdata/zoneinfo/Libya Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/MET b/absl/time/internal/cctz/testdata/zoneinfo/MET index 71963d5..388dd74 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/MET +++ b/absl/time/internal/cctz/testdata/zoneinfo/MET Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/MST b/absl/time/internal/cctz/testdata/zoneinfo/MST index a1bee7c..da3e926 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/MST +++ b/absl/time/internal/cctz/testdata/zoneinfo/MST Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/MST7MDT b/absl/time/internal/cctz/testdata/zoneinfo/MST7MDT index 726a7e5..ddca8d1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/MST7MDT +++ b/absl/time/internal/cctz/testdata/zoneinfo/MST7MDT Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaNorte b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaNorte index 29c83e7..ada6bf7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaNorte +++ b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaNorte Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaSur b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaSur index afa94c2..43ee12d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaSur +++ b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaSur Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/General b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/General index f11e3d2..1434ab0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/General +++ b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/General Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/NZ b/absl/time/internal/cctz/testdata/zoneinfo/NZ index a5f5b6d..60bcef6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/NZ +++ b/absl/time/internal/cctz/testdata/zoneinfo/NZ Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/NZ-CHAT b/absl/time/internal/cctz/testdata/zoneinfo/NZ-CHAT index 957c80b..abe09cb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/NZ-CHAT +++ b/absl/time/internal/cctz/testdata/zoneinfo/NZ-CHAT Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Navajo b/absl/time/internal/cctz/testdata/zoneinfo/Navajo index 7fc6691..5fbe26b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Navajo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Navajo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/PRC b/absl/time/internal/cctz/testdata/zoneinfo/PRC index dbd132f..ce9e00a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/PRC +++ b/absl/time/internal/cctz/testdata/zoneinfo/PRC Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/PST8PDT b/absl/time/internal/cctz/testdata/zoneinfo/PST8PDT index 6242ac0..d773e28 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/PST8PDT +++ b/absl/time/internal/cctz/testdata/zoneinfo/PST8PDT Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia index 4091a85..fd03ff7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Auckland b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Auckland index a5f5b6d..60bcef6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Auckland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Auckland Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Bougainville b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Bougainville index dc5a7d7..6a6c2da 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Bougainville +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Bougainville Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chatham b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chatham index 957c80b..abe09cb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chatham +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chatham Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk index 289b795..e79bca2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Easter b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Easter index 060bef8..cae3744 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Easter +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Easter Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Efate b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Efate index 5cee55d..d650a05 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Efate +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Efate Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury index a3f30e5..8087350 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fakaofo b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fakaofo index 6e4b8af..4fa169f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fakaofo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fakaofo Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji index 912db18..61a6695 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Funafuti b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Funafuti index 3289094..e6a1544 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Funafuti +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Funafuti Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Galapagos b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Galapagos index 76b2b3a..859b76d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Galapagos +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Galapagos Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Gambier b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Gambier index 625016d..4e9e36c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Gambier +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Gambier Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guadalcanal b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guadalcanal index 0c24095..908ccc1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guadalcanal +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guadalcanal Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam index 4286e6b..ffdf8c2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Honolulu b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Honolulu index bd85577..c7cd060 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Honolulu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Honolulu Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Johnston b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Johnston index bd85577..c7cd060 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Johnston +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Johnston Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kiritimati b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kiritimati index 762275d..cf5b3bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kiritimati +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kiritimati Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae index f8222e6..b6bd4b0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein index 1a27122..54bd71f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro index b3a8c18..53f3288 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Marquesas b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Marquesas index 10c5c9b..5fad0e1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Marquesas +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Marquesas Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Midway b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Midway index 3e38e97..72707b5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Midway +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Midway Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru index 6092119..7e7d920 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue index df6110d..1d58fe3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Norfolk b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Norfolk index d0b9607..f630a65 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Norfolk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Norfolk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Noumea b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Noumea index d9c68f8..99f6bca 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Noumea +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Noumea Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pago_Pago b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pago_Pago index 3e38e97..72707b5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pago_Pago +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pago_Pago Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau index e1bbea5..968f195 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pitcairn b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pitcairn index 54783cf..9092e48 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pitcairn +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pitcairn Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei index 9743bc3..d3393a2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape index 9743bc3..d3393a2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Port_Moresby b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Port_Moresby index 3fa1f7f..f6fd51c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Port_Moresby +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Port_Moresby Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga index ace1ce4..9708b87 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan index 4286e6b..ffdf8c2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Samoa b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Samoa index 3e38e97..72707b5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Samoa +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Samoa Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tahiti b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tahiti index 7867d8b..37e4e88 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tahiti +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tahiti Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tarawa b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tarawa index 3340413..e23c0cd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tarawa +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tarawa Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu index b3a5a89..35c9e2c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk index 289b795..e79bca2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wake b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wake index 2dc630c..837ce1f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wake +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wake Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wallis b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wallis index b4f0f9b..8be9ac4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wallis +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wallis Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap index 289b795..e79bca2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Poland b/absl/time/internal/cctz/testdata/zoneinfo/Poland index 5cbba41..d6bb156 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Poland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Poland Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Portugal b/absl/time/internal/cctz/testdata/zoneinfo/Portugal index a856530..355817b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Portugal +++ b/absl/time/internal/cctz/testdata/zoneinfo/Portugal Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/ROC b/absl/time/internal/cctz/testdata/zoneinfo/ROC index 748873b..f9cbe67 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/ROC +++ b/absl/time/internal/cctz/testdata/zoneinfo/ROC Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/ROK b/absl/time/internal/cctz/testdata/zoneinfo/ROK index 312ec40..fa1cbd3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/ROK +++ b/absl/time/internal/cctz/testdata/zoneinfo/ROK Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Singapore b/absl/time/internal/cctz/testdata/zoneinfo/Singapore index 7858366..ebc4b0d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Singapore +++ b/absl/time/internal/cctz/testdata/zoneinfo/Singapore Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Turkey b/absl/time/internal/cctz/testdata/zoneinfo/Turkey index 9a53b3a..833d4eb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Turkey +++ b/absl/time/internal/cctz/testdata/zoneinfo/Turkey Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/UCT b/absl/time/internal/cctz/testdata/zoneinfo/UCT index 40147b9..a88c4b6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/UCT +++ b/absl/time/internal/cctz/testdata/zoneinfo/UCT Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Alaska b/absl/time/internal/cctz/testdata/zoneinfo/US/Alaska index 6c8bdf2..9bbb2fd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Alaska +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Alaska Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Aleutian b/absl/time/internal/cctz/testdata/zoneinfo/US/Aleutian index 5696e0f..4323649 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Aleutian +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Aleutian Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Arizona b/absl/time/internal/cctz/testdata/zoneinfo/US/Arizona index adf2823..4d51271 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Arizona +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Arizona Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Central b/absl/time/internal/cctz/testdata/zoneinfo/US/Central index 3dd8f0f..a5b1617 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Central +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Central Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/East-Indiana b/absl/time/internal/cctz/testdata/zoneinfo/US/East-Indiana index 4a92c06..09511cc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/East-Indiana +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/East-Indiana Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Eastern b/absl/time/internal/cctz/testdata/zoneinfo/US/Eastern index 7553fee..2f75480 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Eastern +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Eastern Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Hawaii b/absl/time/internal/cctz/testdata/zoneinfo/US/Hawaii index bd85577..c7cd060 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Hawaii +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Hawaii Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Indiana-Starke b/absl/time/internal/cctz/testdata/zoneinfo/US/Indiana-Starke index cc785da..fcd408d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Indiana-Starke +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Indiana-Starke Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Michigan b/absl/time/internal/cctz/testdata/zoneinfo/US/Michigan index e3ea5c3..5e02260 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Michigan +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Michigan Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Mountain b/absl/time/internal/cctz/testdata/zoneinfo/US/Mountain index 7fc6691..5fbe26b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Mountain +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Mountain Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Pacific b/absl/time/internal/cctz/testdata/zoneinfo/US/Pacific index c0ce440..9dad4f4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Pacific +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Pacific Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Samoa b/absl/time/internal/cctz/testdata/zoneinfo/US/Samoa index 3e38e97..72707b5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Samoa +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Samoa Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/UTC b/absl/time/internal/cctz/testdata/zoneinfo/UTC index c3b97f1..5583f5b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/UTC +++ b/absl/time/internal/cctz/testdata/zoneinfo/UTC Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Universal b/absl/time/internal/cctz/testdata/zoneinfo/Universal index c3b97f1..5583f5b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Universal +++ b/absl/time/internal/cctz/testdata/zoneinfo/Universal Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/W-SU b/absl/time/internal/cctz/testdata/zoneinfo/W-SU index 906bd05..ddb3f4e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/W-SU +++ b/absl/time/internal/cctz/testdata/zoneinfo/W-SU Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/WET b/absl/time/internal/cctz/testdata/zoneinfo/WET index 444a193..9b03a17 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/WET +++ b/absl/time/internal/cctz/testdata/zoneinfo/WET Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Zulu b/absl/time/internal/cctz/testdata/zoneinfo/Zulu index c3b97f1..5583f5b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Zulu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Zulu Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab b/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab index 2d90ed7..2729e6e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab +++ b/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab
@@ -1,35 +1,35 @@ -# tz zone descriptions +# tzdb timezone descriptions # # This file is in the public domain. # -# From Paul Eggert (2017-10-01): -# This file contains a table where each row stands for a zone where -# civil time stamps have agreed since 1970. Columns are separated by +# From Paul Eggert (2018-06-27): +# This file contains a table where each row stands for a timezone where +# civil timestamps have agreed since 1970. Columns are separated by # a single tab. Lines beginning with '#' are comments. All text uses # UTF-8 encoding. The columns of the table are as follows: # -# 1. The countries that overlap the zone, as a comma-separated list +# 1. The countries that overlap the timezone, as a comma-separated list # of ISO 3166 2-character country codes. See the file 'iso3166.tab'. -# 2. Latitude and longitude of the zone's principal location +# 2. Latitude and longitude of the timezone's principal location # in ISO 6709 sign-degrees-minutes-seconds format, # either ±DDMM±DDDMM or ±DDMMSS±DDDMMSS, # first latitude (+ is north), then longitude (+ is east). -# 3. Zone name used in value of TZ environment variable. -# Please see the theory.html file for how zone names are chosen. -# If multiple zones overlap a country, each has a row in the +# 3. Timezone name used in value of TZ environment variable. +# Please see the theory.html file for how these names are chosen. +# If multiple timezones overlap a country, each has a row in the # table, with each column 1 containing the country code. -# 4. Comments; present if and only if a country has multiple zones. +# 4. Comments; present if and only if a country has multiple timezones. # -# If a zone covers multiple countries, the most-populous city is used, +# If a timezone covers multiple countries, the most-populous city is used, # and that country is listed first in column 1; any other countries # are listed alphabetically by country code. The table is sorted # first by country code, then (if possible) by an order within the # country that (1) makes some geographical sense, and (2) puts the -# most populous zones first, where that does not contradict (1). +# most populous timezones first, where that does not contradict (1). # -# This table is intended as an aid for users, to help them select time -# zone data entries appropriate for their practical needs. It is not -# intended to take or endorse any position on legal or territorial claims. +# This table is intended as an aid for users, to help them select timezones +# appropriate for their practical needs. It is not intended to take or +# endorse any position on legal or territorial claims. # #country- #codes coordinates TZ comments @@ -231,7 +231,7 @@ MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas) MN +4801+09139 Asia/Hovd Bayan-Ölgii, Govi-Altai, Hovd, Uvs, Zavkhan MN +4804+11430 Asia/Choibalsan Dornod, Sükhbaatar -MO +2214+11335 Asia/Macau +MO +221150+1133230 Asia/Macau MQ +1436-06105 America/Martinique MT +3554+01431 Europe/Malta MU -2010+05730 Indian/Mauritius @@ -289,9 +289,9 @@ RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area RU +4457+03406 Europe/Simferopol MSK+00 - Crimea -RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd RU +5836+04939 Europe/Kirov MSK+00 - Kirov RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan +RU +4844+04425 Europe/Volgograd MSK+01 - Volgograd RU +5134+04602 Europe/Saratov MSK+01 - Saratov RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia
diff --git a/absl/time/internal/test_util.cc b/absl/time/internal/test_util.cc index bbbef7d..4483f2a 100644 --- a/absl/time/internal/test_util.cc +++ b/absl/time/internal/test_util.cc
@@ -26,12 +26,6 @@ namespace absl { namespace time_internal { -#if GTEST_USES_SIMPLE_RE -extern const char kZoneAbbrRE[] = ".*"; // just punt -#else -extern const char kZoneAbbrRE[] = "[A-Za-z]{3,4}|[-+][0-9]{2}([0-9]{2})?"; -#endif - TimeZone LoadTimeZone(const std::string& name) { TimeZone tz; ABSL_RAW_CHECK(LoadTimeZone(name, &tz), name.c_str());
diff --git a/absl/time/internal/test_util.h b/absl/time/internal/test_util.h index 8fd5fb9..d994029 100644 --- a/absl/time/internal/test_util.h +++ b/absl/time/internal/test_util.h
@@ -17,35 +17,11 @@ #include <string> -#include "gmock/gmock.h" -#include "gtest/gtest.h" #include "absl/time/time.h" -// This helper is a macro so that failed expectations show up with the -// correct line numbers. -// -// This is for internal testing of the Base Time library itself. This is not -// part of a public API. -#define ABSL_INTERNAL_EXPECT_TIME(bd, y, m, d, h, min, s, off, isdst) \ - do { \ - EXPECT_EQ(y, bd.year); \ - EXPECT_EQ(m, bd.month); \ - EXPECT_EQ(d, bd.day); \ - EXPECT_EQ(h, bd.hour); \ - EXPECT_EQ(min, bd.minute); \ - EXPECT_EQ(s, bd.second); \ - EXPECT_EQ(off, bd.offset); \ - EXPECT_EQ(isdst, bd.is_dst); \ - EXPECT_THAT(bd.zone_abbr, \ - testing::MatchesRegex(absl::time_internal::kZoneAbbrRE)); \ - } while (0) - namespace absl { namespace time_internal { -// A regular expression that matches all zone abbreviations (%Z). -extern const char kZoneAbbrRE[]; - // Loads the named timezone, but dies on any failure. absl::TimeZone LoadTimeZone(const std::string& name);
diff --git a/absl/time/time.cc b/absl/time/time.cc index 71fd8ee..ac2c8a8 100644 --- a/absl/time/time.cc +++ b/absl/time/time.cc
@@ -22,13 +22,14 @@ // NOTE: To keep type verbosity to a minimum, the following variable naming // conventions are used throughout this file. // -// cz: A cctz::time_zone // tz: An absl::TimeZone +// ci: An absl::TimeZone::CivilInfo +// ti: An absl::TimeZone::TimeInfo +// cd: An absl::CivilDay or a cctz::civil_day +// cs: An absl::CivilSecond or a cctz::civil_second +// bd: An absl::Time::Breakdown // cl: A cctz::time_zone::civil_lookup // al: A cctz::time_zone::absolute_lookup -// cd: A cctz::civil_day -// cs: A cctz::civil_second -// bd: An absl::Time::Breakdown #include "absl/time/time.h" @@ -75,7 +76,7 @@ return bd; } -inline Time::Breakdown InfinitePastBreakdown() { +inline absl::Time::Breakdown InfinitePastBreakdown() { Time::Breakdown bd; bd.year = std::numeric_limits<int64_t>::min(); bd.month = 1; @@ -92,6 +93,26 @@ return bd; } +inline absl::TimeZone::CivilInfo InfiniteFutureCivilInfo() { + TimeZone::CivilInfo ci; + ci.cs = CivilSecond::max(); + ci.subsecond = InfiniteDuration(); + ci.offset = 0; + ci.is_dst = false; + ci.zone_abbr = "-00"; + return ci; +} + +inline absl::TimeZone::CivilInfo InfinitePastCivilInfo() { + TimeZone::CivilInfo ci; + ci.cs = CivilSecond::min(); + ci.subsecond = -InfiniteDuration(); + ci.offset = 0; + ci.is_dst = false; + ci.zone_abbr = "-00"; + return ci; +} + inline absl::TimeConversion InfiniteFutureTimeConversion() { absl::TimeConversion tc; tc.pre = tc.trans = tc.post = absl::InfiniteFuture(); @@ -134,19 +155,6 @@ return time_internal::FromUnixDuration(time_internal::MakeDuration(hi)); } -inline absl::TimeConversion::Kind MapKind( - const cctz::time_zone::civil_lookup::civil_kind& kind) { - switch (kind) { - case cctz::time_zone::civil_lookup::UNIQUE: - return absl::TimeConversion::UNIQUE; - case cctz::time_zone::civil_lookup::SKIPPED: - return absl::TimeConversion::SKIPPED; - case cctz::time_zone::civil_lookup::REPEATED: - return absl::TimeConversion::REPEATED; - } - return absl::TimeConversion::UNIQUE; -} - // Returns Mon=1..Sun=7. inline int MapWeekday(const cctz::weekday& wd) { switch (wd) { @@ -168,11 +176,29 @@ return 1; } +bool FindTransition(const cctz::time_zone& tz, + bool (cctz::time_zone::*find_transition)( + const cctz::time_point<cctz::seconds>& tp, + cctz::time_zone::civil_transition* trans) const, + Time t, TimeZone::CivilTransition* trans) { + // Transitions are second-aligned, so we can discard any fractional part. + const auto tp = unix_epoch() + cctz::seconds(ToUnixSeconds(t)); + cctz::time_zone::civil_transition tr; + if (!(tz.*find_transition)(tp, &tr)) return false; + trans->from = CivilSecond(tr.from); + trans->to = CivilSecond(tr.to); + return true; +} + } // namespace +// +// Time +// + absl::Time::Breakdown Time::In(absl::TimeZone tz) const { - if (*this == absl::InfiniteFuture()) return absl::InfiniteFutureBreakdown(); - if (*this == absl::InfinitePast()) return absl::InfinitePastBreakdown(); + if (*this == absl::InfiniteFuture()) return InfiniteFutureBreakdown(); + if (*this == absl::InfinitePast()) return InfinitePastBreakdown(); const auto tp = unix_epoch() + cctz::seconds(time_internal::GetRepHi(rep_)); const auto al = cctz::time_zone(tz).lookup(tp); @@ -187,92 +213,18 @@ bd.minute = cs.minute(); bd.second = cs.second(); bd.subsecond = time_internal::MakeDuration(0, time_internal::GetRepLo(rep_)); - bd.weekday = MapWeekday(get_weekday(cd)); - bd.yearday = get_yearday(cd); + bd.weekday = MapWeekday(cctz::get_weekday(cd)); + bd.yearday = cctz::get_yearday(cd); bd.offset = al.offset; bd.is_dst = al.is_dst; bd.zone_abbr = al.abbr; return bd; } -absl::Time FromTM(const struct tm& tm, absl::TimeZone tz) { - const auto cz = cctz::time_zone(tz); - const auto cs = - cctz::civil_second(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); - const auto cl = cz.lookup(cs); - const auto tp = tm.tm_isdst == 0 ? cl.post : cl.pre; - return MakeTimeWithOverflow(tp, cs, cz); -} - -struct tm ToTM(absl::Time t, absl::TimeZone tz) { - const absl::Time::Breakdown bd = t.In(tz); - struct tm tm; - std::memset(&tm, 0, sizeof(tm)); - tm.tm_sec = bd.second; - tm.tm_min = bd.minute; - tm.tm_hour = bd.hour; - tm.tm_mday = bd.day; - tm.tm_mon = bd.month - 1; - - // Saturates tm.tm_year in cases of over/underflow, accounting for the fact - // that tm.tm_year is years since 1900. - if (bd.year < std::numeric_limits<int>::min() + 1900) { - tm.tm_year = std::numeric_limits<int>::min(); - } else if (bd.year > std::numeric_limits<int>::max()) { - tm.tm_year = std::numeric_limits<int>::max() - 1900; - } else { - tm.tm_year = static_cast<int>(bd.year - 1900); - } - - tm.tm_wday = bd.weekday % 7; - tm.tm_yday = bd.yearday - 1; - tm.tm_isdst = bd.is_dst ? 1 : 0; - - return tm; -} - // -// Factory functions. +// Conversions from/to other time types. // -absl::TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, - int min, int sec, TimeZone tz) { - // Avoids years that are too extreme for civil_second to normalize. - if (year > 300000000000) return InfiniteFutureTimeConversion(); - if (year < -300000000000) return InfinitePastTimeConversion(); - const auto cz = cctz::time_zone(tz); - const auto cs = cctz::civil_second(year, mon, day, hour, min, sec); - absl::TimeConversion tc; - tc.normalized = year != cs.year() || mon != cs.month() || day != cs.day() || - hour != cs.hour() || min != cs.minute() || sec != cs.second(); - const auto cl = cz.lookup(cs); - // Converts the civil_lookup struct to a TimeConversion. - tc.pre = MakeTimeWithOverflow(cl.pre, cs, cz, &tc.normalized); - tc.trans = MakeTimeWithOverflow(cl.trans, cs, cz, &tc.normalized); - tc.post = MakeTimeWithOverflow(cl.post, cs, cz, &tc.normalized); - tc.kind = MapKind(cl.kind); - return tc; -} - -absl::Time FromDateTime(int64_t year, int mon, int day, int hour, int min, - int sec, TimeZone tz) { - if (year > 300000000000) return InfiniteFuture(); - if (year < -300000000000) return InfinitePast(); - const auto cz = cctz::time_zone(tz); - const auto cs = cctz::civil_second(year, mon, day, hour, min, sec); - const auto cl = cz.lookup(cs); - return MakeTimeWithOverflow(cl.pre, cs, cz); -} - -absl::Time TimeFromTimespec(timespec ts) { - return time_internal::FromUnixDuration(absl::DurationFromTimespec(ts)); -} - -absl::Time TimeFromTimeval(timeval tv) { - return time_internal::FromUnixDuration(absl::DurationFromTimeval(tv)); -} - absl::Time FromUDate(double udate) { return time_internal::FromUnixDuration(absl::Milliseconds(udate)); } @@ -281,10 +233,6 @@ return absl::UniversalEpoch() + 100 * absl::Nanoseconds(universal); } -// -// Conversion to other time types. -// - int64_t ToUnixNanos(Time t) { if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 && time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 33 == 0) { @@ -321,6 +269,23 @@ time_t ToTimeT(Time t) { return absl::ToTimespec(t).tv_sec; } +double ToUDate(Time t) { + return absl::FDivDuration(time_internal::ToUnixDuration(t), + absl::Milliseconds(1)); +} + +int64_t ToUniversal(absl::Time t) { + return absl::FloorToUnit(t - absl::UniversalEpoch(), absl::Nanoseconds(100)); +} + +absl::Time TimeFromTimespec(timespec ts) { + return time_internal::FromUnixDuration(absl::DurationFromTimespec(ts)); +} + +absl::Time TimeFromTimeval(timeval tv) { + return time_internal::FromUnixDuration(absl::DurationFromTimeval(tv)); +} + timespec ToTimespec(Time t) { timespec ts; absl::Duration d = time_internal::ToUnixDuration(t); @@ -359,15 +324,6 @@ return tv; } -double ToUDate(Time t) { - return absl::FDivDuration(time_internal::ToUnixDuration(t), - absl::Milliseconds(1)); -} - -int64_t ToUniversal(absl::Time t) { - return absl::FloorToUnit(t - absl::UniversalEpoch(), absl::Nanoseconds(100)); -} - Time FromChrono(const std::chrono::system_clock::time_point& tp) { return time_internal::FromUnixDuration(time_internal::FromChrono( tp - std::chrono::system_clock::from_time_t(0))); @@ -381,4 +337,149 @@ time_internal::ToChronoDuration<D>(d); } +// +// TimeZone +// + +absl::TimeZone::CivilInfo TimeZone::At(Time t) const { + if (t == absl::InfiniteFuture()) return InfiniteFutureCivilInfo(); + if (t == absl::InfinitePast()) return InfinitePastCivilInfo(); + + const auto ud = time_internal::ToUnixDuration(t); + const auto tp = unix_epoch() + cctz::seconds(time_internal::GetRepHi(ud)); + const auto al = cz_.lookup(tp); + + TimeZone::CivilInfo ci; + ci.cs = CivilSecond(al.cs); + ci.subsecond = time_internal::MakeDuration(0, time_internal::GetRepLo(ud)); + ci.offset = al.offset; + ci.is_dst = al.is_dst; + ci.zone_abbr = al.abbr; + return ci; +} + +absl::TimeZone::TimeInfo TimeZone::At(CivilSecond ct) const { + const cctz::civil_second cs(ct); + const auto cl = cz_.lookup(cs); + + TimeZone::TimeInfo ti; + switch (cl.kind) { + case cctz::time_zone::civil_lookup::UNIQUE: + ti.kind = TimeZone::TimeInfo::UNIQUE; + break; + case cctz::time_zone::civil_lookup::SKIPPED: + ti.kind = TimeZone::TimeInfo::SKIPPED; + break; + case cctz::time_zone::civil_lookup::REPEATED: + ti.kind = TimeZone::TimeInfo::REPEATED; + break; + } + ti.pre = MakeTimeWithOverflow(cl.pre, cs, cz_); + ti.trans = MakeTimeWithOverflow(cl.trans, cs, cz_); + ti.post = MakeTimeWithOverflow(cl.post, cs, cz_); + return ti; +} + +bool TimeZone::NextTransition(Time t, CivilTransition* trans) const { + return FindTransition(cz_, &cctz::time_zone::next_transition, t, trans); +} + +bool TimeZone::PrevTransition(Time t, CivilTransition* trans) const { + return FindTransition(cz_, &cctz::time_zone::prev_transition, t, trans); +} + +// +// Conversions involving time zones. +// + +absl::TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, + int min, int sec, TimeZone tz) { + // Avoids years that are too extreme for CivilSecond to normalize. + if (year > 300000000000) return InfiniteFutureTimeConversion(); + if (year < -300000000000) return InfinitePastTimeConversion(); + + const CivilSecond cs(year, mon, day, hour, min, sec); + const auto ti = tz.At(cs); + + TimeConversion tc; + tc.pre = ti.pre; + tc.trans = ti.trans; + tc.post = ti.post; + switch (ti.kind) { + case TimeZone::TimeInfo::UNIQUE: + tc.kind = TimeConversion::UNIQUE; + break; + case TimeZone::TimeInfo::SKIPPED: + tc.kind = TimeConversion::SKIPPED; + break; + case TimeZone::TimeInfo::REPEATED: + tc.kind = TimeConversion::REPEATED; + break; + } + tc.normalized = false; + if (year != cs.year() || mon != cs.month() || day != cs.day() || + hour != cs.hour() || min != cs.minute() || sec != cs.second()) { + tc.normalized = true; + } + return tc; +} + +absl::Time FromTM(const struct tm& tm, absl::TimeZone tz) { + const CivilSecond cs(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + const auto ti = tz.At(cs); + return tm.tm_isdst == 0 ? ti.post : ti.pre; +} + +struct tm ToTM(absl::Time t, absl::TimeZone tz) { + struct tm tm = {}; + + const auto ci = tz.At(t); + const auto& cs = ci.cs; + tm.tm_sec = cs.second(); + tm.tm_min = cs.minute(); + tm.tm_hour = cs.hour(); + tm.tm_mday = cs.day(); + tm.tm_mon = cs.month() - 1; + + // Saturates tm.tm_year in cases of over/underflow, accounting for the fact + // that tm.tm_year is years since 1900. + if (cs.year() < std::numeric_limits<int>::min() + 1900) { + tm.tm_year = std::numeric_limits<int>::min(); + } else if (cs.year() > std::numeric_limits<int>::max()) { + tm.tm_year = std::numeric_limits<int>::max() - 1900; + } else { + tm.tm_year = static_cast<int>(cs.year() - 1900); + } + + const CivilDay cd(cs); + switch (GetWeekday(cd)) { + case Weekday::sunday: + tm.tm_wday = 0; + break; + case Weekday::monday: + tm.tm_wday = 1; + break; + case Weekday::tuesday: + tm.tm_wday = 2; + break; + case Weekday::wednesday: + tm.tm_wday = 3; + break; + case Weekday::thursday: + tm.tm_wday = 4; + break; + case Weekday::friday: + tm.tm_wday = 5; + break; + case Weekday::saturday: + tm.tm_wday = 6; + break; + } + tm.tm_yday = GetYearDay(cd) - 1; + tm.tm_isdst = ci.is_dst ? 1 : 0; + + return tm; +} + } // namespace absl
diff --git a/absl/time/time.h b/absl/time/time.h index 50bf971..ae3b3fa 100644 --- a/absl/time/time.h +++ b/absl/time/time.h
@@ -25,18 +25,29 @@ // * `absl::TimeZone` defines geopolitical time zone regions (as collected // within the IANA Time Zone database (https://www.iana.org/time-zones)). // +// Note: Absolute times are distinct from civil times, which refer to the +// human-scale time commonly represented by `YYYY-MM-DD hh:mm:ss`. The mapping +// between absolute and civil times can be specified by use of time zones +// (`absl::TimeZone` within this API). That is: +// +// Civil Time = F(Absolute Time, Time Zone) +// Absolute Time = G(Civil Time, Time Zone) +// +// See civil_time.h for abstractions related to constructing and manipulating +// civil time. // // Example: // // absl::TimeZone nyc; -// // // LoadTimeZone() may fail so it's always better to check for success. // if (!absl::LoadTimeZone("America/New_York", &nyc)) { // // handle error case // } // // // My flight leaves NYC on Jan 2, 2017 at 03:04:05 -// absl::Time takeoff = absl::FromDateTime(2017, 1, 2, 3, 4, 5, nyc); +// absl::CivilSecond cs(2017, 1, 2, 3, 4, 5); +// absl::Time takeoff = absl::FromCivil(cs, nyc); +// // absl::Duration flight_duration = absl::Hours(21) + absl::Minutes(35); // absl::Time landing = takeoff + flight_duration; // @@ -48,6 +59,7 @@ // "My flight will land in Sydney on %Y-%m-%d at %H:%M:%S", // landing, syd); // + #ifndef ABSL_TIME_TIME_H_ #define ABSL_TIME_TIME_H_ @@ -57,6 +69,7 @@ #include <winsock2.h> #endif #include <chrono> // NOLINT(build/c++11) +#include <cmath> #include <cstdint> #include <ctime> #include <ostream> @@ -66,6 +79,7 @@ #include "absl/base/port.h" // Needed for string vs std::string #include "absl/strings/string_view.h" +#include "absl/time/civil_time.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" namespace absl { @@ -140,6 +154,16 @@ // Value semantics. constexpr Duration() : rep_hi_(0), rep_lo_(0) {} // zero-length duration + // Copyable. +#if !defined(__clang__) && defined(_MSC_VER) && _MSC_VER < 1910 + // Explicitly defining the constexpr copy constructor avoids an MSVC bug. + constexpr Duration(const Duration& d) + : rep_hi_(d.rep_hi_), rep_lo_(d.rep_lo_) {} +#else + constexpr Duration(const Duration& d) = default; +#endif + Duration& operator=(const Duration& d) = default; + // Compound assignment operators. Duration& operator+=(Duration d); Duration& operator-=(Duration d); @@ -348,11 +372,11 @@ // Factory functions for constructing `Duration` values from an integral number // of the unit indicated by the factory function's name. // -// Note: no "Days()" factory function exists because "a day" is ambiguous. Civil -// days are not always 24 hours long, and a 24-hour duration often does not -// correspond with a civil day. If a 24-hour duration is needed, use -// `absl::Hours(24)`. -// +// Note: no "Days()" factory function exists because "a day" is ambiguous. +// Civil days are not always 24 hours long, and a 24-hour duration often does +// not correspond with a civil day. If a 24-hour duration is needed, use +// `absl::Hours(24)`. (If you actually want a civil day, use absl::CivilDay +// from civil_time.h.) // // Example: // @@ -371,6 +395,7 @@ // factories, which should be preferred. // // Example: +// // auto a = absl::Seconds(1.5); // OK // auto b = absl::Milliseconds(1500); // BETTER template <typename T, time_internal::EnableIfFloat<T> = 0> @@ -387,11 +412,13 @@ } template <typename T, time_internal::EnableIfFloat<T> = 0> Duration Seconds(T n) { - if (n >= 0) { - if (n >= std::numeric_limits<int64_t>::max()) return InfiniteDuration(); + if (n >= 0) { // Note: `NaN >= 0` is false. + if (n >= (std::numeric_limits<int64_t>::max)()) return InfiniteDuration(); return time_internal::MakePosDoubleDuration(n); } else { - if (n <= std::numeric_limits<int64_t>::min()) return -InfiniteDuration(); + if (std::isnan(n)) + return std::signbit(n) ? -InfiniteDuration() : InfiniteDuration(); + if (n <= (std::numeric_limits<int64_t>::min)()) return -InfiniteDuration(); return -time_internal::MakePosDoubleDuration(-n); } } @@ -546,7 +573,7 @@ // // `absl::Time` uses a resolution that is high enough to avoid loss in // precision, and a range that is wide enough to avoid overflow, when -// converting between tick counts in most Google time scales (i.e., precision +// converting between tick counts in most Google time scales (i.e., resolution // of at least one nanosecond, and range +/-100 billion years). Conversions // between the time scales are performed by truncating (towards negative // infinity) to the nearest representable point. @@ -556,7 +583,6 @@ // absl::Time t1 = ...; // absl::Time t2 = t1 + absl::Minutes(2); // absl::Duration d = t2 - t1; // == absl::Minutes(2) -// absl::Time::Breakdown bd = t1.In(absl::LocalTimeZone()); // class Time { public: @@ -571,7 +597,11 @@ // absl::Time t = absl::Now(); // absl::Time t = absl::TimeFromTimeval(tv); // absl::Time t = absl::InfinitePast(); - constexpr Time() {} + constexpr Time() = default; + + // Copyable. + constexpr Time(const Time& t) = default; + Time& operator=(const Time& t) = default; // Assignment operators. Time& operator+=(Duration d) { @@ -590,7 +620,10 @@ // intended to represent an instant in time. So, rather than passing // a `Time::Breakdown` to a function, pass an `absl::Time` and an // `absl::TimeZone`. - struct Breakdown { + // + // Deprecated. Use `absl::TimeZone::CivilInfo`. + struct + Breakdown { int64_t year; // year (e.g., 2013) int month; // month of year [1:12] int day; // day of month [1:31] @@ -614,6 +647,8 @@ // Time::In() // // Returns the breakdown of this instant in the given TimeZone. + // + // Deprecated. Use `absl::TimeZone::At(Time)`. Breakdown In(TimeZone tz) const; template <typename H> @@ -668,7 +703,7 @@ // Returns an `absl::Time` that is infinitely far in the future. constexpr Time InfiniteFuture() { return Time( - time_internal::MakeDuration(std::numeric_limits<int64_t>::max(), ~0U)); + time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U)); } // InfinitePast() @@ -676,129 +711,9 @@ // Returns an `absl::Time` that is infinitely far in the past. constexpr Time InfinitePast() { return Time( - time_internal::MakeDuration(std::numeric_limits<int64_t>::min(), ~0U)); + time_internal::MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U)); } -// TimeConversion -// -// An `absl::TimeConversion` represents the conversion of year, month, day, -// hour, minute, and second values (i.e., a civil time), in a particular -// `absl::TimeZone`, to a time instant (an absolute time), as returned by -// `absl::ConvertDateTime()`. (Subseconds must be handled separately.) -// -// It is possible, though, for a caller to try to convert values that -// do not represent an actual or unique instant in time (due to a shift -// in UTC offset in the `absl::TimeZone`, which results in a discontinuity in -// the civil-time components). For example, a daylight-saving-time -// transition skips or repeats civil times---in the United States, March -// 13, 2011 02:15 never occurred, while November 6, 2011 01:15 occurred -// twice---so requests for such times are not well-defined. -// -// To account for these possibilities, `absl::TimeConversion` is richer -// than just a single `absl::Time`. When the civil time is skipped or -// repeated, `absl::ConvertDateTime()` returns times calculated using the -// pre-transition and post-transition UTC offsets, plus the transition -// time itself. -// -// Examples: -// -// absl::TimeZone lax; -// if (!absl::LoadTimeZone("America/Los_Angeles", &lax)) { -// // handle error case -// } -// -// // A unique civil time -// absl::TimeConversion jan01 = -// absl::ConvertDateTime(2011, 1, 1, 0, 0, 0, lax); -// // jan01.kind == TimeConversion::UNIQUE -// // jan01.pre is 2011/01/01 00:00:00 -0800 -// // jan01.trans is 2011/01/01 00:00:00 -0800 -// // jan01.post is 2011/01/01 00:00:00 -0800 -// -// // A Spring DST transition, when there is a gap in civil time -// absl::TimeConversion mar13 = -// absl::ConvertDateTime(2011, 3, 13, 2, 15, 0, lax); -// // mar13.kind == TimeConversion::SKIPPED -// // mar13.pre is 2011/03/13 03:15:00 -0700 -// // mar13.trans is 2011/03/13 03:00:00 -0700 -// // mar13.post is 2011/03/13 01:15:00 -0800 -// -// // A Fall DST transition, when civil times are repeated -// absl::TimeConversion nov06 = -// absl::ConvertDateTime(2011, 11, 6, 1, 15, 0, lax); -// // nov06.kind == TimeConversion::REPEATED -// // nov06.pre is 2011/11/06 01:15:00 -0700 -// // nov06.trans is 2011/11/06 01:00:00 -0800 -// // nov06.post is 2011/11/06 01:15:00 -0800 -// -// The input month, day, hour, minute, and second values can also be -// outside of their valid ranges, in which case they will be "normalized" -// during the conversion. -// -// Example: -// -// // "October 32" normalizes to "November 1". -// absl::TimeZone tz = absl::LocalTimeZone(); -// absl::TimeConversion tc = -// absl::ConvertDateTime(2013, 10, 32, 8, 30, 0, tz); -// // tc.kind == TimeConversion::UNIQUE && tc.normalized == true -// // tc.pre.In(tz).month == 11 && tc.pre.In(tz).day == 1 -struct TimeConversion { - Time pre; // time calculated using the pre-transition offset - Time trans; // when the civil-time discontinuity occurred - Time post; // time calculated using the post-transition offset - - enum Kind { - UNIQUE, // the civil time was singular (pre == trans == post) - SKIPPED, // the civil time did not exist - REPEATED, // the civil time was ambiguous - }; - Kind kind; - - bool normalized; // input values were outside their valid ranges -}; - -// ConvertDateTime() -// -// The full generality of a civil time to absl::Time conversion. -TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, - int min, int sec, TimeZone tz); - -// FromDateTime() -// -// A convenience wrapper for `absl::ConvertDateTime()` that simply returns the -// "pre" `absl::Time`. That is, the unique result, or the instant that -// is correct using the pre-transition offset (as if the transition -// never happened). This is typically the answer that humans expected when -// faced with non-unique times, such as near daylight-saving time transitions. -// -// Example: -// -// absl::TimeZone seattle; -// if (!absl::LoadTimeZone("America/Los_Angeles", &seattle)) { -// // handle error case -// } -// absl::Time t = absl::FromDateTime(2017, 9, 26, 9, 30, 0, seattle); -Time FromDateTime(int64_t year, int mon, int day, int hour, int min, int sec, - TimeZone tz); - -// FromTM() -// -// Converts the `tm_year`, `tm_mon`, `tm_mday`, `tm_hour`, `tm_min`, and -// `tm_sec` fields to an `absl::Time` using the given time zone. See ctime(3) -// for a description of the expected values of the tm fields. IFF the indicated -// time instant is not unique (see `absl::ConvertDateTime()` above), the -// `tm_isdst` field is consulted to select the desired instant (`tm_isdst` > 0 -// means DST, `tm_isdst` == 0 means no DST, `tm_isdst` < 0 means use the default -// like `absl::FromDateTime()`). -Time FromTM(const struct tm& tm, TimeZone tz); - -// ToTM() -// -// Converts the given `absl::Time` to a struct tm using the given time zone. -// See ctime(3) for a description of the values of the tm fields. -struct tm ToTM(Time t, TimeZone tz); - // FromUnixNanos() // FromUnixMicros() // FromUnixMillis() @@ -883,140 +798,6 @@ // // tp == std::chrono::system_clock::from_time_t(123); std::chrono::system_clock::time_point ToChronoTime(Time); -// RFC3339_full -// RFC3339_sec -// -// FormatTime()/ParseTime() format specifiers for RFC3339 date/time strings, -// with trailing zeros trimmed or with fractional seconds omitted altogether. -// -// Note that RFC3339_sec[] matches an ISO 8601 extended format for date and -// time with UTC offset. Also note the use of "%Y": RFC3339 mandates that -// years have exactly four digits, but we allow them to take their natural -// width. -extern const char RFC3339_full[]; // %Y-%m-%dT%H:%M:%E*S%Ez -extern const char RFC3339_sec[]; // %Y-%m-%dT%H:%M:%S%Ez - -// RFC1123_full -// RFC1123_no_wday -// -// FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings. -extern const char RFC1123_full[]; // %a, %d %b %E4Y %H:%M:%S %z -extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z - -// FormatTime() -// -// Formats the given `absl::Time` in the `absl::TimeZone` according to the -// provided format string. Uses strftime()-like formatting options, with -// the following extensions: -// -// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm) -// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss) -// - %E#S - Seconds with # digits of fractional precision -// - %E*S - Seconds with full fractional precision (a literal '*') -// - %E#f - Fractional seconds with # digits of precision -// - %E*f - Fractional seconds with full precision (a literal '*') -// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) -// -// Note that %E0S behaves like %S, and %E0f produces no characters. In -// contrast %E*f always produces at least one digit, which may be '0'. -// -// Note that %Y produces as many characters as it takes to fully render the -// year. A year outside of [-999:9999] when formatted with %E4Y will produce -// more than four characters, just like %Y. -// -// We recommend that format strings include the UTC offset (%z, %Ez, or %E*z) -// so that the result uniquely identifies a time instant. -// -// Example: -// -// absl::TimeZone lax; -// if (!absl::LoadTimeZone("America/Los_Angeles", &lax)) { -// // handle error case -// } -// absl::Time t = absl::FromDateTime(2013, 1, 2, 3, 4, 5, lax); -// -// string f = absl::FormatTime("%H:%M:%S", t, lax); // "03:04:05" -// f = absl::FormatTime("%H:%M:%E3S", t, lax); // "03:04:05.000" -// -// Note: If the given `absl::Time` is `absl::InfiniteFuture()`, the returned -// string will be exactly "infinite-future". If the given `absl::Time` is -// `absl::InfinitePast()`, the returned string will be exactly "infinite-past". -// In both cases the given format string and `absl::TimeZone` are ignored. -// -std::string FormatTime(const std::string& format, Time t, TimeZone tz); - -// Convenience functions that format the given time using the RFC3339_full -// format. The first overload uses the provided TimeZone, while the second -// uses LocalTimeZone(). -std::string FormatTime(Time t, TimeZone tz); -std::string FormatTime(Time t); - -// Output stream operator. -inline std::ostream& operator<<(std::ostream& os, Time t) { - return os << FormatTime(t); -} - -// ParseTime() -// -// Parses an input string according to the provided format string and -// returns the corresponding `absl::Time`. Uses strftime()-like formatting -// options, with the same extensions as FormatTime(), but with the -// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez -// and %E*z also accept the same inputs. -// -// %Y consumes as many numeric characters as it can, so the matching data -// should always be terminated with a non-numeric. %E4Y always consumes -// exactly four characters, including any sign. -// -// Unspecified fields are taken from the default date and time of ... -// -// "1970-01-01 00:00:00.0 +0000" -// -// For example, parsing a string of "15:45" (%H:%M) will return an absl::Time -// that represents "1970-01-01 15:45:00.0 +0000". -// -// Note that since ParseTime() returns time instants, it makes the most sense -// to parse fully-specified date/time strings that include a UTC offset (%z, -// %Ez, or %E*z). -// -// Note also that `absl::ParseTime()` only heeds the fields year, month, day, -// hour, minute, (fractional) second, and UTC offset. Other fields, like -// weekday (%a or %A), while parsed for syntactic validity, are ignored -// in the conversion. -// -// Date and time fields that are out-of-range will be treated as errors -// rather than normalizing them like `absl::FromDateTime()` does. For example, -// it is an error to parse the date "Oct 32, 2013" because 32 is out of range. -// -// A leap second of ":60" is normalized to ":00" of the following minute -// with fractional seconds discarded. The following table shows how the -// given seconds and subseconds will be parsed: -// -// "59.x" -> 59.x // exact -// "60.x" -> 00.0 // normalized -// "00.x" -> 00.x // exact -// -// Errors are indicated by returning false and assigning an error message -// to the "err" out param if it is non-null. -// -// Note: If the input string is exactly "infinite-future", the returned -// `absl::Time` will be `absl::InfiniteFuture()` and `true` will be returned. -// If the input string is "infinite-past", the returned `absl::Time` will be -// `absl::InfinitePast()` and `true` will be returned. -// -bool ParseTime(const std::string& format, const std::string& input, Time* time, - std::string* err); - -// Like ParseTime() above, but if the format string does not contain a UTC -// offset specification (%z/%Ez/%E*z) then the input is interpreted in the -// given TimeZone. This means that the input, by itself, does not identify a -// unique instant. Being time-zone dependent, it also admits the possibility -// of ambiguity or non-existence, in which case the "pre" time (as defined -// for ConvertDateTime()) is returned. For these reasons we recommend that -// all date/time strings include a UTC offset so they're context independent. -bool ParseTime(const std::string& format, const std::string& input, TimeZone tz, - Time* time, std::string* err); - // Support for flag values of type Time. Time flags must be specified in a // format that matches absl::RFC3339_full. For example: // @@ -1062,6 +843,8 @@ public: explicit TimeZone(time_internal::cctz::time_zone tz) : cz_(tz) {} TimeZone() = default; // UTC, but prefer UTCTimeZone() to be explicit. + + // Copyable. TimeZone(const TimeZone&) = default; TimeZone& operator=(const TimeZone&) = default; @@ -1069,6 +852,136 @@ std::string name() const { return cz_.name(); } + // TimeZone::CivilInfo + // + // Information about the civil time corresponding to an absolute time. + // This struct is not intended to represent an instant in time. So, rather + // than passing a `TimeZone::CivilInfo` to a function, pass an `absl::Time` + // and an `absl::TimeZone`. + struct CivilInfo { + CivilSecond cs; + Duration subsecond; + + // Note: The following fields exist for backward compatibility + // with older APIs. Accessing these fields directly is a sign of + // imprudent logic in the calling code. Modern time-related code + // should only access this data indirectly by way of FormatTime(). + // These fields are undefined for InfiniteFuture() and InfinitePast(). + int offset; // seconds east of UTC + bool is_dst; // is offset non-standard? + const char* zone_abbr; // time-zone abbreviation (e.g., "PST") + }; + + // TimeZone::At(Time) + // + // Returns the civil time for this TimeZone at a certain `absl::Time`. + // If the input time is infinite, the output civil second will be set to + // CivilSecond::max() or min(), and the subsecond will be infinite. + // + // Example: + // + // const auto epoch = lax.At(absl::UnixEpoch()); + // // epoch.cs == 1969-12-31 16:00:00 + // // epoch.subsecond == absl::ZeroDuration() + // // epoch.offset == -28800 + // // epoch.is_dst == false + // // epoch.abbr == "PST" + CivilInfo At(Time t) const; + + // TimeZone::TimeInfo + // + // Information about the absolute times corresponding to a civil time. + // (Subseconds must be handled separately.) + // + // It is possible for a caller to pass a civil-time value that does + // not represent an actual or unique instant in time (due to a shift + // in UTC offset in the TimeZone, which results in a discontinuity in + // the civil-time components). For example, a daylight-saving-time + // transition skips or repeats civil times---in the United States, + // March 13, 2011 02:15 never occurred, while November 6, 2011 01:15 + // occurred twice---so requests for such times are not well-defined. + // To account for these possibilities, `absl::TimeZone::TimeInfo` is + // richer than just a single `absl::Time`. + struct TimeInfo { + enum CivilKind { + UNIQUE, // the civil time was singular (pre == trans == post) + SKIPPED, // the civil time did not exist (pre >= trans > post) + REPEATED, // the civil time was ambiguous (pre < trans <= post) + } kind; + Time pre; // time calculated using the pre-transition offset + Time trans; // when the civil-time discontinuity occurred + Time post; // time calculated using the post-transition offset + }; + + // TimeZone::At(CivilSecond) + // + // Returns an `absl::TimeInfo` containing the absolute time(s) for this + // TimeZone at an `absl::CivilSecond`. When the civil time is skipped or + // repeated, returns times calculated using the pre-transition and post- + // transition UTC offsets, plus the transition time itself. + // + // Examples: + // + // // A unique civil time + // const auto jan01 = lax.At(absl::CivilSecond(2011, 1, 1, 0, 0, 0)); + // // jan01.kind == TimeZone::TimeInfo::UNIQUE + // // jan01.pre is 2011-01-01 00:00:00 -0800 + // // jan01.trans is 2011-01-01 00:00:00 -0800 + // // jan01.post is 2011-01-01 00:00:00 -0800 + // + // // A Spring DST transition, when there is a gap in civil time + // const auto mar13 = lax.At(absl::CivilSecond(2011, 3, 13, 2, 15, 0)); + // // mar13.kind == TimeZone::TimeInfo::SKIPPED + // // mar13.pre is 2011-03-13 03:15:00 -0700 + // // mar13.trans is 2011-03-13 03:00:00 -0700 + // // mar13.post is 2011-03-13 01:15:00 -0800 + // + // // A Fall DST transition, when civil times are repeated + // const auto nov06 = lax.At(absl::CivilSecond(2011, 11, 6, 1, 15, 0)); + // // nov06.kind == TimeZone::TimeInfo::REPEATED + // // nov06.pre is 2011-11-06 01:15:00 -0700 + // // nov06.trans is 2011-11-06 01:00:00 -0800 + // // nov06.post is 2011-11-06 01:15:00 -0800 + TimeInfo At(CivilSecond ct) const; + + // TimeZone::NextTransition() + // TimeZone::PrevTransition() + // + // Finds the time of the next/previous offset change in this time zone. + // + // By definition, `NextTransition(t, &trans)` returns false when `t` is + // `InfiniteFuture()`, and `PrevTransition(t, &trans)` returns false + // when `t` is `InfinitePast()`. If the zone has no transitions, the + // result will also be false no matter what the argument. + // + // Otherwise, when `t` is `InfinitePast()`, `NextTransition(t, &trans)` + // returns true and sets `trans` to the first recorded transition. Chains + // of calls to `NextTransition()/PrevTransition()` will eventually return + // false, but it is unspecified exactly when `NextTransition(t, &trans)` + // jumps to false, or what time is set by `PrevTransition(t, &trans)` for + // a very distant `t`. + // + // Note: Enumeration of time-zone transitions is for informational purposes + // only. Modern time-related code should not care about when offset changes + // occur. + // + // Example: + // absl::TimeZone nyc; + // if (!absl::LoadTimeZone("America/New_York", &nyc)) { ... } + // const auto now = absl::Now(); + // auto t = absl::InfinitePast(); + // absl::TimeZone::CivilTransition trans; + // while (t <= now && nyc.NextTransition(t, &trans)) { + // // transition: trans.from -> trans.to + // t = nyc.At(trans.to).trans; + // } + struct CivilTransition { + CivilSecond from; // the civil time we jump from + CivilSecond to; // the civil time we jump to + }; + bool NextTransition(Time t, CivilTransition* trans) const; + bool PrevTransition(Time t, CivilTransition* trans) const; + template <typename H> friend H AbslHashValue(H h, TimeZone tz) { return H::combine(std::move(h), tz.cz_); @@ -1127,6 +1040,268 @@ return TimeZone(time_internal::cctz::local_time_zone()); } +// ToCivilSecond() +// ToCivilMinute() +// ToCivilHour() +// ToCivilDay() +// ToCivilMonth() +// ToCivilYear() +// +// Helpers for TimeZone::At(Time) to return particularly aligned civil times. +// +// Example: +// +// absl::Time t = ...; +// absl::TimeZone tz = ...; +// const auto cd = absl::ToCivilDay(t, tz); +inline CivilSecond ToCivilSecond(Time t, TimeZone tz) { + return tz.At(t).cs; // already a CivilSecond +} +inline CivilMinute ToCivilMinute(Time t, TimeZone tz) { + return CivilMinute(tz.At(t).cs); +} +inline CivilHour ToCivilHour(Time t, TimeZone tz) { + return CivilHour(tz.At(t).cs); +} +inline CivilDay ToCivilDay(Time t, TimeZone tz) { + return CivilDay(tz.At(t).cs); +} +inline CivilMonth ToCivilMonth(Time t, TimeZone tz) { + return CivilMonth(tz.At(t).cs); +} +inline CivilYear ToCivilYear(Time t, TimeZone tz) { + return CivilYear(tz.At(t).cs); +} + +// FromCivil() +// +// Helper for TimeZone::At(CivilSecond) that provides "order-preserving +// semantics." If the civil time maps to a unique time, that time is +// returned. If the civil time is repeated in the given time zone, the +// time using the pre-transition offset is returned. Otherwise, the +// civil time is skipped in the given time zone, and the transition time +// is returned. This means that for any two civil times, ct1 and ct2, +// (ct1 < ct2) => (FromCivil(ct1) <= FromCivil(ct2)), the equal case +// being when two non-existent civil times map to the same transition time. +// +// Note: Accepts civil times of any alignment. +inline Time FromCivil(CivilSecond ct, TimeZone tz) { + const auto ti = tz.At(ct); + if (ti.kind == TimeZone::TimeInfo::SKIPPED) return ti.trans; + return ti.pre; +} + +// TimeConversion +// +// An `absl::TimeConversion` represents the conversion of year, month, day, +// hour, minute, and second values (i.e., a civil time), in a particular +// `absl::TimeZone`, to a time instant (an absolute time), as returned by +// `absl::ConvertDateTime()`. Lecacy version of `absl::TimeZone::TimeInfo`. +// +// Deprecated. Use `absl::TimeZone::TimeInfo`. +struct + TimeConversion { + Time pre; // time calculated using the pre-transition offset + Time trans; // when the civil-time discontinuity occurred + Time post; // time calculated using the post-transition offset + + enum Kind { + UNIQUE, // the civil time was singular (pre == trans == post) + SKIPPED, // the civil time did not exist + REPEATED, // the civil time was ambiguous + }; + Kind kind; + + bool normalized; // input values were outside their valid ranges +}; + +// ConvertDateTime() +// +// Legacy version of `absl::TimeZone::At(absl::CivilSecond)` that takes +// the civil time as six, separate values (YMDHMS). +// +// The input month, day, hour, minute, and second values can be outside +// of their valid ranges, in which case they will be "normalized" during +// the conversion. +// +// Example: +// +// // "October 32" normalizes to "November 1". +// absl::TimeConversion tc = +// absl::ConvertDateTime(2013, 10, 32, 8, 30, 0, lax); +// // tc.kind == TimeConversion::UNIQUE && tc.normalized == true +// // absl::ToCivilDay(tc.pre, tz).month() == 11 +// // absl::ToCivilDay(tc.pre, tz).day() == 1 +// +// Deprecated. Use `absl::TimeZone::At(CivilSecond)`. +TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, + int min, int sec, TimeZone tz); + +// FromDateTime() +// +// A convenience wrapper for `absl::ConvertDateTime()` that simply returns +// the "pre" `absl::Time`. That is, the unique result, or the instant that +// is correct using the pre-transition offset (as if the transition never +// happened). +// +// Example: +// +// absl::Time t = absl::FromDateTime(2017, 9, 26, 9, 30, 0, lax); +// // t = 2017-09-26 09:30:00 -0700 +// +// Deprecated. Use `absl::TimeZone::At(CivilSecond).pre`. +inline Time FromDateTime(int64_t year, int mon, int day, int hour, + int min, int sec, TimeZone tz) { + return ConvertDateTime(year, mon, day, hour, min, sec, tz).pre; +} + +// FromTM() +// +// Converts the `tm_year`, `tm_mon`, `tm_mday`, `tm_hour`, `tm_min`, and +// `tm_sec` fields to an `absl::Time` using the given time zone. See ctime(3) +// for a description of the expected values of the tm fields. If the indicated +// time instant is not unique (see `absl::TimeZone::At(absl::CivilSecond)` +// above), the `tm_isdst` field is consulted to select the desired instant +// (`tm_isdst` > 0 means DST, `tm_isdst` == 0 means no DST, `tm_isdst` < 0 +// means use the post-transition offset). +Time FromTM(const struct tm& tm, TimeZone tz); + +// ToTM() +// +// Converts the given `absl::Time` to a struct tm using the given time zone. +// See ctime(3) for a description of the values of the tm fields. +struct tm ToTM(Time t, TimeZone tz); + +// RFC3339_full +// RFC3339_sec +// +// FormatTime()/ParseTime() format specifiers for RFC3339 date/time strings, +// with trailing zeros trimmed or with fractional seconds omitted altogether. +// +// Note that RFC3339_sec[] matches an ISO 8601 extended format for date and +// time with UTC offset. Also note the use of "%Y": RFC3339 mandates that +// years have exactly four digits, but we allow them to take their natural +// width. +extern const char RFC3339_full[]; // %Y-%m-%dT%H:%M:%E*S%Ez +extern const char RFC3339_sec[]; // %Y-%m-%dT%H:%M:%S%Ez + +// RFC1123_full +// RFC1123_no_wday +// +// FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings. +extern const char RFC1123_full[]; // %a, %d %b %E4Y %H:%M:%S %z +extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z + +// FormatTime() +// +// Formats the given `absl::Time` in the `absl::TimeZone` according to the +// provided format string. Uses strftime()-like formatting options, with +// the following extensions: +// +// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm) +// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss) +// - %E#S - Seconds with # digits of fractional precision +// - %E*S - Seconds with full fractional precision (a literal '*') +// - %E#f - Fractional seconds with # digits of precision +// - %E*f - Fractional seconds with full precision (a literal '*') +// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) +// +// Note that %E0S behaves like %S, and %E0f produces no characters. In +// contrast %E*f always produces at least one digit, which may be '0'. +// +// Note that %Y produces as many characters as it takes to fully render the +// year. A year outside of [-999:9999] when formatted with %E4Y will produce +// more than four characters, just like %Y. +// +// We recommend that format strings include the UTC offset (%z, %Ez, or %E*z) +// so that the result uniquely identifies a time instant. +// +// Example: +// +// absl::CivilSecond cs(2013, 1, 2, 3, 4, 5); +// absl::Time t = absl::FromCivil(cs, lax); +// string f = absl::FormatTime("%H:%M:%S", t, lax); // "03:04:05" +// f = absl::FormatTime("%H:%M:%E3S", t, lax); // "03:04:05.000" +// +// Note: If the given `absl::Time` is `absl::InfiniteFuture()`, the returned +// string will be exactly "infinite-future". If the given `absl::Time` is +// `absl::InfinitePast()`, the returned string will be exactly "infinite-past". +// In both cases the given format string and `absl::TimeZone` are ignored. +// +std::string FormatTime(const std::string& format, Time t, TimeZone tz); + +// Convenience functions that format the given time using the RFC3339_full +// format. The first overload uses the provided TimeZone, while the second +// uses LocalTimeZone(). +std::string FormatTime(Time t, TimeZone tz); +std::string FormatTime(Time t); + +// Output stream operator. +inline std::ostream& operator<<(std::ostream& os, Time t) { + return os << FormatTime(t); +} + +// ParseTime() +// +// Parses an input string according to the provided format string and +// returns the corresponding `absl::Time`. Uses strftime()-like formatting +// options, with the same extensions as FormatTime(), but with the +// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez +// and %E*z also accept the same inputs. +// +// %Y consumes as many numeric characters as it can, so the matching data +// should always be terminated with a non-numeric. %E4Y always consumes +// exactly four characters, including any sign. +// +// Unspecified fields are taken from the default date and time of ... +// +// "1970-01-01 00:00:00.0 +0000" +// +// For example, parsing a string of "15:45" (%H:%M) will return an absl::Time +// that represents "1970-01-01 15:45:00.0 +0000". +// +// Note that since ParseTime() returns time instants, it makes the most sense +// to parse fully-specified date/time strings that include a UTC offset (%z, +// %Ez, or %E*z). +// +// Note also that `absl::ParseTime()` only heeds the fields year, month, day, +// hour, minute, (fractional) second, and UTC offset. Other fields, like +// weekday (%a or %A), while parsed for syntactic validity, are ignored +// in the conversion. +// +// Date and time fields that are out-of-range will be treated as errors +// rather than normalizing them like `absl::CivilSecond` does. For example, +// it is an error to parse the date "Oct 32, 2013" because 32 is out of range. +// +// A leap second of ":60" is normalized to ":00" of the following minute +// with fractional seconds discarded. The following table shows how the +// given seconds and subseconds will be parsed: +// +// "59.x" -> 59.x // exact +// "60.x" -> 00.0 // normalized +// "00.x" -> 00.x // exact +// +// Errors are indicated by returning false and assigning an error message +// to the "err" out param if it is non-null. +// +// Note: If the input string is exactly "infinite-future", the returned +// `absl::Time` will be `absl::InfiniteFuture()` and `true` will be returned. +// If the input string is "infinite-past", the returned `absl::Time` will be +// `absl::InfinitePast()` and `true` will be returned. +// +bool ParseTime(const std::string& format, const std::string& input, Time* time, + std::string* err); + +// Like ParseTime() above, but if the format string does not contain a UTC +// offset specification (%z/%Ez/%E*z) then the input is interpreted in the +// given TimeZone. This means that the input, by itself, does not identify a +// unique instant. Being time-zone dependent, it also admits the possibility +// of ambiguity or non-existence, in which case the "pre" time (as defined +// by TimeZone::TimeInfo) is returned. For these reasons we recommend that +// all date/time strings include a UTC offset so they're context independent. +bool ParseTime(const std::string& format, const std::string& input, TimeZone tz, + Time* time, std::string* err); + // ============================================================================ // Implementation Details Follow // ============================================================================ @@ -1164,17 +1339,20 @@ return (ticks < 0) ? MakeDuration(sec - 1, ticks + kTicksPerSecond) : MakeDuration(sec, ticks); } + // Provide access to the Duration representation. constexpr int64_t GetRepHi(Duration d) { return d.rep_hi_; } constexpr uint32_t GetRepLo(Duration d) { return d.rep_lo_; } + +// Returns true iff d is positive or negative infinity. constexpr bool IsInfiniteDuration(Duration d) { return GetRepLo(d) == ~0U; } // Returns an infinite Duration with the opposite sign. // REQUIRES: IsInfiniteDuration(d) constexpr Duration OppositeInfinity(Duration d) { return GetRepHi(d) < 0 - ? MakeDuration(std::numeric_limits<int64_t>::max(), ~0U) - : MakeDuration(std::numeric_limits<int64_t>::min(), ~0U); + ? MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U) + : MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U); } // Returns (-n)-1 (equivalently -(n+1)) without avoidable overflow. @@ -1199,14 +1377,14 @@ v / N, v % N * kTicksPerNanosecond * 1000 * 1000 * 1000 / N); } constexpr Duration FromInt64(int64_t v, std::ratio<60>) { - return (v <= std::numeric_limits<int64_t>::max() / 60 && - v >= std::numeric_limits<int64_t>::min() / 60) + return (v <= (std::numeric_limits<int64_t>::max)() / 60 && + v >= (std::numeric_limits<int64_t>::min)() / 60) ? MakeDuration(v * 60) : v > 0 ? InfiniteDuration() : -InfiniteDuration(); } constexpr Duration FromInt64(int64_t v, std::ratio<3600>) { - return (v <= std::numeric_limits<int64_t>::max() / 3600 && - v >= std::numeric_limits<int64_t>::min() / 3600) + return (v <= (std::numeric_limits<int64_t>::max)() / 3600 && + v >= (std::numeric_limits<int64_t>::min)() / 3600) ? MakeDuration(v * 3600) : v > 0 ? InfiniteDuration() : -InfiniteDuration(); } @@ -1263,10 +1441,10 @@ using Period = typename T::period; static_assert(IsValidRep64<Rep>(0), "duration::rep is invalid"); if (time_internal::IsInfiniteDuration(d)) - return d < ZeroDuration() ? T::min() : T::max(); + return d < ZeroDuration() ? (T::min)() : (T::max)(); const auto v = ToInt64(d, Period{}); - if (v > std::numeric_limits<Rep>::max()) return T::max(); - if (v < std::numeric_limits<Rep>::min()) return T::min(); + if (v > (std::numeric_limits<Rep>::max)()) return (T::max)(); + if (v < (std::numeric_limits<Rep>::min)()) return (T::min)(); return T{v}; } @@ -1293,7 +1471,8 @@ constexpr bool operator<(Duration lhs, Duration rhs) { return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs) ? time_internal::GetRepHi(lhs) < time_internal::GetRepHi(rhs) - : time_internal::GetRepHi(lhs) == std::numeric_limits<int64_t>::min() + : time_internal::GetRepHi(lhs) == + (std::numeric_limits<int64_t>::min)() ? time_internal::GetRepLo(lhs) + 1 < time_internal::GetRepLo(rhs) + 1 : time_internal::GetRepLo(lhs) < @@ -1318,7 +1497,8 @@ // a second's worth of ticks and avoid overflow (as negating int64_t-min + 1 // is safe). return time_internal::GetRepLo(d) == 0 - ? time_internal::GetRepHi(d) == std::numeric_limits<int64_t>::min() + ? time_internal::GetRepHi(d) == + (std::numeric_limits<int64_t>::min)() ? InfiniteDuration() : time_internal::MakeDuration(-time_internal::GetRepHi(d)) : time_internal::IsInfiniteDuration(d) @@ -1331,7 +1511,8 @@ } constexpr Duration InfiniteDuration() { - return time_internal::MakeDuration(std::numeric_limits<int64_t>::max(), ~0U); + return time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(), + ~0U); } constexpr Duration FromChrono(const std::chrono::nanoseconds& d) {
diff --git a/absl/time/time_benchmark.cc b/absl/time/time_benchmark.cc index e100994..9bbed6f 100644 --- a/absl/time/time_benchmark.cc +++ b/absl/time/time_benchmark.cc
@@ -169,32 +169,32 @@ BENCHMARK(BM_Time_ToUnixSeconds); // -// FromDateTime +// FromCivil // -// 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_). +// In each "FromCivil" benchmark we switch between two YMDhms values +// separated by at least one transition in order to defeat any internal +// caching of previous results (e.g., see time_local_hint_). // // The "UTC" variants use UTC instead of the Google/local time zone. // The "Day0" variants require normalization of the day of month. // -void BM_Time_FromDateTime_Absl(benchmark::State& state) { +void BM_Time_FromCivil_Absl(benchmark::State& state) { const absl::TimeZone tz = absl::time_internal::LoadTimeZone("America/Los_Angeles"); int i = 0; while (state.KeepRunning()) { if ((i & 1) == 0) { - absl::FromDateTime(2014, 12, 18, 20, 16, 18, tz); + absl::FromCivil(absl::CivilSecond(2014, 12, 18, 20, 16, 18), tz); } else { - absl::FromDateTime(2013, 11, 15, 18, 30, 27, tz); + absl::FromCivil(absl::CivilSecond(2013, 11, 15, 18, 30, 27), tz); } ++i; } } -BENCHMARK(BM_Time_FromDateTime_Absl); +BENCHMARK(BM_Time_FromCivil_Absl); -void BM_Time_FromDateTime_Libc(benchmark::State& state) { +void BM_Time_FromCivil_Libc(benchmark::State& state) { // No timezone support, so just use localtime. int i = 0; while (state.KeepRunning()) { @@ -219,32 +219,32 @@ ++i; } } -BENCHMARK(BM_Time_FromDateTime_Libc); +BENCHMARK(BM_Time_FromCivil_Libc); -void BM_Time_FromDateTimeUTC_Absl(benchmark::State& state) { +void BM_Time_FromCivilUTC_Absl(benchmark::State& state) { const absl::TimeZone tz = absl::UTCTimeZone(); while (state.KeepRunning()) { - FromDateTime(2014, 12, 18, 20, 16, 18, tz); + absl::FromCivil(absl::CivilSecond(2014, 12, 18, 20, 16, 18), tz); } } -BENCHMARK(BM_Time_FromDateTimeUTC_Absl); +BENCHMARK(BM_Time_FromCivilUTC_Absl); -void BM_Time_FromDateTimeDay0_Absl(benchmark::State& state) { +void BM_Time_FromCivilDay0_Absl(benchmark::State& state) { const absl::TimeZone tz = absl::time_internal::LoadTimeZone("America/Los_Angeles"); int i = 0; while (state.KeepRunning()) { if ((i & 1) == 0) { - absl::FromDateTime(2014, 12, 0, 20, 16, 18, tz); + absl::FromCivil(absl::CivilSecond(2014, 12, 0, 20, 16, 18), tz); } else { - absl::FromDateTime(2013, 11, 0, 18, 30, 27, tz); + absl::FromCivil(absl::CivilSecond(2013, 11, 0, 18, 30, 27), tz); } ++i; } } -BENCHMARK(BM_Time_FromDateTimeDay0_Absl); +BENCHMARK(BM_Time_FromCivilDay0_Absl); -void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) { +void BM_Time_FromCivilDay0_Libc(benchmark::State& state) { // No timezone support, so just use localtime. int i = 0; while (state.KeepRunning()) { @@ -269,7 +269,7 @@ ++i; } } -BENCHMARK(BM_Time_FromDateTimeDay0_Libc); +BENCHMARK(BM_Time_FromCivilDay0_Libc); // // To/FromTimespec
diff --git a/absl/time/time_norm_test.cc b/absl/time/time_norm_test.cc deleted file mode 100644 index 4436242..0000000 --- a/absl/time/time_norm_test.cc +++ /dev/null
@@ -1,306 +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 tests for FromDateTime() normalization, which is -// time-zone independent so we just use UTC throughout. - -#include <cstdint> -#include <limits> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/time/internal/test_util.h" -#include "absl/time/time.h" - -namespace { - -TEST(TimeNormCase, SimpleOverflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = - absl::ConvertDateTime(2013, 11, 15, 16, 32, 59 + 1, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 16, 33, 0, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16, 59 + 1, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 17, 0, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 23 + 1, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 16, 0, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 30 + 1, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 12, 1, 16, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 12 + 1, 15, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2014, 1, 15, 16, 32, 14, 0, false); -} - -TEST(TimeNormCase, SimpleUnderflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = ConvertDateTime(2013, 11, 15, 16, 32, 0 - 1, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 16, 31, 59, 0, false); - - tc = ConvertDateTime(2013, 11, 15, 16, 0 - 1, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 15, 59, 14, 0, false); - - tc = ConvertDateTime(2013, 11, 15, 0 - 1, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 14, 23, 32, 14, 0, false); - - tc = ConvertDateTime(2013, 11, 1 - 1, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 10, 31, 16, 32, 14, 0, false); - - tc = ConvertDateTime(2013, 1 - 1, 15, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2012, 12, 15, 16, 32, 14, 0, false); -} - -TEST(TimeNormCase, MultipleOverflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - absl::TimeConversion tc = ConvertDateTime(2013, 12, 31, 23, 59, 59 + 1, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2014, 1, 1, 0, 0, 0, 0, false); -} - -TEST(TimeNormCase, MultipleUnderflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - absl::TimeConversion tc = absl::ConvertDateTime(2014, 1, 1, 0, 0, 0 - 1, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 12, 31, 23, 59, 59, 0, false); -} - -TEST(TimeNormCase, OverflowLimits) { - const absl::TimeZone utc = absl::UTCTimeZone(); - absl::TimeConversion tc; - absl::Time::Breakdown bd; - - const int kintmax = std::numeric_limits<int>::max(); - tc = absl::ConvertDateTime(0, kintmax, kintmax, kintmax, kintmax, kintmax, - utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 185085715, 11, 27, 12, 21, 7, 0, false); - - const int kintmin = std::numeric_limits<int>::min(); - tc = absl::ConvertDateTime(0, kintmin, kintmin, kintmin, kintmin, kintmin, - utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, -185085717, 10, 31, 10, 37, 52, 0, false); - - const int64_t max_year = std::numeric_limits<int64_t>::max(); - tc = absl::ConvertDateTime(max_year, 12, 31, 23, 59, 59, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - EXPECT_EQ(absl::InfiniteFuture(), tc.pre); - - const int64_t min_year = std::numeric_limits<int64_t>::min(); - tc = absl::ConvertDateTime(min_year, 1, 1, 0, 0, 0, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - EXPECT_EQ(absl::InfinitePast(), tc.pre); -} - -TEST(TimeNormCase, ComplexOverflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = - ConvertDateTime(2013, 11, 15, 16, 32, 14 + 123456789, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2017, 10, 14, 14, 5, 23, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16, 32 + 1234567, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2016, 3, 22, 0, 39, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16 + 123456, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2027, 12, 16, 16, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15 + 1234, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2017, 4, 2, 16, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11 + 123, 15, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2024, 2, 15, 16, 32, 14, 0, false); -} - -TEST(TimeNormCase, ComplexUnderflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = - absl::ConvertDateTime(1999, 3, 0, 0, 0, 0, utc); // year 400 - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 1999, 2, 28, 0, 0, 0, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16, 32, 14 - 123456789, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2009, 12, 17, 18, 59, 5, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16, 32 - 1234567, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2011, 7, 12, 8, 25, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16 - 123456, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 1999, 10, 16, 16, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15 - 1234, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2010, 6, 30, 16, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11 - 123, 15, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2003, 8, 15, 16, 32, 14, 0, false); -} - -TEST(TimeNormCase, Mishmash) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = - absl::ConvertDateTime(2013, 11 - 123, 15 + 1234, 16 - 123456, - 32 + 1234567, 14 - 123456789, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 1991, 5, 9, 3, 6, 5, 0, false); - - tc = absl::ConvertDateTime(2013, 11 + 123, 15 - 1234, 16 + 123456, - 32 - 1234567, 14 + 123456789, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2036, 5, 24, 5, 58, 23, 0, false); - - // Here is a normalization case we got wrong for a while. Because the - // day is converted to "1" within a 400-year (146097-day) period, we - // didn't need to roll the month and so we didn't mark it as normalized. - tc = absl::ConvertDateTime(2013, 11, -146097 + 1, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 1613, 11, 1, 16, 32, 14, 0, false); - - // Even though the month overflow compensates for the day underflow, - // this should still be marked as normalized. - tc = absl::ConvertDateTime(2013, 11 + 400 * 12, -146097 + 1, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 1, 16, 32, 14, 0, false); -} - -TEST(TimeNormCase, LeapYears) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = - absl::ConvertDateTime(2013, 2, 28 + 1, 0, 0, 0, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 3, 1, 0, 0, 0, 0, false); - - tc = absl::ConvertDateTime(2012, 2, 28 + 1, 0, 0, 0, utc); - EXPECT_FALSE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2012, 2, 29, 0, 0, 0, 0, false); - - tc = absl::ConvertDateTime(2000, 2, 28 + 1, 0, 0, 0, utc); - EXPECT_FALSE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2000, 2, 29, 0, 0, 0, 0, false); - - tc = absl::ConvertDateTime(1900, 2, 28 + 1, 0, 0, 0, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 1900, 3, 1, 0, 0, 0, 0, false); -} - -// Convert all the days from 1970-1-1 to 1970-1-146097 (aka 2369-12-31) -// and check that they normalize to the expected time. 146097 days span -// the 400-year Gregorian cycle used during normalization. -TEST(TimeNormCase, AllTheDays) { - const absl::TimeZone utc = absl::UTCTimeZone(); - absl::Time exp_time = absl::UnixEpoch(); - - for (int day = 1; day <= 146097; ++day) { - absl::TimeConversion tc = absl::ConvertDateTime(1970, 1, day, 0, 0, 0, utc); - EXPECT_EQ(day > 31, tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - EXPECT_EQ(exp_time, tc.pre); - exp_time += absl::Hours(24); - } -} - -} // namespace
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc index 4f8f58a..4d71070 100644 --- a/absl/time/time_test.cc +++ b/absl/time/time_test.cc
@@ -28,6 +28,27 @@ namespace { +#if GTEST_USES_SIMPLE_RE +const char kZoneAbbrRE[] = ".*"; // just punt +#else +const char kZoneAbbrRE[] = "[A-Za-z]{3,4}|[-+][0-9]{2}([0-9]{2})?"; +#endif + +// This helper is a macro so that failed expectations show up with the +// correct line numbers. +#define EXPECT_CIVIL_INFO(ci, y, m, d, h, min, s, off, isdst) \ + do { \ + EXPECT_EQ(y, ci.cs.year()); \ + EXPECT_EQ(m, ci.cs.month()); \ + EXPECT_EQ(d, ci.cs.day()); \ + EXPECT_EQ(h, ci.cs.hour()); \ + EXPECT_EQ(min, ci.cs.minute()); \ + EXPECT_EQ(s, ci.cs.second()); \ + EXPECT_EQ(off, ci.offset); \ + EXPECT_EQ(isdst, ci.is_dst); \ + EXPECT_THAT(ci.zone_abbr, testing::MatchesRegex(kZoneAbbrRE)); \ + } while (0) + // A gMock matcher to match timespec values. Use this matcher like: // timespec ts1, ts2; // EXPECT_THAT(ts1, TimespecMatcher(ts2)); @@ -84,10 +105,10 @@ } TEST(Time, UnixEpoch) { - absl::Time::Breakdown bd = absl::UnixEpoch().In(absl::UTCTimeZone()); - ABSL_INTERNAL_EXPECT_TIME(bd, 1970, 1, 1, 0, 0, 0, 0, false); - EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); - EXPECT_EQ(4, bd.weekday); // Thursday + const auto ci = absl::UTCTimeZone().At(absl::UnixEpoch()); + EXPECT_EQ(absl::CivilSecond(1970, 1, 1, 0, 0, 0), ci.cs); + EXPECT_EQ(absl::ZeroDuration(), ci.subsecond); + EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(absl::CivilDay(ci.cs))); } TEST(Time, Breakdown) { @@ -95,26 +116,26 @@ absl::Time t = absl::UnixEpoch(); // The Unix epoch as seen in NYC. - absl::Time::Breakdown bd = t.In(tz); - ABSL_INTERNAL_EXPECT_TIME(bd, 1969, 12, 31, 19, 0, 0, -18000, false); - EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); - EXPECT_EQ(3, bd.weekday); // Wednesday + auto ci = tz.At(t); + EXPECT_CIVIL_INFO(ci, 1969, 12, 31, 19, 0, 0, -18000, false); + EXPECT_EQ(absl::ZeroDuration(), ci.subsecond); + EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(absl::CivilDay(ci.cs))); // Just before the epoch. t -= absl::Nanoseconds(1); - bd = t.In(tz); - ABSL_INTERNAL_EXPECT_TIME(bd, 1969, 12, 31, 18, 59, 59, -18000, false); - EXPECT_EQ(absl::Nanoseconds(999999999), bd.subsecond); - EXPECT_EQ(3, bd.weekday); // Wednesday + ci = tz.At(t); + EXPECT_CIVIL_INFO(ci, 1969, 12, 31, 18, 59, 59, -18000, false); + EXPECT_EQ(absl::Nanoseconds(999999999), ci.subsecond); + EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(absl::CivilDay(ci.cs))); // Some time later. t += absl::Hours(24) * 2735; t += absl::Hours(18) + absl::Minutes(30) + absl::Seconds(15) + absl::Nanoseconds(9); - bd = t.In(tz); - ABSL_INTERNAL_EXPECT_TIME(bd, 1977, 6, 28, 14, 30, 15, -14400, true); - EXPECT_EQ(8, bd.subsecond / absl::Nanoseconds(1)); - EXPECT_EQ(2, bd.weekday); // Tuesday + ci = tz.At(t); + EXPECT_CIVIL_INFO(ci, 1977, 6, 28, 14, 30, 15, -14400, true); + EXPECT_EQ(8, ci.subsecond / absl::Nanoseconds(1)); + EXPECT_EQ(absl::Weekday::tuesday, absl::GetWeekday(absl::CivilDay(ci.cs))); } TEST(Time, AdditiveOperators) { @@ -550,67 +571,63 @@ absl::ToChronoTime(absl::UnixEpoch() - tick)); } -TEST(Time, ConvertDateTime) { - const absl::TimeZone utc = absl::UTCTimeZone(); - const absl::TimeZone goog = - absl::time_internal::LoadTimeZone("America/Los_Angeles"); +TEST(Time, TimeZoneAt) { const absl::TimeZone nyc = absl::time_internal::LoadTimeZone("America/New_York"); const std::string fmt = "%a, %e %b %Y %H:%M:%S %z (%Z)"; - // A simple case of normalization. - absl::TimeConversion oct32 = ConvertDateTime(2013, 10, 32, 8, 30, 0, goog); - EXPECT_TRUE(oct32.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, oct32.kind); - absl::TimeConversion nov01 = ConvertDateTime(2013, 11, 1, 8, 30, 0, goog); - EXPECT_FALSE(nov01.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, nov01.kind); - EXPECT_EQ(oct32.pre, nov01.pre); - EXPECT_EQ("Fri, 1 Nov 2013 08:30:00 -0700 (PDT)", - absl::FormatTime(fmt, nov01.pre, goog)); + // A non-transition where the civil time is unique. + absl::CivilSecond nov01(2013, 11, 1, 8, 30, 0); + const auto nov01_ci = nyc.At(nov01); + EXPECT_EQ(absl::TimeZone::TimeInfo::UNIQUE, nov01_ci.kind); + EXPECT_EQ("Fri, 1 Nov 2013 08:30:00 -0400 (EDT)", + absl::FormatTime(fmt, nov01_ci.pre, nyc)); + EXPECT_EQ(nov01_ci.pre, nov01_ci.trans); + EXPECT_EQ(nov01_ci.pre, nov01_ci.post); + EXPECT_EQ(nov01_ci.pre, absl::FromCivil(nov01, nyc)); // A Spring DST transition, when there is a gap in civil time // and we prefer the later of the possible interpretations of a // non-existent time. - absl::TimeConversion mar13 = ConvertDateTime(2011, 3, 13, 2, 15, 0, nyc); - EXPECT_FALSE(mar13.normalized); - EXPECT_EQ(absl::TimeConversion::SKIPPED, mar13.kind); + absl::CivilSecond mar13(2011, 3, 13, 2, 15, 0); + const auto mar_ci = nyc.At(mar13); + EXPECT_EQ(absl::TimeZone::TimeInfo::SKIPPED, mar_ci.kind); EXPECT_EQ("Sun, 13 Mar 2011 03:15:00 -0400 (EDT)", - absl::FormatTime(fmt, mar13.pre, nyc)); + absl::FormatTime(fmt, mar_ci.pre, nyc)); EXPECT_EQ("Sun, 13 Mar 2011 03:00:00 -0400 (EDT)", - absl::FormatTime(fmt, mar13.trans, nyc)); + absl::FormatTime(fmt, mar_ci.trans, nyc)); EXPECT_EQ("Sun, 13 Mar 2011 01:15:00 -0500 (EST)", - absl::FormatTime(fmt, mar13.post, nyc)); - EXPECT_EQ(mar13.pre, absl::FromDateTime(2011, 3, 13, 2, 15, 0, nyc)); + absl::FormatTime(fmt, mar_ci.post, nyc)); + EXPECT_EQ(mar_ci.trans, absl::FromCivil(mar13, nyc)); // A Fall DST transition, when civil times are repeated and // we prefer the earlier of the possible interpretations of an // ambiguous time. - absl::TimeConversion nov06 = ConvertDateTime(2011, 11, 6, 1, 15, 0, nyc); - EXPECT_FALSE(nov06.normalized); - EXPECT_EQ(absl::TimeConversion::REPEATED, nov06.kind); + absl::CivilSecond nov06(2011, 11, 6, 1, 15, 0); + const auto nov06_ci = nyc.At(nov06); + EXPECT_EQ(absl::TimeZone::TimeInfo::REPEATED, nov06_ci.kind); EXPECT_EQ("Sun, 6 Nov 2011 01:15:00 -0400 (EDT)", - absl::FormatTime(fmt, nov06.pre, nyc)); + absl::FormatTime(fmt, nov06_ci.pre, nyc)); EXPECT_EQ("Sun, 6 Nov 2011 01:00:00 -0500 (EST)", - absl::FormatTime(fmt, nov06.trans, nyc)); + absl::FormatTime(fmt, nov06_ci.trans, nyc)); EXPECT_EQ("Sun, 6 Nov 2011 01:15:00 -0500 (EST)", - absl::FormatTime(fmt, nov06.post, nyc)); - EXPECT_EQ(nov06.pre, absl::FromDateTime(2011, 11, 6, 1, 15, 0, nyc)); + absl::FormatTime(fmt, nov06_ci.post, nyc)); + EXPECT_EQ(nov06_ci.pre, absl::FromCivil(nov06, nyc)); // Check that (time_t) -1 is handled correctly. - absl::TimeConversion minus1 = ConvertDateTime(1969, 12, 31, 18, 59, 59, nyc); - EXPECT_FALSE(minus1.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, minus1.kind); - EXPECT_EQ(-1, absl::ToTimeT(minus1.pre)); + absl::CivilSecond minus1(1969, 12, 31, 18, 59, 59); + const auto minus1_cl = nyc.At(minus1); + EXPECT_EQ(absl::TimeZone::TimeInfo::UNIQUE, minus1_cl.kind); + EXPECT_EQ(-1, absl::ToTimeT(minus1_cl.pre)); EXPECT_EQ("Wed, 31 Dec 1969 18:59:59 -0500 (EST)", - absl::FormatTime(fmt, minus1.pre, nyc)); + absl::FormatTime(fmt, minus1_cl.pre, nyc)); EXPECT_EQ("Wed, 31 Dec 1969 23:59:59 +0000 (UTC)", - absl::FormatTime(fmt, minus1.pre, utc)); + absl::FormatTime(fmt, minus1_cl.pre, absl::UTCTimeZone())); } -// FromDateTime(year, mon, day, hour, min, sec, UTCTimeZone()) has -// a specialized fastpath implementation which we exercise here. -TEST(Time, FromDateTimeUTC) { +// FromCivil(CivilSecond(year, mon, day, hour, min, sec), UTCTimeZone()) +// has a specialized fastpath implementation, which we exercise here. +TEST(Time, FromCivilUTC) { const absl::TimeZone utc = absl::UTCTimeZone(); const std::string fmt = "%a, %e %b %Y %H:%M:%S %z (%Z)"; const int kMax = std::numeric_limits<int>::max(); @@ -618,65 +635,36 @@ absl::Time t; // 292091940881 is the last positive year to use the fastpath. - t = absl::FromDateTime(292091940881, kMax, kMax, kMax, kMax, kMax, utc); + t = absl::FromCivil( + absl::CivilSecond(292091940881, kMax, kMax, kMax, kMax, kMax), utc); EXPECT_EQ("Fri, 25 Nov 292277026596 12:21:07 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - t = absl::FromDateTime(292091940882, kMax, kMax, kMax, kMax, kMax, utc); - EXPECT_EQ("infinite-future", absl::FormatTime(fmt, t, utc)); // no overflow - t = absl::FromDateTime( - std::numeric_limits<int64_t>::max(), kMax, kMax, kMax, kMax, kMax, utc); + t = absl::FromCivil( + absl::CivilSecond(292091940882, kMax, kMax, kMax, kMax, kMax), utc); EXPECT_EQ("infinite-future", absl::FormatTime(fmt, t, utc)); // no overflow // -292091936940 is the last negative year to use the fastpath. - t = absl::FromDateTime(-292091936940, kMin, kMin, kMin, kMin, kMin, utc); + t = absl::FromCivil( + absl::CivilSecond(-292091936940, kMin, kMin, kMin, kMin, kMin), utc); EXPECT_EQ("Fri, 1 Nov -292277022657 10:37:52 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - t = absl::FromDateTime(-292091936941, kMin, kMin, kMin, kMin, kMin, utc); + t = absl::FromCivil( + absl::CivilSecond(-292091936941, kMin, kMin, kMin, kMin, kMin), utc); EXPECT_EQ("infinite-past", absl::FormatTime(fmt, t, utc)); // no underflow - t = absl::FromDateTime( - std::numeric_limits<int64_t>::min(), kMin, kMin, kMin, kMin, kMin, utc); - EXPECT_EQ("infinite-past", absl::FormatTime(fmt, t, utc)); // no overflow // Check that we're counting leap years correctly. - t = absl::FromDateTime(1900, 2, 28, 23, 59, 59, utc); + t = absl::FromCivil(absl::CivilSecond(1900, 2, 28, 23, 59, 59), utc); EXPECT_EQ("Wed, 28 Feb 1900 23:59:59 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - t = absl::FromDateTime(1900, 3, 1, 0, 0, 0, utc); + t = absl::FromCivil(absl::CivilSecond(1900, 3, 1, 0, 0, 0), utc); EXPECT_EQ("Thu, 1 Mar 1900 00:00:00 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - t = absl::FromDateTime(2000, 2, 29, 23, 59, 59, utc); + t = absl::FromCivil(absl::CivilSecond(2000, 2, 29, 23, 59, 59), utc); EXPECT_EQ("Tue, 29 Feb 2000 23:59:59 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - t = absl::FromDateTime(2000, 3, 1, 0, 0, 0, utc); + t = absl::FromCivil(absl::CivilSecond(2000, 3, 1, 0, 0, 0), utc); EXPECT_EQ("Wed, 1 Mar 2000 00:00:00 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - - // Check normalization. - const std::string ymdhms = "%Y-%m-%d %H:%M:%S"; - t = absl::FromDateTime(2015, 1, 1, 0, 0, 60, utc); - EXPECT_EQ("2015-01-01 00:01:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 1, 0, 60, 0, utc); - EXPECT_EQ("2015-01-01 01:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 1, 24, 0, 0, utc); - EXPECT_EQ("2015-01-02 00:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 32, 0, 0, 0, utc); - EXPECT_EQ("2015-02-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 13, 1, 0, 0, 0, utc); - EXPECT_EQ("2016-01-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 13, 32, 60, 60, 60, utc); - EXPECT_EQ("2016-02-03 13:01:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 1, 0, 0, -1, utc); - EXPECT_EQ("2014-12-31 23:59:59", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 1, 0, -1, 0, utc); - EXPECT_EQ("2014-12-31 23:59:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 1, -1, 0, 0, utc); - EXPECT_EQ("2014-12-31 23:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, -1, 0, 0, 0, utc); - EXPECT_EQ("2014-12-30 00:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, -1, 1, 0, 0, 0, utc); - EXPECT_EQ("2014-11-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, -1, -1, -1, -1, -1, utc); - EXPECT_EQ("2014-10-29 22:58:59", absl::FormatTime(ymdhms, t, utc)); } TEST(Time, ToTM) { @@ -684,8 +672,10 @@ // Compares the results of ToTM() to gmtime_r() for lots of times over the // course of a few days. - const absl::Time start = absl::FromDateTime(2014, 1, 2, 3, 4, 5, utc); - const absl::Time end = absl::FromDateTime(2014, 1, 5, 3, 4, 5, utc); + const absl::Time start = + absl::FromCivil(absl::CivilSecond(2014, 1, 2, 3, 4, 5), utc); + const absl::Time end = + absl::FromCivil(absl::CivilSecond(2014, 1, 5, 3, 4, 5), utc); for (absl::Time t = start; t < end; t += absl::Seconds(30)) { const struct tm tm_bt = ToTM(t, utc); const time_t tt = absl::ToTimeT(t); @@ -711,12 +701,12 @@ // Checks that the tm_isdst field is correct when in standard time. const absl::TimeZone nyc = absl::time_internal::LoadTimeZone("America/New_York"); - absl::Time t = absl::FromDateTime(2014, 3, 1, 0, 0, 0, nyc); + absl::Time t = absl::FromCivil(absl::CivilSecond(2014, 3, 1, 0, 0, 0), nyc); struct tm tm = ToTM(t, nyc); EXPECT_FALSE(tm.tm_isdst); // Checks that the tm_isdst field is correct when in daylight time. - t = absl::FromDateTime(2014, 4, 1, 0, 0, 0, nyc); + t = absl::FromCivil(absl::CivilSecond(2014, 4, 1, 0, 0, 0), nyc); tm = ToTM(t, nyc); EXPECT_TRUE(tm.tm_isdst); @@ -808,8 +798,8 @@ absl::time_internal::LoadTimeZone("America/New_York"); // Test round-tripping across a skipped transition - absl::Time start = absl::FromDateTime(2014, 3, 9, 0, 0, 0, nyc); - absl::Time end = absl::FromDateTime(2014, 3, 9, 4, 0, 0, nyc); + absl::Time start = absl::FromCivil(absl::CivilHour(2014, 3, 9, 0), nyc); + absl::Time end = absl::FromCivil(absl::CivilHour(2014, 3, 9, 4), nyc); for (absl::Time t = start; t < end; t += absl::Minutes(1)) { struct tm tm = ToTM(t, nyc); absl::Time rt = FromTM(tm, nyc); @@ -817,8 +807,8 @@ } // Test round-tripping across an ambiguous transition - start = absl::FromDateTime(2014, 11, 2, 0, 0, 0, nyc); - end = absl::FromDateTime(2014, 11, 2, 4, 0, 0, nyc); + start = absl::FromCivil(absl::CivilHour(2014, 11, 2, 0), nyc); + end = absl::FromCivil(absl::CivilHour(2014, 11, 2, 4), nyc); for (absl::Time t = start; t < end; t += absl::Minutes(1)) { struct tm tm = ToTM(t, nyc); absl::Time rt = FromTM(tm, nyc); @@ -826,8 +816,8 @@ } // Test round-tripping of unique instants crossing a day boundary - start = absl::FromDateTime(2014, 6, 27, 22, 0, 0, nyc); - end = absl::FromDateTime(2014, 6, 28, 4, 0, 0, nyc); + start = absl::FromCivil(absl::CivilHour(2014, 6, 27, 22), nyc); + end = absl::FromCivil(absl::CivilHour(2014, 6, 28, 4), nyc); for (absl::Time t = start; t < end; t += absl::Minutes(1)) { struct tm tm = ToTM(t, nyc); absl::Time rt = FromTM(tm, nyc); @@ -980,27 +970,27 @@ EXPECT_EQ(min_timespec_sec, ts.tv_sec); EXPECT_EQ(0, ts.tv_nsec); - // Checks how Time::In() saturates on infinities. - absl::Time::Breakdown bd = absl::InfiniteFuture().In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, std::numeric_limits<int64_t>::max(), 12, 31, 23, + // Checks how TimeZone::At() saturates on infinities. + auto ci = utc.At(absl::InfiniteFuture()); + EXPECT_CIVIL_INFO(ci, std::numeric_limits<int64_t>::max(), 12, 31, 23, 59, 59, 0, false); - EXPECT_EQ(absl::InfiniteDuration(), bd.subsecond); - EXPECT_EQ(4, bd.weekday); // Thursday - EXPECT_EQ(365, bd.yearday); - EXPECT_STREQ("-00", bd.zone_abbr); // artifact of absl::Time::In() - bd = absl::InfinitePast().In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, std::numeric_limits<int64_t>::min(), 1, 1, 0, 0, + EXPECT_EQ(absl::InfiniteDuration(), ci.subsecond); + EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(absl::CivilDay(ci.cs))); + EXPECT_EQ(365, absl::GetYearDay(absl::CivilDay(ci.cs))); + EXPECT_STREQ("-00", ci.zone_abbr); // artifact of TimeZone::At() + ci = utc.At(absl::InfinitePast()); + EXPECT_CIVIL_INFO(ci, std::numeric_limits<int64_t>::min(), 1, 1, 0, 0, 0, 0, false); - EXPECT_EQ(-absl::InfiniteDuration(), bd.subsecond); - EXPECT_EQ(7, bd.weekday); // Sunday - EXPECT_EQ(1, bd.yearday); - EXPECT_STREQ("-00", bd.zone_abbr); // artifact of absl::Time::In() + EXPECT_EQ(-absl::InfiniteDuration(), ci.subsecond); + EXPECT_EQ(absl::Weekday::sunday, absl::GetWeekday(absl::CivilDay(ci.cs))); + EXPECT_EQ(1, absl::GetYearDay(absl::CivilDay(ci.cs))); + EXPECT_STREQ("-00", ci.zone_abbr); // artifact of TimeZone::At() // Approach the maximal Time value from below. - t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 6, utc); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 15, 30, 6), utc); EXPECT_EQ("292277026596-12-04T15:30:06+00:00", absl::FormatTime(absl::RFC3339_full, t, utc)); - t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 7, utc); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 15, 30, 7), utc); EXPECT_EQ("292277026596-12-04T15:30:07+00:00", absl::FormatTime(absl::RFC3339_full, t, utc)); EXPECT_EQ( @@ -1008,21 +998,21 @@ // Checks that we can also get the maximal Time value for a far-east zone. const absl::TimeZone plus14 = absl::FixedTimeZone(14 * 60 * 60); - t = absl::FromDateTime(292277026596, 12, 5, 5, 30, 7, plus14); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 5, 30, 7), plus14); EXPECT_EQ("292277026596-12-05T05:30:07+14:00", absl::FormatTime(absl::RFC3339_full, t, plus14)); EXPECT_EQ( absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()), t); // One second later should push us to infinity. - t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 8, utc); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 15, 30, 8), utc); EXPECT_EQ("infinite-future", absl::FormatTime(absl::RFC3339_full, t, utc)); // Approach the minimal Time value from above. - t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 53, utc); + t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 27, 8, 29, 53), utc); EXPECT_EQ("-292277022657-01-27T08:29:53+00:00", absl::FormatTime(absl::RFC3339_full, t, utc)); - t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 52, utc); + t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 27, 8, 29, 52), utc); EXPECT_EQ("-292277022657-01-27T08:29:52+00:00", absl::FormatTime(absl::RFC3339_full, t, utc)); EXPECT_EQ( @@ -1030,14 +1020,15 @@ // Checks that we can also get the minimal Time value for a far-west zone. const absl::TimeZone minus12 = absl::FixedTimeZone(-12 * 60 * 60); - t = absl::FromDateTime(-292277022657, 1, 26, 20, 29, 52, minus12); + t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 26, 20, 29, 52), + minus12); EXPECT_EQ("-292277022657-01-26T20:29:52-12:00", absl::FormatTime(absl::RFC3339_full, t, minus12)); EXPECT_EQ( absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()), t); // One second before should push us to -infinity. - t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 51, utc); + t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 27, 8, 29, 51), utc); EXPECT_EQ("infinite-past", absl::FormatTime(absl::RFC3339_full, t, utc)); } @@ -1051,38 +1042,160 @@ absl::time_internal::LoadTimeZone("America/New_York"); const absl::Time max = absl::FromUnixSeconds(std::numeric_limits<int64_t>::max()); - absl::Time::Breakdown bd; + absl::TimeZone::CivilInfo ci; absl::Time t; // The maximal time converted in each zone. - bd = max.In(syd); - ABSL_INTERNAL_EXPECT_TIME(bd, 292277026596, 12, 5, 2, 30, 7, 39600, true); - t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 7, syd); + ci = syd.At(max); + EXPECT_CIVIL_INFO(ci, 292277026596, 12, 5, 2, 30, 7, 39600, true); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 2, 30, 7), syd); EXPECT_EQ(max, t); - bd = max.In(nyc); - ABSL_INTERNAL_EXPECT_TIME(bd, 292277026596, 12, 4, 10, 30, 7, -18000, false); - t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 7, nyc); + ci = nyc.At(max); + EXPECT_CIVIL_INFO(ci, 292277026596, 12, 4, 10, 30, 7, -18000, false); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 10, 30, 7), nyc); EXPECT_EQ(max, t); // One second later should push us to infinity. - t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 8, syd); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 2, 30, 8), syd); EXPECT_EQ(absl::InfiniteFuture(), t); - t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 8, nyc); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 10, 30, 8), nyc); EXPECT_EQ(absl::InfiniteFuture(), t); // And we should stick there. - t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 9, syd); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 2, 30, 9), syd); EXPECT_EQ(absl::InfiniteFuture(), t); - t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 9, nyc); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 10, 30, 9), nyc); EXPECT_EQ(absl::InfiniteFuture(), t); // All the way up to a saturated date/time, without overflow. - t = absl::FromDateTime( - std::numeric_limits<int64_t>::max(), 12, 31, 23, 59, 59, syd); + t = absl::FromCivil(absl::CivilSecond::max(), syd); EXPECT_EQ(absl::InfiniteFuture(), t); - t = absl::FromDateTime( - std::numeric_limits<int64_t>::max(), 12, 31, 23, 59, 59, nyc); + t = absl::FromCivil(absl::CivilSecond::max(), nyc); EXPECT_EQ(absl::InfiniteFuture(), t); } +TEST(Time, FromCivilAlignment) { + const absl::TimeZone utc = absl::UTCTimeZone(); + const absl::CivilSecond cs(2015, 2, 3, 4, 5, 6); + absl::Time t = absl::FromCivil(cs, utc); + EXPECT_EQ("2015-02-03T04:05:06+00:00", absl::FormatTime(t, utc)); + t = absl::FromCivil(absl::CivilMinute(cs), utc); + EXPECT_EQ("2015-02-03T04:05:00+00:00", absl::FormatTime(t, utc)); + t = absl::FromCivil(absl::CivilHour(cs), utc); + EXPECT_EQ("2015-02-03T04:00:00+00:00", absl::FormatTime(t, utc)); + t = absl::FromCivil(absl::CivilDay(cs), utc); + EXPECT_EQ("2015-02-03T00:00:00+00:00", absl::FormatTime(t, utc)); + t = absl::FromCivil(absl::CivilMonth(cs), utc); + EXPECT_EQ("2015-02-01T00:00:00+00:00", absl::FormatTime(t, utc)); + t = absl::FromCivil(absl::CivilYear(cs), utc); + EXPECT_EQ("2015-01-01T00:00:00+00:00", absl::FormatTime(t, utc)); +} + +TEST(Time, LegacyDateTime) { + const absl::TimeZone utc = absl::UTCTimeZone(); + const std::string ymdhms = "%Y-%m-%d %H:%M:%S"; + const int kMax = std::numeric_limits<int>::max(); + const int kMin = std::numeric_limits<int>::min(); + absl::Time t; + + t = absl::FromDateTime(std::numeric_limits<absl::civil_year_t>::max(), + kMax, kMax, kMax, kMax, kMax, utc); + EXPECT_EQ("infinite-future", + absl::FormatTime(ymdhms, t, utc)); // no overflow + t = absl::FromDateTime(std::numeric_limits<absl::civil_year_t>::min(), + kMin, kMin, kMin, kMin, kMin, utc); + EXPECT_EQ("infinite-past", + absl::FormatTime(ymdhms, t, utc)); // no overflow + + // Check normalization. + EXPECT_TRUE(absl::ConvertDateTime(2013, 10, 32, 8, 30, 0, utc).normalized); + t = absl::FromDateTime(2015, 1, 1, 0, 0, 60, utc); + EXPECT_EQ("2015-01-01 00:01:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 1, 0, 60, 0, utc); + EXPECT_EQ("2015-01-01 01:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 1, 24, 0, 0, utc); + EXPECT_EQ("2015-01-02 00:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 32, 0, 0, 0, utc); + EXPECT_EQ("2015-02-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 13, 1, 0, 0, 0, utc); + EXPECT_EQ("2016-01-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 13, 32, 60, 60, 60, utc); + EXPECT_EQ("2016-02-03 13:01:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 1, 0, 0, -1, utc); + EXPECT_EQ("2014-12-31 23:59:59", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 1, 0, -1, 0, utc); + EXPECT_EQ("2014-12-31 23:59:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 1, -1, 0, 0, utc); + EXPECT_EQ("2014-12-31 23:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, -1, 0, 0, 0, utc); + EXPECT_EQ("2014-12-30 00:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, -1, 1, 0, 0, 0, utc); + EXPECT_EQ("2014-11-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, -1, -1, -1, -1, -1, utc); + EXPECT_EQ("2014-10-29 22:58:59", absl::FormatTime(ymdhms, t, utc)); +} + +TEST(Time, NextTransitionUTC) { + const auto tz = absl::UTCTimeZone(); + absl::TimeZone::CivilTransition trans; + + auto t = absl::InfinitePast(); + EXPECT_FALSE(tz.NextTransition(t, &trans)); + + t = absl::InfiniteFuture(); + EXPECT_FALSE(tz.NextTransition(t, &trans)); +} + +TEST(Time, PrevTransitionUTC) { + const auto tz = absl::UTCTimeZone(); + absl::TimeZone::CivilTransition trans; + + auto t = absl::InfiniteFuture(); + EXPECT_FALSE(tz.PrevTransition(t, &trans)); + + t = absl::InfinitePast(); + EXPECT_FALSE(tz.PrevTransition(t, &trans)); +} + +TEST(Time, NextTransitionNYC) { + const auto tz = absl::time_internal::LoadTimeZone("America/New_York"); + absl::TimeZone::CivilTransition trans; + + auto t = absl::FromCivil(absl::CivilSecond(2018, 6, 30, 0, 0, 0), tz); + EXPECT_TRUE(tz.NextTransition(t, &trans)); + EXPECT_EQ(absl::CivilSecond(2018, 11, 4, 2, 0, 0), trans.from); + EXPECT_EQ(absl::CivilSecond(2018, 11, 4, 1, 0, 0), trans.to); + + t = absl::InfiniteFuture(); + EXPECT_FALSE(tz.NextTransition(t, &trans)); + + t = absl::InfinitePast(); + EXPECT_TRUE(tz.NextTransition(t, &trans)); + if (trans.from == absl::CivilSecond(1918, 03, 31, 2, 0, 0)) { + // It looks like the tzdata is only 32 bit (probably macOS), + // which bottoms out at 1901-12-13T20:45:52+00:00. + EXPECT_EQ(absl::CivilSecond(1918, 3, 31, 3, 0, 0), trans.to); + } else { + EXPECT_EQ(absl::CivilSecond(1883, 11, 18, 12, 3, 58), trans.from); + EXPECT_EQ(absl::CivilSecond(1883, 11, 18, 12, 0, 0), trans.to); + } +} + +TEST(Time, PrevTransitionNYC) { + const auto tz = absl::time_internal::LoadTimeZone("America/New_York"); + absl::TimeZone::CivilTransition trans; + + auto t = absl::FromCivil(absl::CivilSecond(2018, 6, 30, 0, 0, 0), tz); + EXPECT_TRUE(tz.PrevTransition(t, &trans)); + EXPECT_EQ(absl::CivilSecond(2018, 3, 11, 2, 0, 0), trans.from); + EXPECT_EQ(absl::CivilSecond(2018, 3, 11, 3, 0, 0), trans.to); + + t = absl::InfinitePast(); + EXPECT_FALSE(tz.PrevTransition(t, &trans)); + + t = absl::InfiniteFuture(); + EXPECT_TRUE(tz.PrevTransition(t, &trans)); + // We have a transition but we don't know which one. +} + } // namespace
diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel index 32f690c..2e49000 100644 --- a/absl/types/BUILD.bazel +++ b/absl/types/BUILD.bazel
@@ -15,7 +15,7 @@ # load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", "ABSL_EXCEPTIONS_FLAG", @@ -168,6 +168,7 @@ deps = [ ":bad_optional_access", "//absl/base:config", + "//absl/base:core_headers", "//absl/memory", "//absl/meta:type_traits", "//absl/utility", @@ -286,6 +287,7 @@ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, deps = [ ":variant", + "//absl/base:config", "//absl/base:exception_safety_testing", "//absl/memory", "@com_google_googletest//:gtest_main",
diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt index 2f2e3a7..e862076 100644 --- a/absl/types/CMakeLists.txt +++ b/absl/types/CMakeLists.txt
@@ -123,7 +123,7 @@ # test any_test set(ANY_TEST_SRC "any_test.cc") -set(ANY_TEST_PUBLIC_LIBRARIES absl::base absl::throw_delegate absl::any absl::bad_any_cast test_instance_tracker_lib) +set(ANY_TEST_PUBLIC_LIBRARIES absl::base absl_internal_throw_delegate absl::any absl::bad_any_cast absl::test_instance_tracker) absl_test( TARGET @@ -152,7 +152,7 @@ set(ANY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES absl::any absl::base - absl_base_internal_exception_safety_testing + absl_internal_exception_safety_testing ) absl_test( @@ -169,7 +169,7 @@ # test span_test set(SPAN_TEST_SRC "span_test.cc") -set(SPAN_TEST_PUBLIC_LIBRARIES absl::base absl::strings absl::throw_delegate absl::span test_instance_tracker_lib) +set(SPAN_TEST_PUBLIC_LIBRARIES absl::base absl::strings absl_internal_throw_delegate absl::span absl::test_instance_tracker) absl_test( TARGET @@ -197,7 +197,7 @@ # test optional_test set(OPTIONAL_TEST_SRC "optional_test.cc") -set(OPTIONAL_TEST_PUBLIC_LIBRARIES absl::base absl::throw_delegate absl::optional absl_bad_optional_access) +set(OPTIONAL_TEST_PUBLIC_LIBRARIES absl::base absl_internal_throw_delegate absl::optional absl_bad_optional_access) absl_test( TARGET @@ -213,7 +213,7 @@ 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_internal_exception_safety_testing ) absl_test(
diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h index eff4fef..477e589 100644 --- a/absl/types/internal/variant.h +++ b/absl/types/internal/variant.h
@@ -15,6 +15,7 @@ // Implementation details of absl/types/variant.h, pulled into a // separate file to avoid cluttering the top of the API header with // implementation details. +// #ifndef ABSL_TYPES_variant_internal_H_ #define ABSL_TYPES_variant_internal_H_ @@ -1234,23 +1235,29 @@ // Base that is dependent on whether or not the move-assign can be trivial. template <class... T> using VariantMoveAssignBase = absl::conditional_t< - absl::disjunction<absl::conjunction<absl::is_move_assignable<Union<T...>>, - std::is_move_constructible<Union<T...>>, - std::is_destructible<Union<T...>>>, - absl::negation<absl::conjunction< - std::is_move_constructible<T>..., - absl::is_move_assignable<T>...>>>::value, + absl::disjunction< + absl::conjunction<absl::is_move_assignable<Union<T...>>, + std::is_move_constructible<Union<T...>>, + std::is_destructible<Union<T...>>>, + absl::negation<absl::conjunction<std::is_move_constructible<T>..., + // Note: We're not qualifying this with + // absl:: because it doesn't compile + // under MSVC. + is_move_assignable<T>...>>>::value, VariantCopyBase<T...>, VariantMoveAssignBaseNontrivial<T...>>; // Base that is dependent on whether or not the copy-assign can be trivial. template <class... T> using VariantCopyAssignBase = absl::conditional_t< - absl::disjunction<absl::conjunction<absl::is_copy_assignable<Union<T...>>, - std::is_copy_constructible<Union<T...>>, - std::is_destructible<Union<T...>>>, - absl::negation<absl::conjunction< - std::is_copy_constructible<T>..., - absl::is_copy_assignable<T>...>>>::value, + absl::disjunction< + absl::conjunction<absl::is_copy_assignable<Union<T...>>, + std::is_copy_constructible<Union<T...>>, + std::is_destructible<Union<T...>>>, + absl::negation<absl::conjunction<std::is_copy_constructible<T>..., + // Note: We're not qualifying this with + // absl:: because it doesn't compile + // under MSVC. + is_copy_assignable<T>...>>>::value, VariantMoveAssignBase<T...>, VariantCopyAssignBaseNontrivial<T...>>; template <class... T>
diff --git a/absl/types/optional.h b/absl/types/optional.h index 1421001..7677fe5 100644 --- a/absl/types/optional.h +++ b/absl/types/optional.h
@@ -163,7 +163,7 @@ // This class stores the data in optional<T>. // It is specialized based on whether T is trivially destructible. // This is the specialization for non trivially destructible type. -template <typename T, bool = std::is_trivially_destructible<T>::value> +template <typename T, bool unused = std::is_trivially_destructible<T>::value> class optional_data_dtor_base { struct dummy_type { static_assert(sizeof(T) % sizeof(empty_struct) == 0, ""); @@ -261,10 +261,10 @@ // have trivial move but nontrivial copy. // Also, we should be checking is_trivially_copyable here, which is not // supported now, so we use is_trivially_* traits instead. -template <typename T, bool = absl::is_trivially_copy_constructible<T>::value&& - absl::is_trivially_copy_assignable< - typename std::remove_cv<T>::type>::value&& - std::is_trivially_destructible<T>::value> +template <typename T, + bool unused = absl::is_trivially_copy_constructible<T>::value&& + absl::is_trivially_copy_assignable<typename std::remove_cv< + T>::type>::value&& std::is_trivially_destructible<T>::value> class optional_data; // Trivially copyable types
diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc index d90db9f..fc4f00a 100644 --- a/absl/types/optional_test.cc +++ b/absl/types/optional_test.cc
@@ -1042,9 +1042,9 @@ // test exception throw on value() absl::optional<int> empty; #ifdef ABSL_HAVE_EXCEPTIONS - EXPECT_THROW(empty.value(), absl::bad_optional_access); + EXPECT_THROW((void)empty.value(), absl::bad_optional_access); #else - EXPECT_DEATH(empty.value(), "Bad optional access"); + EXPECT_DEATH((void)empty.value(), "Bad optional access"); #endif // test constexpr value()
diff --git a/absl/types/variant.h b/absl/types/variant.h index 2f78722..48c5d7b 100644 --- a/absl/types/variant.h +++ b/absl/types/variant.h
@@ -82,7 +82,7 @@ // absl::variant // ----------------------------------------------------------------------------- // -// An 'absl::variant` type is a form of type-safe union. An `absl::variant` -- +// An `absl::variant` type is a form of type-safe union. An `absl::variant` -- // except in exceptional cases -- always holds a value of one of its alternative // types. // @@ -136,7 +136,7 @@ // variant_size // -// Returns the number of alterative types available for a given `absl::variant` +// Returns the number of alternative types available for a given `absl::variant` // type as a compile-time constant expression. As this is a class template, it // is not generally useful for accessing the number of alternative types of // any given `absl::variant` instance. @@ -399,9 +399,9 @@ // Calls a provided functor on a given set of variants. `absl::visit()` is // commonly used to conditionally inspect the state of a given variant (or set // of variants). -// Requires: The expression in the Effects: element shall be a valid expression -// of the same type and value category, for all combinations of alternative -// types of all variants. Otherwise, the program is ill-formed. +// +// The functor must return the same type when called with any of the variants' +// alternatives. // // Example: // @@ -414,6 +414,7 @@ // }; // // // Declare our variant, and call `absl::visit()` on it. +// // Note that `GetVariant()` returns void in either case. // absl::variant<int, std::string> foo = std::string("foo"); // GetVariant visitor; // absl::visit(visitor, foo); // Prints `The variant's value is: foo' @@ -453,7 +454,7 @@ std::is_object<Tn>...>::value, "Attempted to instantiate a variant containing a non-object " "type."); - // Intentionally not qualifing `negation` with `absl::` to work around a bug + // Intentionally not qualifying `negation` with `absl::` to work around a bug // in MSVC 2015 with inline namespace and variadic template. static_assert(absl::conjunction<negation<std::is_array<T0> >, negation<std::is_array<Tn> >...>::value, @@ -561,7 +562,7 @@ // Assignment Operators - // Copy assignement operator + // Copy assignment operator variant& operator=(const variant& other) = default; // Move assignment operator
diff --git a/absl/types/variant_exception_safety_test.cc b/absl/types/variant_exception_safety_test.cc index 58436f0..82425db 100644 --- a/absl/types/variant_exception_safety_test.cc +++ b/absl/types/variant_exception_safety_test.cc
@@ -11,6 +11,7 @@ // 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/variant.h" #include <iostream> @@ -20,8 +21,11 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/base/config.h" #include "absl/base/internal/exception_safety_testing.h" #include "absl/memory/memory.h" +// See comment in absl/base/config.h +#if !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE) namespace absl { namespace { @@ -506,3 +510,5 @@ } // namespace } // namespace absl + +#endif // !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE)
diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc index bfb8bd7..f47f3a7 100644 --- a/absl/types/variant_test.cc +++ b/absl/types/variant_test.cc
@@ -52,7 +52,7 @@ #endif // ABSL_HAVE_EXCEPTIONS #define ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(...) \ - ABSL_VARIANT_TEST_EXPECT_FAIL((__VA_ARGS__), absl::bad_variant_access, \ + ABSL_VARIANT_TEST_EXPECT_FAIL((void)(__VA_ARGS__), absl::bad_variant_access, \ "Bad variant access") struct Hashable {}; @@ -559,9 +559,14 @@ } #ifdef ABSL_HAVE_EXCEPTIONS - +// See comment in absl/base/config.h +#if defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE) +TEST(VariantTest, DISABLED_TestDtorValuelessByException) +#else // Test destruction when in the valueless_by_exception state. -TEST(VariantTest, TestDtorValuelessByException) { +TEST(VariantTest, TestDtorValuelessByException) +#endif +{ int counter = 0; IncrementInDtor counter_adjuster(&counter);
diff --git a/absl/utility/BUILD.bazel b/absl/utility/BUILD.bazel index c01b49b..5185ccd 100644 --- a/absl/utility/BUILD.bazel +++ b/absl/utility/BUILD.bazel
@@ -1,5 +1,5 @@ load( - "//absl:copts.bzl", + "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", )