diff --git a/.gitignore b/.gitignore
index 886f4432..7175c4f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,12 @@
# 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/*
diff --git a/CMake/AbseilConfigureCopts.cmake b/CMake/AbseilConfigureCopts.cmake
new file mode 100644
index 00000000..96e0390b
--- /dev/null
+++ b/CMake/AbseilConfigureCopts.cmake
@@ -0,0 +1,145 @@
+# Abseil-specific compiler flags. See absl/copts.bzl for description.
+# DO NOT CHANGE THIS FILE WITHOUT THE CORRESPONDING CHANGE TO absl/copts.bzl
+
+list(APPEND GCC_FLAGS
+ -Wall
+ -Wextra
+ -Wcast-qual
+ -Wconversion-null
+ -Wmissing-declarations
+ -Woverlength-strings
+ -Wpointer-arith
+ -Wunused-local-typedefs
+ -Wunused-result
+ -Wvarargs
+ -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_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_FLAGS
+ /W3
+ /wd4005
+ /wd4018
+ /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
+ /wd4101
+ /wd4503
+)
+
+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 "-fexceptions")
+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 "-fexceptions")
+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 "/U_HAS_EXCEPTIONS;/D_HAS_EXCEPTIONS=1;/EHsc")
+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()
diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake
index e4eafe49..5402bf51 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 @@ function(absl_library)
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 @@ function(absl_library)
# 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 @@ function(absl_header_library)
# 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
#
@@ -123,7 +317,7 @@ endfunction()
#
# all tests will be register for execution with add_test()
#
-# test compilation and execution is disable when BUILD_TESTING=OFF
+# test compilation and execution is disable when ABSL_RUN_TESTS=OFF
#
function(absl_test)
@@ -135,25 +329,32 @@ function(absl_test)
)
- if(BUILD_TESTING)
+ 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})
+
+ set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD})
+ set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
- add_test(${_NAME} ${_NAME}_bin)
- endif(BUILD_TESTING)
+ add_test(NAME ${_NAME} COMMAND ${_NAME})
+ endif(ABSL_RUN_TESTS)
endfunction()
diff --git a/CMake/DownloadGTest.cmake b/CMake/DownloadGTest.cmake
index 9d413215..3c682aef 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 89a3386f..1eafa407 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,9 +17,15 @@
# 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)
include(GNUInstallDirs)
include(AbseilHelpers)
@@ -32,8 +38,16 @@ if (MSVC)
# /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 /WX /wd4005 /wd4068 /wd4244 /wd4267 /wd4800)
- add_definitions(/DNOMINMAX /DWIN32_LEAN_AND_MEAN=1 /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS)
+ add_compile_options(/W3 /wd4005 /wd4068 /wd4244 /wd4267 /wd4800)
+ # /D_ENABLE_EXTENDED_ALIGNED_STORAGE Introduced in VS 2017 15.8, before the
+ # member type would non-conformingly have an alignment of only alignof(max_align_t).
+ add_definitions(
+ /DNOMINMAX
+ /DWIN32_LEAN_AND_MEAN=1
+ /D_CRT_SECURE_NO_WARNINGS
+ /D_SCL_SECURE_NO_WARNINGS
+ /D_ENABLE_EXTENDED_ALIGNED_STORAGE
+ )
else()
set(ABSL_STD_CXX_FLAG "-std=c++11" CACHE STRING "c++ std flag (default: c++11)")
endif()
@@ -60,6 +74,12 @@ 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 40351ddc..f4cb4a29 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -18,6 +18,53 @@ You generally only need to submit a CLA once, so if you've already submitted one
(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 8eed5751..e9362be2 100644
--- a/README.md
+++ b/README.md
@@ -63,10 +63,14 @@ Abseil contains the following C++ library components:
The `algorithm` library contains additions to the C++ ``
library and container-based versions of such algorithms.
* [`container`](absl/container/)
-
The `container` library contains additional STL-style containers.
+
The `container` library contains additional STL-style containers,
+ including Abseil's unordered "Swiss table" containers.
* [`debugging`](absl/debugging/)
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/)
+
The `hash` library contains the hashing framework and default hash
+ functor implementations for hashable types in Abseil.
* [`memory`](absl/memory/)
The `memory` library contains C++11-compatible versions of
`std::make_unique()` and related memory management facilities.
@@ -90,6 +94,8 @@ Abseil contains the following C++ library components:
* [`types`](absl/types/)
The `types` library contains non-container utility types, like a
C++11-compatible version of the C++17 `std::optional` type.
+* [`utility`](absl/utility/)
+
The `utility` library contains utility and helper code.
## License
diff --git a/WORKSPACE b/WORKSPACE
index a7b1c139..72ef1398 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,21 +1,23 @@
workspace(name = "com_google_absl")
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
# Bazel toolchains
http_archive(
name = "bazel_toolchains",
urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/287b64e0a211fb7c23b74695f8d5f5205b61f4eb.tar.gz",
- "https://github.com/bazelbuild/bazel-toolchains/archive/287b64e0a211fb7c23b74695f8d5f5205b61f4eb.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/bc09b995c137df042bb80a395b73d7ce6f26afbe.tar.gz",
+ "https://github.com/bazelbuild/bazel-toolchains/archive/bc09b995c137df042bb80a395b73d7ce6f26afbe.tar.gz",
],
- strip_prefix = "bazel-toolchains-287b64e0a211fb7c23b74695f8d5f5205b61f4eb",
- sha256 = "aca8ac6afd7745027ee4a43032b51a725a61a75a30f02cc58681ee87e4dcdf4b",
+ strip_prefix = "bazel-toolchains-bc09b995c137df042bb80a395b73d7ce6f26afbe",
+ sha256 = "4329663fe6c523425ad4d3c989a8ac026b04e1acedeceb56aa4b190fa7f3973c",
)
# GoogleTest/GoogleMock framework. Used by most unit-tests.
http_archive(
name = "com_google_googletest",
- urls = ["https://github.com/google/googletest/archive/4e4df226fc197c0dda6e37f5c8c3845ca1e73a49.zip"],
- strip_prefix = "googletest-4e4df226fc197c0dda6e37f5c8c3845ca1e73a49",
- sha256 = "d4179caf54410968d1fff0b869e7d74803dd30209ee6645ccf1ca65ab6cf5e5a",
+ urls = ["https://github.com/google/googletest/archive/b4d4438df9479675a632b2f11125e57133822ece.zip"], # 2018-07-16
+ strip_prefix = "googletest-b4d4438df9479675a632b2f11125e57133822ece",
+ sha256 = "5aaa5d566517cae711e2a3505ea9a6438be1b37fcaae0ebcb96ccba9aa56f23a",
)
# Google benchmark.
@@ -25,11 +27,3 @@ http_archive(
strip_prefix = "benchmark-16703ff83c1ae6d53e5155df3bb3ab0bc96083be",
sha256 = "59f918c8ccd4d74b6ac43484467b500f1d64b40cc1010daa055375b322a43ba3",
)
-
-# RE2 regular-expression framework. Used by some unit-tests.
-http_archive(
- name = "com_googlesource_code_re2",
- urls = ["https://github.com/google/re2/archive/6cf8ccd82dbaab2668e9b13596c68183c9ecd13f.zip"],
- strip_prefix = "re2-6cf8ccd82dbaab2668e9b13596c68183c9ecd13f",
- sha256 = "279a852219dbfc504501775596089d30e9c0b29664ce4128b0ac4c841471a16a",
-)
diff --git a/absl/BUILD.bazel b/absl/BUILD.bazel
index 439addbf..edd0274c 100644
--- a/absl/BUILD.bazel
+++ b/absl/BUILD.bazel
@@ -18,11 +18,10 @@ package(default_visibility = ["//visibility:public"])
licenses(["notice"]) # Apache 2.0
-config_setting(
+load(":compiler_config_setting.bzl", "create_llvm_config")
+
+create_llvm_config(
name = "llvm_compiler",
- values = {
- "compiler": "llvm",
- },
visibility = [":__subpackages__"],
)
diff --git a/absl/CMakeLists.txt b/absl/CMakeLists.txt
index 689f64e2..1d09b193 100644
--- a/absl/CMakeLists.txt
+++ b/absl/CMakeLists.txt
@@ -20,6 +20,7 @@ add_subdirectory(base)
add_subdirectory(algorithm)
add_subdirectory(container)
add_subdirectory(debugging)
+add_subdirectory(hash)
add_subdirectory(memory)
add_subdirectory(meta)
add_subdirectory(numeric)
diff --git a/absl/algorithm/CMakeLists.txt b/absl/algorithm/CMakeLists.txt
index fdf45c55..87a165c0 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
)
+absl_cc_library(
+ NAME
+ algorithm_container
+ HDRS
+ "container.h"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
+ DEPS
+ absl::algorithm
+ absl::core_headers
+ absl::meta
+ PUBLIC
+)
-
-
-# test container_test
-set(CONTAINER_TEST_SRC "container_test.cc")
-
-absl_test(
- TARGET
+absl_cc_test(
+ NAME
container_test
- SOURCES
- ${CONTAINER_TEST_SRC}
- PUBLIC_LIBRARIES
- absl::algorithm
+ SRCS
+ "container_test.cc"
+ DEPS
+ absl::algorithm_container
+ absl::base
+ absl::core_headers
+ absl::memory
+ absl::span
+ gmock_main
)
diff --git a/absl/algorithm/algorithm.h b/absl/algorithm/algorithm.h
index 3a8f2724..1eef16cb 100644
--- a/absl/algorithm/algorithm.h
+++ b/absl/algorithm/algorithm.h
@@ -27,7 +27,7 @@
#include
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace algorithm_internal {
@@ -146,7 +146,7 @@ ForwardIterator rotate(ForwardIterator first, ForwardIterator middle,
ForwardIterator>());
}
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_ALGORITHM_ALGORITHM_H_
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h
index 8eb10d7a..b7718206 100644
--- a/absl/algorithm/container.h
+++ b/absl/algorithm/container.h
@@ -46,6 +46,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -54,8 +56,7 @@
#include "absl/meta/type_traits.h"
namespace absl {
-inline namespace lts_2018_06_20 {
-
+inline namespace lts_2018_12_18 {
namespace container_algorithm_internal {
// NOTE: it is important to defer to ADL lookup for building with C++ modules,
@@ -102,6 +103,17 @@ ContainerIter c_begin(C& c) { return begin(c); }
template
ContainerIter c_end(C& c) { return end(c); }
+template
+struct IsUnorderedContainer : std::false_type {};
+
+template
+struct IsUnorderedContainer<
+ std::unordered_map> : std::true_type {};
+
+template
+struct IsUnorderedContainer>
+ : std::true_type {};
+
} // namespace container_algorithm_internal
// PUBLIC API
@@ -315,7 +327,7 @@ container_algorithm_internal::ContainerDifferenceType c_count_if(
// c_mismatch()
//
-// Container-based version of the `std::mismatchf()` function to
+// Container-based version of the `std::mismatch()` function to
// return the first element where two ordered containers differ.
template
container_algorithm_internal::ContainerIterPairType
@@ -495,7 +507,7 @@ BidirectionalIterator c_copy_backward(const C& src,
// Container-based version of the `std::move()` function to move
// a container's elements into an iterator.
template
-OutputIterator c_move(C& src, OutputIterator dest) {
+OutputIterator c_move(C&& src, OutputIterator dest) {
return std::move(container_algorithm_internal::c_begin(src),
container_algorithm_internal::c_end(src), dest);
}
@@ -635,7 +647,7 @@ container_algorithm_internal::ContainerIter c_generate_n(C& c, Size n,
// Note: `c_xx()` container versions for `remove()`, `remove_if()`,
// and `unique()` are omitted, because it's not clear whether or not such
-// functions should call erase their supplied sequences afterwards. Either
+// functions should call erase on their supplied sequences afterwards. Either
// behavior would be surprising for a different set of users.
//
@@ -1155,7 +1167,13 @@ bool c_includes(const C1& c1, const C2& c2, Compare&& comp) {
// Container-based version of the `std::set_union()` function
// to return an iterator containing the union of two containers; duplicate
// values are not copied into the output.
-template
+template ::value,
+ void>::type,
+ typename = typename std::enable_if<
+ !container_algorithm_internal::IsUnorderedContainer::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),
@@ -1165,7 +1183,13 @@ OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output) {
// Overload of c_set_union() for performing a merge using a `comp` other than
// `operator<`.
-template
+template ::value,
+ void>::type,
+ typename = typename std::enable_if<
+ !container_algorithm_internal::IsUnorderedContainer::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),
@@ -1179,7 +1203,13 @@ OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output,
//
// Container-based version of the `std::set_intersection()` function
// to return an iterator containing the intersection of two containers.
-template
+template ::value,
+ void>::type,
+ typename = typename std::enable_if<
+ !container_algorithm_internal::IsUnorderedContainer::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),
@@ -1190,7 +1220,13 @@ OutputIterator c_set_intersection(const C1& c1, const C2& c2,
// Overload of c_set_intersection() for performing a merge using a `comp` other
// than `operator<`.
-template
+template ::value,
+ void>::type,
+ typename = typename std::enable_if<
+ !container_algorithm_internal::IsUnorderedContainer::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),
@@ -1205,7 +1241,13 @@ OutputIterator c_set_intersection(const C1& c1, const C2& c2,
// Container-based version of the `std::set_difference()` function
// to return an iterator containing elements present in the first container but
// not in the second.
-template
+template ::value,
+ void>::type,
+ typename = typename std::enable_if<
+ !container_algorithm_internal::IsUnorderedContainer::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),
@@ -1216,7 +1258,13 @@ OutputIterator c_set_difference(const C1& c1, const C2& c2,
// Overload of c_set_difference() for performing a merge using a `comp` other
// than `operator<`.
-template
+template ::value,
+ void>::type,
+ typename = typename std::enable_if<
+ !container_algorithm_internal::IsUnorderedContainer::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),
@@ -1231,7 +1279,13 @@ OutputIterator c_set_difference(const C1& c1, const C2& c2,
// Container-based version of the `std::set_symmetric_difference()`
// function to return an iterator containing elements present in either one
// container or the other, but not both.
-template
+template ::value,
+ void>::type,
+ typename = typename std::enable_if<
+ !container_algorithm_internal::IsUnorderedContainer::value,
+ void>::type>
OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2,
OutputIterator output) {
return std::set_symmetric_difference(
@@ -1243,7 +1297,13 @@ OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2,
// Overload of c_set_symmetric_difference() for performing a merge using a
// `comp` other than `operator<`.
-template
+template ::value,
+ void>::type,
+ typename = typename std::enable_if<
+ !container_algorithm_internal::IsUnorderedContainer::value,
+ void>::type>
OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2,
OutputIterator output,
Compare&& comp) {
@@ -1638,7 +1698,7 @@ OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first,
output_first, std::forward(op));
}
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_ALGORITHM_CONTAINER_H_
diff --git a/absl/algorithm/container_test.cc b/absl/algorithm/container_test.cc
index de66f146..1502b17f 100644
--- a/absl/algorithm/container_test.cc
+++ b/absl/algorithm/container_test.cc
@@ -636,6 +636,21 @@ TEST(MutatingTest, Move) {
Pointee(5)));
}
+TEST(MutatingTest, MoveWithRvalue) {
+ auto MakeRValueSrc = [] {
+ std::vector> src;
+ src.emplace_back(absl::make_unique(1));
+ src.emplace_back(absl::make_unique(2));
+ src.emplace_back(absl::make_unique(3));
+ return src;
+ };
+
+ std::vector> dest = MakeRValueSrc();
+ absl::c_move(MakeRValueSrc(), std::back_inserter(dest));
+ EXPECT_THAT(dest, ElementsAre(Pointee(1), Pointee(2), Pointee(3), Pointee(1),
+ Pointee(2), Pointee(3)));
+}
+
TEST(MutatingTest, SwapRanges) {
std::vector odds = {2, 4, 6};
std::vector evens = {1, 3, 5};
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index d117a4fe..4566c697 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -19,6 +19,7 @@ load(
"ABSL_DEFAULT_COPTS",
"ABSL_TEST_COPTS",
"ABSL_EXCEPTIONS_FLAG",
+ "ABSL_EXCEPTIONS_FLAG_LINKOPTS",
)
package(default_visibility = ["//visibility:public"])
@@ -29,6 +30,7 @@ cc_library(
name = "spinlock_wait",
srcs = [
"internal/spinlock_akaros.inc",
+ "internal/spinlock_linux.inc",
"internal/spinlock_posix.inc",
"internal/spinlock_wait.cc",
"internal/spinlock_win32.inc",
@@ -73,7 +75,6 @@ cc_library(
copts = ABSL_DEFAULT_COPTS,
deps = [
":config",
- ":dynamic_annotations",
],
)
@@ -106,6 +107,7 @@ cc_library(
"internal/identity.h",
"internal/inline_variable.h",
"internal/invoke.h",
+ "internal/scheduling_mode.h",
],
copts = ABSL_DEFAULT_COPTS,
visibility = [
@@ -179,13 +181,13 @@ cc_library(
srcs = ["internal/throw_delegate.cc"],
hdrs = ["internal/throw_delegate.h"],
copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":base",
":config",
- ":core_headers",
],
)
@@ -193,6 +195,7 @@ cc_test(
name = "throw_delegate_test",
srcs = ["throw_delegate_test.cc"],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":throw_delegate",
"@com_google_googletest//:gtest_main",
@@ -225,6 +228,7 @@ cc_library(
srcs = ["internal/exception_safety_testing.cc"],
hdrs = ["internal/exception_safety_testing.h"],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":base",
":config",
@@ -232,7 +236,7 @@ cc_library(
"//absl/memory",
"//absl/meta:type_traits",
"//absl/strings",
- "//absl/types:optional",
+ "//absl/utility",
"@com_google_googletest//:gtest",
],
)
@@ -241,6 +245,7 @@ cc_test(
name = "exception_safety_testing_test",
srcs = ["exception_safety_testing_test.cc"],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":exception_safety_testing",
"//absl/memory",
@@ -299,6 +304,7 @@ cc_test(
size = "medium",
srcs = ["spinlock_test_common.cc"],
copts = ABSL_TEST_COPTS,
+ tags = ["no_test_wasm"],
deps = [
":base",
":core_headers",
@@ -308,6 +314,33 @@ cc_test(
],
)
+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 = [
@@ -337,6 +370,9 @@ cc_test(
name = "config_test",
srcs = ["config_test.cc"],
copts = ABSL_TEST_COPTS,
+ tags = [
+ "no_test_wasm",
+ ],
deps = [
":config",
"//absl/synchronization:thread_pool",
@@ -348,6 +384,9 @@ cc_test(
name = "call_once_test",
srcs = ["call_once_test.cc"],
copts = ABSL_TEST_COPTS,
+ tags = [
+ "no_test_wasm",
+ ],
deps = [
":base",
":core_headers",
@@ -362,6 +401,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
deps = [
":base",
+ "//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
@@ -387,6 +427,7 @@ cc_test(
"//absl:windows": [],
"//conditions:default": ["-pthread"],
}),
+ tags = ["no_test_ios_x86_64"],
deps = [":malloc_internal"],
)
@@ -399,6 +440,9 @@ cc_test(
"//absl:windows": [],
"//conditions:default": ["-pthread"],
}),
+ tags = [
+ "no_test_wasm",
+ ],
deps = [
":base",
":core_headers",
@@ -419,3 +463,23 @@ cc_test(
"@com_github_google_benchmark//:benchmark_main",
],
)
+
+cc_library(
+ name = "bits",
+ hdrs = ["internal/bits.h"],
+ visibility = [
+ "//absl:__subpackages__",
+ ],
+ deps = [":core_headers"],
+)
+
+cc_test(
+ name = "bits_test",
+ size = "small",
+ srcs = ["internal/bits_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":bits",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index 303533e2..212dd083 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -14,373 +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
)
+absl_cc_library(
+ NAME
+ config
+ HDRS
+ "config.h"
+ "policy_checks.h"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
+ PUBLIC
+)
+
+absl_cc_library(
+ NAME
+ dynamic_annotations
+ HDRS
+ "dynamic_annotations.h"
+ SRCS
+ "dynamic_annotations.cc"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
+ DEFINES
+ "__CLANG_SUPPORT_DYN_ANNOTATION__"
+ PUBLIC
+)
-list(APPEND BASE_INTERNAL_HEADERS
- "internal/atomic_hook.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
+ core_headers
+ HDRS
+ "attributes.h"
+ "macros.h"
+ "optimization.h"
+ "port.h"
+ "thread_annotations.h"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
+ DEPS
+ absl::config
+ PUBLIC
)
+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_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
+ base_internal
+ HDRS
+ "internal/hide_ptr.h"
+ "internal/identity.h"
+ "internal/inline_variable.h"
+ "internal/invoke.h"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
)
-absl_library(
- TARGET
- absl_base
- SOURCES
- ${BASE_SRC}
- PUBLIC_LIBRARIES
- absl_dynamic_annotations
- absl_spinlock_wait
- EXPORT_NAME
+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
)
-# 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
+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}
)
-if(BUILD_TESTING)
- # exception-safety testing library
- set(EXCEPTION_SAFETY_TESTING_SRC
+absl_cc_library(
+ NAME
+ exception_safety_testing
+ HDRS
"internal/exception_safety_testing.h"
+ SRCS
"internal/exception_safety_testing.cc"
- )
- set(EXCEPTION_SAFETY_TESTING_PUBLIC_LIBRARIES
- ${ABSL_TEST_COMMON_LIBRARIES}
+ 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}
-)
-
-
-# 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"
+ TESTONLY
)
-absl_library(
- TARGET
- absl_malloc_internal
- SOURCES
- ${MALLOC_INTERNAL_SRC}
- PUBLIC_LIBRARIES
- absl_dynamic_annotations
+absl_cc_test(
+ NAME
+ absl_exception_safety_testing_test
+ SRCS
+ "exception_safety_testing_test.cc"
+ COPTS
+ ${ABSL_EXCEPTIONS_FLAG}
+ LINKOPTS
+ ${ABSL_EXCEPTIONS_FLAG_LINKOPTS}
+ DEPS
+ absl::exception_safety_testing
+ absl::memory
+ gtest_main
)
-
-
-#
-## 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
+absl_cc_test(
+ NAME
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}
+ SRCS
+ "internal/atomic_hook_test.cc"
+ DEPS
+ absl::base
+ absl::core_headers
+ gtest_main
)
-
-# test bit_cast_test
-set(BIT_CAST_TEST_SRC "bit_cast_test.cc")
-
-absl_test(
- TARGET
+absl_cc_test(
+ NAME
bit_cast_test
- SOURCES
- ${BIT_CAST_TEST_SRC}
+ SRCS
+ "bit_cast_test.cc"
+ DEPS
+ absl::base
+ absl::core_headers
+ gtest_main
)
-
-# 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
+absl_cc_test(
+ NAME
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"
+ SRCS
+ "throw_delegate_test.cc"
+ DEPS
+ absl::base
+ absl_internal_throw_delegate
+ gtest_main
)
-set(INLINE_VARIABLE_TEST_PUBLIC_LIBRARIES absl::base)
-
-absl_test(
- TARGET
+absl_cc_test(
+ NAME
inline_variable_test
- SOURCES
- ${INLINE_VARIABLE_TEST_SRC}
- PUBLIC_LIBRARIES
- ${INLINE_VARIABLE_TEST_PUBLIC_LIBRARIES}
+ 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
+)
-# 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
+absl_cc_library(
+ NAME
spinlock_test_common
- SOURCES
- ${SPINLOCK_TEST_COMMON_SRC}
- PUBLIC_LIBRARIES
- ${SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES}
+ SRCS
+ "spinlock_test_common.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
+ DEPS
+ absl::base
+ absl::core_headers
+ absl::spinlock_wait
+ absl::synchronization
+ gtest
+ TESTONLY
)
-
-# test spinlock_test
-set(SPINLOCK_TEST_SRC "spinlock_test_common.cc")
-set(SPINLOCK_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization)
-
-absl_test(
- TARGET
+# On bazel BUILD this target use "alwayslink = 1" which is not implemented here
+absl_cc_test(
+ NAME
spinlock_test
- SOURCES
- ${SPINLOCK_TEST_SRC}
- PUBLIC_LIBRARIES
- ${SPINLOCK_TEST_PUBLIC_LIBRARIES}
+ 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
+)
-# test endian_test
-set(ENDIAN_TEST_SRC "internal/endian_test.cc")
-
-absl_test(
- TARGET
+absl_cc_test(
+ NAME
endian_test
- SOURCES
- ${ENDIAN_TEST_SRC}
+ SRCS
+ "internal/endian_test.cc"
+ DEPS
+ absl::base
+ absl::config
+ absl::endian
+ gtest_main
)
-
-# test config_test
-set(CONFIG_TEST_SRC "config_test.cc")
-set(CONFIG_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization)
-absl_test(
- TARGET
+absl_cc_test(
+ NAME
config_test
- SOURCES
- ${CONFIG_TEST_SRC}
- PUBLIC_LIBRARIES
- ${CONFIG_TEST_PUBLIC_LIBRARIES}
+ 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
+)
-# test raw_logging_test
-set(RAW_LOGGING_TEST_SRC "raw_logging_test.cc")
-set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base)
-
-absl_test(
- TARGET
+absl_cc_test(
+ NAME
raw_logging_test
- SOURCES
- ${RAW_LOGGING_TEST_SRC}
- PUBLIC_LIBRARIES
- ${RAW_LOGGING_TEST_PUBLIC_LIBRARIES}
+ SRCS
+ "raw_logging_test.cc"
+ DEPS
+ absl::base
+ absl::strings
+ gtest_main
)
-
-# test sysinfo_test
-set(SYSINFO_TEST_SRC "internal/sysinfo_test.cc")
-set(SYSINFO_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization)
-
-absl_test(
- TARGET
+absl_cc_test(
+ NAME
sysinfo_test
- SOURCES
- ${SYSINFO_TEST_SRC}
- PUBLIC_LIBRARIES
- ${SYSINFO_TEST_PUBLIC_LIBRARIES}
+ SRCS
+ "internal/sysinfo_test.cc"
+ DEPS
+ absl::base
+ absl::synchronization
+ gtest_main
)
-
-# 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
+absl_cc_test(
+ NAME
low_level_alloc_test
- SOURCES
- ${LOW_LEVEL_ALLOC_TEST_SRC}
- PUBLIC_LIBRARIES
- ${LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES}
+ SRCS
+ "internal/low_level_alloc_test.cc"
+ DEPS
+ absl::malloc_internal
+ Threads::Threads
)
-
-# 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
+absl_cc_test(
+ NAME
thread_identity_test
- SOURCES
- ${THREAD_IDENTITY_TEST_SRC}
- PUBLIC_LIBRARIES
- ${THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES}
+ SRCS
+ "internal/thread_identity_test.cc"
+ DEPS
+ absl::base
+ absl::core_headers
+ absl::synchronization
+ Threads::Threads
+ gtest_main
)
-#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_cc_library(
+ NAME
+ bits
+ HDRS
+ "internal/bits.h"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
+ DEPS
+ absl::core_headers
)
-absl_test(
- TARGET
- absl_exception_safety_testing_test
- SOURCES
- ${EXCEPTION_SAFETY_TESTING_TEST_SRC}
- PUBLIC_LIBRARIES
- ${EXCEPTION_SAFETY_TESTING_TEST_PUBLIC_LIBRARIES}
- PRIVATE_COMPILE_FLAGS
- ${ABSL_EXCEPTIONS_FLAG}
+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 b1883b6d..291ad89e 100644
--- a/absl/base/attributes.h
+++ b/absl/base/attributes.h
@@ -100,7 +100,7 @@
// ABSL_PRINTF_ATTRIBUTE
// ABSL_SCANF_ATTRIBUTE
//
-// Tells the compiler to perform `printf` format std::string checking if the
+// Tells the compiler to perform `printf` format string checking if the
// compiler supports it; see the 'format' attribute in
// .
//
@@ -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.
+//
+// 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:
//
-// 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.
+// 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.
@@ -494,14 +510,27 @@
#define ABSL_XRAY_LOG_ARGS(N)
#endif
+// ABSL_ATTRIBUTE_REINITIALIZES
+//
+// Indicates that a member function reinitializes the entire object to a known
+// state, independent of the previous state of the object.
+//
+// The clang-tidy check bugprone-use-after-move allows member functions marked
+// with this attribute to be called on objects that have been moved from;
+// without the attribute, this would result in a use-after-move warning.
+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::reinitializes)
+#define ABSL_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]]
+#else
+#define ABSL_ATTRIBUTE_REINITIALIZES
+#endif
+
// -----------------------------------------------------------------------------
// Variable Attributes
// -----------------------------------------------------------------------------
// ABSL_ATTRIBUTE_UNUSED
//
-// Prevents the compiler from complaining about or optimizing away variables
-// that appear unused.
+// Prevents the compiler from complaining about variables that appear unused.
#if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__))
#undef ABSL_ATTRIBUTE_UNUSED
#define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__))
diff --git a/absl/base/bit_cast_test.cc b/absl/base/bit_cast_test.cc
index 71bb368f..5af036df 100644
--- a/absl/base/bit_cast_test.cc
+++ b/absl/base/bit_cast_test.cc
@@ -22,7 +22,7 @@
#include "absl/base/macros.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace {
template
@@ -105,5 +105,5 @@ TEST(BitCast, Double) {
}
} // namespace
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/call_once.h b/absl/base/call_once.h
index 37b6608a..aea9197b 100644
--- a/absl/base/call_once.h
+++ b/absl/base/call_once.h
@@ -39,7 +39,7 @@
#include "absl/base/port.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
class once_flag;
@@ -151,12 +151,8 @@ void CallOnceImpl(std::atomic* control,
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(old_control)); // NOLINT
+ ABSL_RAW_LOG(FATAL, "Unexpected value for control word: 0x%lx",
+ static_cast(old_control)); // NOLINT
}
}
#endif // NDEBUG
@@ -212,7 +208,7 @@ void call_once(absl::once_flag& flag, Callable&& fn, Args&&... args) {
}
}
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_CALL_ONCE_H_
diff --git a/absl/base/call_once_test.cc b/absl/base/call_once_test.cc
index 43a71656..4d98a405 100644
--- a/absl/base/call_once_test.cc
+++ b/absl/base/call_once_test.cc
@@ -22,7 +22,7 @@
#include "absl/synchronization/mutex.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace {
absl::once_flag once;
@@ -100,5 +100,5 @@ TEST(CallOnceTest, ExecutionCount) {
}
} // namespace
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/casts.h b/absl/base/casts.h
index cd07d8f6..bba623b4 100644
--- a/absl/base/casts.h
+++ b/absl/base/casts.h
@@ -25,12 +25,36 @@
#define ABSL_BASE_CASTS_H_
#include
+#include
#include
#include "absl/base/internal/identity.h"
+#include "absl/base/macros.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
+
+namespace internal_casts {
+
+// NOTE: Not a fully compliant implementation of `std::is_trivially_copyable`.
+// TODO(calabrese) Branch on implementations that directly provide
+// `std::is_trivially_copyable`, create a more rigorous workaround, and publicly
+// expose in meta/type_traits.
+template
+struct is_trivially_copyable
+ : std::integral_constant<
+ bool, std::is_destructible::value&& __has_trivial_destructor(T) &&
+ __has_trivial_copy(T) && __has_trivial_assign(T)> {};
+
+template
+struct is_bitcastable
+ : std::integral_constant::value &&
+ is_trivially_copyable::value &&
+ std::is_default_constructible::value> {};
+
+} // namespace internal_casts
// implicit_cast()
//
@@ -82,7 +106,7 @@ inline namespace lts_2018_06_20 {
//
// Such implicit cast chaining may be useful within template logic.
template
-inline To implicit_cast(typename absl::internal::identity_t to) {
+constexpr To implicit_cast(typename absl::internal::identity_t to) {
return to;
}
@@ -126,7 +150,32 @@ inline To implicit_cast(typename absl::internal::identity_t to) {
// and reading its bits back using a different type. A `bit_cast()` avoids this
// issue by implementing its casts using `memcpy()`, which avoids introducing
// this undefined behavior.
-template
+//
+// NOTE: The requirements here are more strict than the bit_cast of standard
+// proposal p0476 due to the need for workarounds and lack of intrinsics.
+// Specifically, this implementation also requires `Dest` to be
+// default-constructible.
+template <
+ typename Dest, typename Source,
+ typename std::enable_if::value,
+ int>::type = 0>
+inline Dest bit_cast(const Source& source) {
+ Dest dest;
+ memcpy(static_cast(std::addressof(dest)),
+ static_cast(std::addressof(source)), sizeof(dest));
+ return dest;
+}
+
+// NOTE: This overload is only picked if the requirements of bit_cast are not
+// met. It is therefore UB, but is provided temporarily as previous versions of
+// this function template were unchecked. Do not use this in new code.
+template <
+ typename Dest, typename Source,
+ typename std::enable_if<
+ !internal_casts::is_bitcastable::value, int>::type = 0>
+ABSL_DEPRECATED(
+ "absl::bit_cast type requirements were violated. Update the types being "
+ "used such that they are the same size and are both TriviallyCopyable.")
inline Dest bit_cast(const Source& source) {
static_assert(sizeof(Dest) == sizeof(Source),
"Source and destination types should have equal sizes.");
@@ -136,7 +185,7 @@ inline Dest bit_cast(const Source& source) {
return dest;
}
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_CASTS_H_
diff --git a/absl/base/config.h b/absl/base/config.h
index 2f5f1595..db4c4539 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__)
@@ -199,7 +205,7 @@
#define ABSL_HAVE_INTRINSIC_INT128 1
#elif defined(__CUDACC__)
// __CUDACC_VER__ is a full version number before CUDA 9, and is defined to a
-// std::string explaining that it has been removed starting with CUDA 9. We use
+// string explaining that it has been removed starting with CUDA 9. We use
// nested #ifs because there is no short-circuiting in the preprocessor.
// NOTE: `__CUDACC__` could be undefined while `__CUDACC_VER__` is defined.
#if __CUDACC_VER__ >= 70000
@@ -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(__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 , , or 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 exists.
@@ -364,7 +385,8 @@
#endif
#ifdef __has_include
-#if __has_include() && __cplusplus >= 201703L
+#if __has_include() && __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() && __cplusplus >= 201703L
+#if __has_include() && __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() && __cplusplus >= 201703L
+#if __has_include() && __cplusplus >= 201703L && \
+ ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES
#define ABSL_HAVE_STD_VARIANT 1
#endif
#endif
@@ -414,14 +438,21 @@
// , is implemented) or higher. Also, `__cplusplus` is
// not correctly set by MSVC, so we use `_MSVC_LANG` to check the language
// version.
-// TODO(zhangxy): fix tests before enabling aliasing for `std::any`,
-// `std::string_view`.
+// TODO(zhangxy): fix tests before enabling aliasing for `std::any`.
#if defined(_MSC_VER) && _MSC_VER >= 1910 && \
((defined(_MSVC_LANG) && _MSVC_LANG > 201402) || __cplusplus > 201402)
// #define ABSL_HAVE_STD_ANY 1
#define ABSL_HAVE_STD_OPTIONAL 1
#define ABSL_HAVE_STD_VARIANT 1
-// #define ABSL_HAVE_STD_STRING_VIEW 1
+#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 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 97c8d6f8..7518264d 100644
--- a/absl/base/exception_safety_testing_test.cc
+++ b/absl/base/exception_safety_testing_test.cc
@@ -38,7 +38,7 @@ template
void ExpectNoThrow(const F& f) {
try {
f();
- } catch (TestException e) {
+ } catch (const TestException& e) {
ADD_FAILURE() << "Unexpected exception thrown from " << e.what();
}
}
@@ -179,7 +179,7 @@ TEST(ThrowingValueTest, ThrowingStreamOps) {
}
// Tests the operator<< of ThrowingValue by forcing ConstructorTracker to emit
-// a nonfatal failure that contains the std::string representation of the Thrower
+// a nonfatal failure that contains the string representation of the Thrower
TEST(ThrowingValueTest, StreamOpsOutput) {
using ::testing::TypeSpec;
exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown);
@@ -548,21 +548,21 @@ TEST(ExceptionSafetyTesterTest, IncompleteTypesAreNotTestable) {
// Test that providing operation and inveriants still does not allow for the
// the invocation of .Test() and .Test(op) because it lacks a factory
auto without_fac =
- testing::MakeExceptionSafetyTester().WithOperation(op).WithInvariants(
+ testing::MakeExceptionSafetyTester().WithOperation(op).WithContracts(
inv, testing::strong_guarantee);
EXPECT_FALSE(HasNullaryTest(without_fac));
EXPECT_FALSE(HasUnaryTest(without_fac));
- // Test that providing invariants and factory allows the invocation of
+ // Test that providing contracts and factory allows the invocation of
// .Test(op) but does not allow for .Test() because it lacks an operation
auto without_op = testing::MakeExceptionSafetyTester()
- .WithInvariants(inv, testing::strong_guarantee)
+ .WithContracts(inv, testing::strong_guarantee)
.WithFactory(fac);
EXPECT_FALSE(HasNullaryTest(without_op));
EXPECT_TRUE(HasUnaryTest(without_op));
// Test that providing operation and factory still does not allow for the
- // the invocation of .Test() and .Test(op) because it lacks invariants
+ // the invocation of .Test() and .Test(op) because it lacks contracts
auto without_inv =
testing::MakeExceptionSafetyTester().WithOperation(op).WithFactory(fac);
EXPECT_FALSE(HasNullaryTest(without_inv));
@@ -577,7 +577,7 @@ std::unique_ptr ExampleFunctionFactory() {
void ExampleFunctionOperation(ExampleStruct*) {}
-testing::AssertionResult ExampleFunctionInvariant(ExampleStruct*) {
+testing::AssertionResult ExampleFunctionContract(ExampleStruct*) {
return testing::AssertionSuccess();
}
@@ -593,16 +593,16 @@ struct {
struct {
testing::AssertionResult operator()(ExampleStruct* example_struct) const {
- return ExampleFunctionInvariant(example_struct);
+ return ExampleFunctionContract(example_struct);
}
-} example_struct_invariant;
+} example_struct_contract;
auto example_lambda_factory = []() { return ExampleFunctionFactory(); };
auto example_lambda_operation = [](ExampleStruct*) {};
-auto example_lambda_invariant = [](ExampleStruct* example_struct) {
- return ExampleFunctionInvariant(example_struct);
+auto example_lambda_contract = [](ExampleStruct* example_struct) {
+ return ExampleFunctionContract(example_struct);
};
// Testing that function references, pointers, structs with operator() and
@@ -612,28 +612,28 @@ TEST(ExceptionSafetyTesterTest, MixedFunctionTypes) {
EXPECT_TRUE(testing::MakeExceptionSafetyTester()
.WithFactory(ExampleFunctionFactory)
.WithOperation(ExampleFunctionOperation)
- .WithInvariants(ExampleFunctionInvariant)
+ .WithContracts(ExampleFunctionContract)
.Test());
// function pointer
EXPECT_TRUE(testing::MakeExceptionSafetyTester()
.WithFactory(&ExampleFunctionFactory)
.WithOperation(&ExampleFunctionOperation)
- .WithInvariants(&ExampleFunctionInvariant)
+ .WithContracts(&ExampleFunctionContract)
.Test());
// struct
EXPECT_TRUE(testing::MakeExceptionSafetyTester()
.WithFactory(example_struct_factory)
.WithOperation(example_struct_operation)
- .WithInvariants(example_struct_invariant)
+ .WithContracts(example_struct_contract)
.Test());
// lambda
EXPECT_TRUE(testing::MakeExceptionSafetyTester()
.WithFactory(example_lambda_factory)
.WithOperation(example_lambda_operation)
- .WithInvariants(example_lambda_invariant)
+ .WithContracts(example_lambda_contract)
.Test());
}
@@ -658,9 +658,9 @@ struct {
} invoker;
auto tester =
- testing::MakeExceptionSafetyTester().WithOperation(invoker).WithInvariants(
+ testing::MakeExceptionSafetyTester().WithOperation(invoker).WithContracts(
CheckNonNegativeInvariants);
-auto strong_tester = tester.WithInvariants(testing::strong_guarantee);
+auto strong_tester = tester.WithContracts(testing::strong_guarantee);
struct FailsBasicGuarantee : public NonNegative {
void operator()() {
@@ -690,7 +690,7 @@ TEST(ExceptionCheckTest, StrongGuaranteeFailure) {
EXPECT_FALSE(strong_tester.WithInitialValue(FollowsBasicGuarantee{}).Test());
}
-struct BasicGuaranteeWithExtraInvariants : public NonNegative {
+struct BasicGuaranteeWithExtraContracts : public NonNegative {
// After operator(), i is incremented. If operator() throws, i is set to 9999
void operator()() {
int old_i = i;
@@ -701,21 +701,21 @@ struct BasicGuaranteeWithExtraInvariants : public NonNegative {
static constexpr int kExceptionSentinel = 9999;
};
-constexpr int BasicGuaranteeWithExtraInvariants::kExceptionSentinel;
+constexpr int BasicGuaranteeWithExtraContracts::kExceptionSentinel;
-TEST(ExceptionCheckTest, BasicGuaranteeWithExtraInvariants) {
+TEST(ExceptionCheckTest, BasicGuaranteeWithExtraContracts) {
auto tester_with_val =
- tester.WithInitialValue(BasicGuaranteeWithExtraInvariants{});
+ tester.WithInitialValue(BasicGuaranteeWithExtraContracts{});
EXPECT_TRUE(tester_with_val.Test());
EXPECT_TRUE(
tester_with_val
- .WithInvariants([](BasicGuaranteeWithExtraInvariants* o) {
- if (o->i == BasicGuaranteeWithExtraInvariants::kExceptionSentinel) {
+ .WithContracts([](BasicGuaranteeWithExtraContracts* o) {
+ if (o->i == BasicGuaranteeWithExtraContracts::kExceptionSentinel) {
return testing::AssertionSuccess();
}
return testing::AssertionFailure()
<< "i should be "
- << BasicGuaranteeWithExtraInvariants::kExceptionSentinel
+ << BasicGuaranteeWithExtraContracts::kExceptionSentinel
<< ", but is " << o->i;
})
.Test());
@@ -740,7 +740,7 @@ struct HasReset : public NonNegative {
void reset() { i = 0; }
};
-testing::AssertionResult CheckHasResetInvariants(HasReset* h) {
+testing::AssertionResult CheckHasResetContracts(HasReset* h) {
h->reset();
return testing::AssertionResult(h->i == 0);
}
@@ -759,17 +759,29 @@ TEST(ExceptionCheckTest, ModifyingChecker) {
};
EXPECT_FALSE(tester.WithInitialValue(FollowsBasicGuarantee{})
- .WithInvariants(set_to_1000, is_1000)
+ .WithContracts(set_to_1000, is_1000)
.Test());
EXPECT_TRUE(strong_tester.WithInitialValue(FollowsStrongGuarantee{})
- .WithInvariants(increment)
+ .WithContracts(increment)
.Test());
EXPECT_TRUE(testing::MakeExceptionSafetyTester()
.WithInitialValue(HasReset{})
- .WithInvariants(CheckHasResetInvariants)
+ .WithContracts(CheckHasResetContracts)
.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} {}
@@ -799,7 +811,7 @@ TEST(ExceptionCheckTest, NonEqualityComparable) {
return testing::AssertionResult(nec->i == NonEqualityComparable().i);
};
auto strong_nec_tester = tester.WithInitialValue(NonEqualityComparable{})
- .WithInvariants(nec_is_strong);
+ .WithContracts(nec_is_strong);
EXPECT_TRUE(strong_nec_tester.Test());
EXPECT_FALSE(strong_nec_tester.Test(
@@ -833,14 +845,14 @@ struct {
testing::AssertionResult operator()(ExhaustivenessTester*) const {
return testing::AssertionSuccess();
}
-} CheckExhaustivenessTesterInvariants;
+} CheckExhaustivenessTesterContracts;
template
unsigned char ExhaustivenessTester::successes = 0;
TEST(ExceptionCheckTest, Exhaustiveness) {
auto exhaust_tester = testing::MakeExceptionSafetyTester()
- .WithInvariants(CheckExhaustivenessTesterInvariants)
+ .WithContracts(CheckExhaustivenessTesterContracts)
.WithOperation(invoker);
EXPECT_TRUE(
@@ -849,7 +861,7 @@ TEST(ExceptionCheckTest, Exhaustiveness) {
EXPECT_TRUE(
exhaust_tester.WithInitialValue(ExhaustivenessTester>{})
- .WithInvariants(testing::strong_guarantee)
+ .WithContracts(testing::strong_guarantee)
.Test());
EXPECT_EQ(ExhaustivenessTester>::successes, 0xF);
}
@@ -931,8 +943,8 @@ TEST(ThrowingValueTraitsTest, RelationalOperators) {
}
TEST(ThrowingAllocatorTraitsTest, Assignablility) {
- EXPECT_TRUE(std::is_move_assignable>::value);
- EXPECT_TRUE(std::is_copy_assignable>::value);
+ EXPECT_TRUE(absl::is_move_assignable>::value);
+ EXPECT_TRUE(absl::is_copy_assignable>::value);
EXPECT_TRUE(std::is_nothrow_move_assignable>::value);
EXPECT_TRUE(std::is_nothrow_copy_assignable>::value);
}
diff --git a/absl/base/inline_variable_test.cc b/absl/base/inline_variable_test.cc
index b34aebd8..b968b10f 100644
--- a/absl/base/inline_variable_test.cc
+++ b/absl/base/inline_variable_test.cc
@@ -20,7 +20,7 @@
#include "gtest/gtest.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace inline_variable_testing_internal {
namespace {
@@ -60,5 +60,5 @@ TEST(InlineVariableTest, FunPtrType) {
} // namespace
} // namespace inline_variable_testing_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/inline_variable_test_a.cc b/absl/base/inline_variable_test_a.cc
index 0ea363af..a51b1d81 100644
--- a/absl/base/inline_variable_test_a.cc
+++ b/absl/base/inline_variable_test_a.cc
@@ -15,7 +15,7 @@
#include "absl/base/internal/inline_variable_testing.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace inline_variable_testing_internal {
const Foo& get_foo_a() { return inline_variable_foo; }
@@ -23,5 +23,5 @@ const Foo& get_foo_a() { return inline_variable_foo; }
const int& get_int_a() { return inline_variable_int; }
} // namespace inline_variable_testing_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/inline_variable_test_b.cc b/absl/base/inline_variable_test_b.cc
index 32704cf1..5041e20a 100644
--- a/absl/base/inline_variable_test_b.cc
+++ b/absl/base/inline_variable_test_b.cc
@@ -15,7 +15,7 @@
#include "absl/base/internal/inline_variable_testing.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace inline_variable_testing_internal {
const Foo& get_foo_b() { return inline_variable_foo; }
@@ -23,5 +23,5 @@ const Foo& get_foo_b() { return inline_variable_foo; }
const int& get_int_b() { return inline_variable_int; }
} // namespace inline_variable_testing_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/internal/atomic_hook.h b/absl/base/internal/atomic_hook.h
index 7d0ee2fa..58ddf272 100644
--- a/absl/base/internal/atomic_hook.h
+++ b/absl/base/internal/atomic_hook.h
@@ -28,7 +28,7 @@
#endif
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
template
@@ -161,7 +161,7 @@ class AtomicHook {
#undef ABSL_HAVE_WORKING_ATOMIC_POINTER
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_
diff --git a/absl/base/internal/bits.h b/absl/base/internal/bits.h
new file mode 100644
index 00000000..29657426
--- /dev/null
+++ b/absl/base/internal/bits.h
@@ -0,0 +1,195 @@
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_BASE_INTERNAL_BITS_H_
+#define ABSL_BASE_INTERNAL_BITS_H_
+
+// This file contains bitwise ops which are implementation details of various
+// absl libraries.
+
+#include
+
+// Clang on Windows has __builtin_clzll; otherwise we need to use the
+// windows intrinsic functions.
+#if defined(_MSC_VER)
+#include
+#if defined(_M_X64)
+#pragma intrinsic(_BitScanReverse64)
+#pragma intrinsic(_BitScanForward64)
+#endif
+#pragma intrinsic(_BitScanReverse)
+#pragma intrinsic(_BitScanForward)
+#endif
+
+#include "absl/base/attributes.h"
+
+#if defined(_MSC_VER)
+// We can achieve something similar to attribute((always_inline)) with MSVC by
+// using the __forceinline keyword, however this is not perfect. MSVC is
+// much less aggressive about inlining, and even with the __forceinline keyword.
+#define ABSL_BASE_INTERNAL_FORCEINLINE __forceinline
+#else
+// Use default attribute inline.
+#define ABSL_BASE_INTERNAL_FORCEINLINE inline ABSL_ATTRIBUTE_ALWAYS_INLINE
+#endif
+
+
+namespace absl {
+inline namespace lts_2018_12_18 {
+namespace base_internal {
+
+ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64Slow(uint64_t n) {
+ int zeroes = 60;
+ if (n >> 32) zeroes -= 32, n >>= 32;
+ if (n >> 16) zeroes -= 16, n >>= 16;
+ if (n >> 8) zeroes -= 8, n >>= 8;
+ if (n >> 4) zeroes -= 4, n >>= 4;
+ return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes;
+}
+
+ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64(uint64_t n) {
+#if defined(_MSC_VER) && defined(_M_X64)
+ // MSVC does not have __buitin_clzll. Use _BitScanReverse64.
+ unsigned long result = 0; // NOLINT(runtime/int)
+ if (_BitScanReverse64(&result, n)) {
+ return 63 - result;
+ }
+ return 64;
+#elif defined(_MSC_VER)
+ // MSVC does not have __buitin_clzll. Compose two calls to _BitScanReverse
+ unsigned long result = 0; // NOLINT(runtime/int)
+ if ((n >> 32) && _BitScanReverse(&result, n >> 32)) {
+ return 31 - result;
+ }
+ if (_BitScanReverse(&result, n)) {
+ return 63 - result;
+ }
+ return 64;
+#elif defined(__GNUC__)
+ // Use __builtin_clzll, which uses the following instructions:
+ // x86: bsr
+ // ARM64: clz
+ // PPC: cntlzd
+ static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int)
+ "__builtin_clzll does not take 64-bit arg");
+
+ // Handle 0 as a special case because __builtin_clzll(0) is undefined.
+ if (n == 0) {
+ return 64;
+ }
+ return __builtin_clzll(n);
+#else
+ return CountLeadingZeros64Slow(n);
+#endif
+}
+
+ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros32Slow(uint64_t n) {
+ int zeroes = 28;
+ if (n >> 16) zeroes -= 16, n >>= 16;
+ if (n >> 8) zeroes -= 8, n >>= 8;
+ if (n >> 4) zeroes -= 4, n >>= 4;
+ return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes;
+}
+
+ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros32(uint32_t n) {
+#if defined(_MSC_VER)
+ unsigned long result = 0; // NOLINT(runtime/int)
+ if (_BitScanReverse(&result, n)) {
+ return 31 - result;
+ }
+ return 32;
+#elif defined(__GNUC__)
+ // Use __builtin_clz, which uses the following instructions:
+ // x86: bsr
+ // ARM64: clz
+ // PPC: cntlzd
+ static_assert(sizeof(int) == sizeof(n),
+ "__builtin_clz does not take 32-bit arg");
+
+ // Handle 0 as a special case because __builtin_clz(0) is undefined.
+ if (n == 0) {
+ return 32;
+ }
+ return __builtin_clz(n);
+#else
+ return CountLeadingZeros32Slow(n);
+#endif
+}
+
+ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero64Slow(uint64_t n) {
+ int c = 63;
+ n &= ~n + 1;
+ if (n & 0x00000000FFFFFFFF) c -= 32;
+ if (n & 0x0000FFFF0000FFFF) c -= 16;
+ if (n & 0x00FF00FF00FF00FF) c -= 8;
+ if (n & 0x0F0F0F0F0F0F0F0F) c -= 4;
+ if (n & 0x3333333333333333) c -= 2;
+ if (n & 0x5555555555555555) c -= 1;
+ return c;
+}
+
+ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero64(uint64_t n) {
+#if defined(_MSC_VER) && defined(_M_X64)
+ unsigned long result = 0; // NOLINT(runtime/int)
+ _BitScanForward64(&result, n);
+ return result;
+#elif defined(_MSC_VER)
+ unsigned long result = 0; // NOLINT(runtime/int)
+ if (static_cast(n) == 0) {
+ _BitScanForward(&result, n >> 32);
+ return result + 32;
+ }
+ _BitScanForward(&result, n);
+ return result;
+#elif defined(__GNUC__)
+ static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int)
+ "__builtin_ctzll does not take 64-bit arg");
+ return __builtin_ctzll(n);
+#else
+ return CountTrailingZerosNonZero64Slow(n);
+#endif
+}
+
+ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32Slow(uint32_t n) {
+ int c = 31;
+ n &= ~n + 1;
+ if (n & 0x0000FFFF) c -= 16;
+ if (n & 0x00FF00FF) c -= 8;
+ if (n & 0x0F0F0F0F) c -= 4;
+ if (n & 0x33333333) c -= 2;
+ if (n & 0x55555555) c -= 1;
+ return c;
+}
+
+ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32(uint32_t n) {
+#if defined(_MSC_VER)
+ unsigned long result = 0; // NOLINT(runtime/int)
+ _BitScanForward(&result, n);
+ return result;
+#elif defined(__GNUC__)
+ static_assert(sizeof(int) == sizeof(n),
+ "__builtin_ctz does not take 32-bit arg");
+ return __builtin_ctz(n);
+#else
+ return CountTrailingZerosNonZero32Slow(n);
+#endif
+}
+
+#undef ABSL_BASE_INTERNAL_FORCEINLINE
+
+} // namespace base_internal
+} // inline namespace lts_2018_12_18
+} // namespace absl
+
+#endif // ABSL_BASE_INTERNAL_BITS_H_
diff --git a/absl/base/internal/bits_test.cc b/absl/base/internal/bits_test.cc
new file mode 100644
index 00000000..e5d991d6
--- /dev/null
+++ b/absl/base/internal/bits_test.cc
@@ -0,0 +1,97 @@
+// 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/base/internal/bits.h"
+
+#include "gtest/gtest.h"
+
+namespace {
+
+int CLZ64(uint64_t n) {
+ int fast = absl::base_internal::CountLeadingZeros64(n);
+ int slow = absl::base_internal::CountLeadingZeros64Slow(n);
+ EXPECT_EQ(fast, slow) << n;
+ return fast;
+}
+
+TEST(BitsTest, CountLeadingZeros64) {
+ EXPECT_EQ(64, CLZ64(uint64_t{}));
+ EXPECT_EQ(0, CLZ64(~uint64_t{}));
+
+ for (int index = 0; index < 64; index++) {
+ uint64_t x = static_cast(1) << index;
+ const auto cnt = 63 - index;
+ ASSERT_EQ(cnt, CLZ64(x)) << index;
+ ASSERT_EQ(cnt, CLZ64(x + x - 1)) << index;
+ }
+}
+
+int CLZ32(uint32_t n) {
+ int fast = absl::base_internal::CountLeadingZeros32(n);
+ int slow = absl::base_internal::CountLeadingZeros32Slow(n);
+ EXPECT_EQ(fast, slow) << n;
+ return fast;
+}
+
+TEST(BitsTest, CountLeadingZeros32) {
+ EXPECT_EQ(32, CLZ32(uint32_t{}));
+ EXPECT_EQ(0, CLZ32(~uint32_t{}));
+
+ for (int index = 0; index < 32; index++) {
+ uint32_t x = static_cast(1) << index;
+ const auto cnt = 31 - index;
+ ASSERT_EQ(cnt, CLZ32(x)) << index;
+ ASSERT_EQ(cnt, CLZ32(x + x - 1)) << index;
+ ASSERT_EQ(CLZ64(x), CLZ32(x) + 32);
+ }
+}
+
+int CTZ64(uint64_t n) {
+ int fast = absl::base_internal::CountTrailingZerosNonZero64(n);
+ int slow = absl::base_internal::CountTrailingZerosNonZero64Slow(n);
+ EXPECT_EQ(fast, slow) << n;
+ return fast;
+}
+
+TEST(BitsTest, CountTrailingZerosNonZero64) {
+ EXPECT_EQ(0, CTZ64(~uint64_t{}));
+
+ for (int index = 0; index < 64; index++) {
+ uint64_t x = static_cast(1) << index;
+ const auto cnt = index;
+ ASSERT_EQ(cnt, CTZ64(x)) << index;
+ ASSERT_EQ(cnt, CTZ64(~(x - 1))) << index;
+ }
+}
+
+int CTZ32(uint32_t n) {
+ int fast = absl::base_internal::CountTrailingZerosNonZero32(n);
+ int slow = absl::base_internal::CountTrailingZerosNonZero32Slow(n);
+ EXPECT_EQ(fast, slow) << n;
+ return fast;
+}
+
+TEST(BitsTest, CountTrailingZerosNonZero32) {
+ EXPECT_EQ(0, CTZ32(~uint32_t{}));
+
+ for (int index = 0; index < 32; index++) {
+ uint32_t x = static_cast(1) << index;
+ const auto cnt = index;
+ ASSERT_EQ(cnt, CTZ32(x)) << index;
+ ASSERT_EQ(cnt, CTZ32(~(x - 1))) << index;
+ }
+}
+
+
+} // namespace
diff --git a/absl/base/internal/cycleclock.cc b/absl/base/internal/cycleclock.cc
index a4f1fc21..d99b63d3 100644
--- a/absl/base/internal/cycleclock.cc
+++ b/absl/base/internal/cycleclock.cc
@@ -27,7 +27,7 @@
#include "absl/base/internal/unscaledcycleclock.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
#if ABSL_USE_UNSCALED_CYCLECLOCK
@@ -79,5 +79,5 @@ double CycleClock::Frequency() {
#endif
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/internal/cycleclock.h b/absl/base/internal/cycleclock.h
index 5fd8b348..ae5ede3e 100644
--- a/absl/base/internal/cycleclock.h
+++ b/absl/base/internal/cycleclock.h
@@ -46,7 +46,7 @@
#include
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
// -----------------------------------------------------------------------------
@@ -73,7 +73,7 @@ class CycleClock {
};
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_CYCLECLOCK_H_
diff --git a/absl/base/internal/direct_mmap.h b/absl/base/internal/direct_mmap.h
index e98c9960..f064e363 100644
--- a/absl/base/internal/direct_mmap.h
+++ b/absl/base/internal/direct_mmap.h
@@ -62,7 +62,7 @@ extern "C" void* __mmap2(void*, size_t, int, int, int, size_t);
#endif // __BIONIC__
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
// Platform specific logic extracted from
@@ -76,7 +76,11 @@ inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd,
// 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;
@@ -93,11 +97,13 @@ inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd,
#endif
#elif defined(__s390x__)
// On s390x, mmap() arguments are passed in memory.
- uint32_t buf[6] = {
- reinterpret_cast(start), static_cast(length),
- static_cast(prot), static_cast(flags),
- static_cast(fd), static_cast(offset)};
- return reintrepret_cast(syscall(SYS_mmap, buf));
+ unsigned long buf[6] = {reinterpret_cast(start), // NOLINT
+ static_cast(length), // NOLINT
+ static_cast(prot), // NOLINT
+ static_cast(flags), // NOLINT
+ static_cast(fd), // NOLINT
+ static_cast(offset)}; // NOLINT
+ return reinterpret_cast(syscall(SYS_mmap, buf));
#elif defined(__x86_64__)
// The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
// We need to explicitly cast to an unsigned 64 bit type to avoid implicit
@@ -123,7 +129,7 @@ inline int DirectMunmap(void* start, size_t length) {
}
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#else // !__linux__
@@ -132,7 +138,7 @@ inline int DirectMunmap(void* start, size_t length) {
// actual mmap()/munmap() methods.
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd,
@@ -145,7 +151,7 @@ inline int DirectMunmap(void* start, size_t length) {
}
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // __linux__
diff --git a/absl/base/internal/endian.h b/absl/base/internal/endian.h
index 00447110..52c09c5b 100644
--- a/absl/base/internal/endian.h
+++ b/absl/base/internal/endian.h
@@ -34,7 +34,7 @@
#include "absl/base/port.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
// Use compiler byte-swapping intrinsics if they are available. 32-bit
// and 64-bit versions are available in Clang and GCC as of GCC 4.3.0.
@@ -83,14 +83,14 @@ inline uint64_t gbswap_64(uint64_t host_int) {
#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
}
@@ -98,8 +98,10 @@ inline uint32_t gbswap_32(uint32_t host_int) {
#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
}
@@ -107,7 +109,8 @@ inline uint16_t gbswap_16(uint16_t host_int) {
#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
}
@@ -265,7 +268,7 @@ inline void Store64(void *p, uint64_t v) {
} // namespace big_endian
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_ENDIAN_H_
diff --git a/absl/base/internal/endian_test.cc b/absl/base/internal/endian_test.cc
index 66ccd45a..14ac4765 100644
--- a/absl/base/internal/endian_test.cc
+++ b/absl/base/internal/endian_test.cc
@@ -24,7 +24,7 @@
#include "absl/base/config.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace {
const uint64_t kInitialNumber{0x0123456789abcdef};
@@ -34,32 +34,16 @@ const uint16_t k16Value{0x0123};
const int kNumValuesToTest = 1000000;
const int kRandomSeed = 12345;
-#ifdef ABSL_IS_BIG_ENDIAN
+#if defined(ABSL_IS_BIG_ENDIAN)
const uint64_t kInitialInNetworkOrder{kInitialNumber};
const uint64_t k64ValueLE{0xefcdab8967452301};
const uint32_t k32ValueLE{0x67452301};
const uint16_t k16ValueLE{0x2301};
-const uint8_t k8ValueLE{k8Value};
-const uint64_t k64IValueLE{0xefcdab89674523a1};
-const uint32_t k32IValueLE{0x67452391};
-const uint16_t k16IValueLE{0x85ff};
-const uint8_t k8IValueLE{0xff};
-const uint64_t kDoubleValueLE{0x6e861bf0f9210940};
-const uint32_t kFloatValueLE{0xd00f4940};
-const uint8_t kBoolValueLE{0x1};
const uint64_t k64ValueBE{kInitialNumber};
const uint32_t k32ValueBE{k32Value};
const uint16_t k16ValueBE{k16Value};
-const uint8_t k8ValueBE{k8Value};
-const uint64_t k64IValueBE{0xa123456789abcdef};
-const uint32_t k32IValueBE{0x91234567};
-const uint16_t k16IValueBE{0xff85};
-const uint8_t k8IValueBE{0xff};
-const uint64_t kDoubleValueBE{0x400921f9f01b866e};
-const uint32_t kFloatValueBE{0x40490fd0};
-const uint8_t kBoolValueBE{0x1};
-#elif defined ABSL_IS_LITTLE_ENDIAN
+#elif defined(ABSL_IS_LITTLE_ENDIAN)
const uint64_t kInitialInNetworkOrder{0xefcdab8967452301};
const uint64_t k64ValueLE{kInitialNumber};
const uint32_t k32ValueLE{k32Value};
@@ -277,5 +261,5 @@ TEST(EndianessTest, big_endian) {
}
} // namespace
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/internal/exception_safety_testing.cc b/absl/base/internal/exception_safety_testing.cc
index f1d081f7..8207b7d7 100644
--- a/absl/base/internal/exception_safety_testing.cc
+++ b/absl/base/internal/exception_safety_testing.cc
@@ -23,6 +23,10 @@ exceptions_internal::NoThrowTag nothrow_ctor;
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 8c2f5093..d4d41a8a 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 @@ class ConstructorTracker {
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 @@ class ConstructorTracker {
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 @@ class ConstructorTracker {
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 @@ class ConstructorTracker {
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 address_map_;
int countdown_;
@@ -190,70 +197,6 @@ class TrackedObject {
~TrackedObject() noexcept { ConstructorTracker::ObjectDestructed(this); }
};
-
-template
-absl::optional TestSingleInvariantAtCountdownImpl(
- const Factory& factory, const Operation& operation, int count,
- const Invariant& invariant) {
- auto t_ptr = factory();
- absl::optional current_res;
- SetCountdown(count);
- try {
- operation(t_ptr.get());
- } catch (const exceptions_internal::TestException& e) {
- current_res.emplace(invariant(t_ptr.get()));
- if (!current_res.value()) {
- *current_res << e.what() << " failed invariant check";
- }
- }
- UnsetCountdown();
- return current_res;
-}
-
-template
-absl::optional TestSingleInvariantAtCountdownImpl(
- 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 TestSingleInvariantAtCountdownImpl(factory, operation, count,
- t_is_strong);
-}
-
-template
-int TestSingleInvariantAtCountdown(
- const Factory& factory, const Operation& operation, int count,
- const Invariant& invariant,
- absl::optional* reduced_res) {
- // If reduced_res is empty, it means the current call to
- // TestSingleInvariantAtCountdown(...) 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 = TestSingleInvariantAtCountdownImpl(factory, operation, count,
- invariant);
- }
- return 0;
-}
-
-template
-inline absl::optional TestAllInvariantsAtCountdown(
- const Factory& factory, const Operation& operation, int count,
- const Invariants&... invariants) {
- absl::optional reduced_res;
-
- // Run each checker, short circuiting after the first failure
- int dummy[] = {
- 0, (TestSingleInvariantAtCountdown(factory, operation, count, invariants,
- &reduced_res))...};
- static_cast(dummy);
- return reduced_res;
-}
-
} // namespace exceptions_internal
extern exceptions_internal::NoThrowTag nothrow_ctor;
@@ -773,7 +716,7 @@ class ThrowingAllocator : private exceptions_internal::TrackedObject {
}
size_type max_size() const noexcept {
- return std::numeric_limits::max() / sizeof(value_type);
+ return (std::numeric_limits::max)() / sizeof(value_type);
}
ThrowingAllocator select_on_container_copy_construction() noexcept(
@@ -858,7 +801,7 @@ testing::AssertionResult TestNothrowOp(const Operation& operation) {
try {
operation();
return testing::AssertionSuccess();
- } catch (exceptions_internal::TestException) {
+ } catch (const exceptions_internal::TestException&) {
return testing::AssertionFailure()
<< "TestException thrown during call to operation() when nothrow "
"guarantee was expected.";
@@ -871,7 +814,7 @@ testing::AssertionResult TestNothrowOp(const Operation& operation) {
namespace exceptions_internal {
-// Dummy struct for ExceptionSafetyTester<> partial state.
+// Dummy struct for ExceptionSafetyTestBuilder<> partial state.
struct UninitializedT {};
template
@@ -884,29 +827,106 @@ class DefaultFactory {
T t_;
};
-template
using EnableIfTestable = typename absl::enable_if_t<
- LazyInvariantsCount != 0 &&
+ LazyContractsCount != 0 &&
!std::is_same::value &&
!std::is_same::value>;
template
-class ExceptionSafetyTester;
+ typename Operation = UninitializedT, typename... Contracts>
+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
+struct IsUniquePtr : std::false_type {};
+
+template
+struct IsUniquePtr> : std::true_type {};
+
+template
+struct FactoryPtrTypeHelper {
+ using type = decltype(std::declval()());
+
+ static_assert(IsUniquePtr::value, "Factories must return a unique_ptr");
+};
+
+template
+using FactoryPtrType = typename FactoryPtrTypeHelper::type;
+
+template
+using FactoryElementType = typename FactoryPtrType::element_type;
+
+template
+class ExceptionSafetyTest {
+ using Factory = std::function()>;
+ using Operation = std::function;
+ using Contract = std::function;
+
+ public:
+ template
+ 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
+ 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 contracts_;
+};
/*
* Builds a tester object that tests if performing a operation on a T follows
- * exception safety guarantees. Verification is done via invariant assertion
+ * 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
@@ -921,25 +941,25 @@ namespace exceptions_internal {
* fresh T instance so it's free to modify and destroy the T instances as it
* pleases.
*
- * - Invariants...: The invariant assertion callback objects (passed in via
- * tester.WithInvariants(...)) must be invocable with the signature
+ * - Contracts...: The contract assertion callback objects (passed in via
+ * tester.WithContracts(...)) must be invocable with the signature
* `testing::AssertionResult operator()(T*) const` where T is the type being
- * tested. Invariant assertion callbacks are provided T instances post-throw.
- * They must return testing::AssertionSuccess when the type invariants of the
- * provided T instance hold. If the type invariants of the T instance do not
+ * tested. Contract assertion callbacks are provided T instances post-throw.
+ * They must return testing::AssertionSuccess when the type contracts of the
+ * provided T instance hold. If the type contracts of the T instance do not
* hold, they must return testing::AssertionFailure. Execution order of
- * Invariants... is unspecified. They will each individually get a fresh T
+ * Contracts... is unspecified. They will each individually get a fresh T
* instance so they are free to modify and destroy the T instances as they
* please.
*/
-template
-class ExceptionSafetyTester {
+template
+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,63 +968,63 @@ class ExceptionSafetyTester {
* tester.WithFactory(...).
*/
template
- ExceptionSafetyTester, Operation, Invariants...>
+ ExceptionSafetyTestBuilder, Operation, Contracts...>
WithInitialValue(const T& t) const {
return WithFactory(DefaultFactory(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
- ExceptionSafetyTester, Operation, Invariants...>
+ ExceptionSafetyTestBuilder, Operation, Contracts...>
WithFactory(const NewFactory& new_factory) const {
- return {new_factory, operation_, invariants_};
+ 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
- ExceptionSafetyTester, Invariants...>
+ ExceptionSafetyTestBuilder, Contracts...>
WithOperation(const NewOperation& new_operation) const {
- return {factory_, new_operation, invariants_};
+ return {factory_, new_operation, contracts_};
}
/*
- * Returns a new ExceptionSafetyTester with the provided MoreInvariants...
- * combined with the Invariants... that were already included in the instance
- * on which the method was called. Invariants... cannot be removed or replaced
- * once added to an ExceptionSafetyTester instance. A fresh object must be
- * created in order to get an empty Invariants... list.
+ * 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 ExceptionSafetyTestBuilder instance. A fresh object must
+ * be created in order to get an empty Contracts... list.
*
- * In addition to passing in custom invariant assertion callbacks, this method
+ * In addition to passing in custom contract assertion callbacks, this method
* accepts `testing::strong_guarantee` as an argument which checks T instances
* post-throw against freshly created T instances via operator== to verify
* that any state changes made during the execution of the operation were
* properly rolled back.
*/
- template
- ExceptionSafetyTester...>
- WithInvariants(const MoreInvariants&... more_invariants) const {
- return {factory_, operation_,
- std::tuple_cat(invariants_,
- std::tuple...>(
- more_invariants...))};
+ template
+ ExceptionSafetyTestBuilder...>
+ WithContracts(const MoreContracts&... more_contracts) const {
+ return {
+ factory_, operation_,
+ std::tuple_cat(contracts_, std::tuple...>(
+ more_contracts...))};
}
/*
* Returns a testing::AssertionResult that is the reduced result of the
* exception safety algorithm. The algorithm short circuits and returns
- * AssertionFailure after the first invariant callback returns an
- * AssertionFailure. Otherwise, if all invariant callbacks return an
+ * AssertionFailure after the first contract callback returns an
+ * AssertionFailure. Otherwise, if all contract callbacks return an
* AssertionSuccess, the reduced result is AssertionSuccess.
*
* The passed-in testable operation will not be saved in a new tester instance
@@ -1013,97 +1033,62 @@ class ExceptionSafetyTester {
*
* Preconditions for tester.Test(const NewOperation& new_operation):
*
- * - May only be called after at least one invariant assertion callback and a
+ * - May only be called after at least one contract assertion callback and a
* factory or initial value have been provided.
*/
template <
typename NewOperation,
- typename = EnableIfTestable>
+ typename = EnableIfTestable>
testing::AssertionResult Test(const NewOperation& new_operation) const {
- return TestImpl(new_operation, absl::index_sequence_for());
+ return TestImpl(new_operation, absl::index_sequence_for());
}
/*
* Returns a testing::AssertionResult that is the reduced result of the
* exception safety algorithm. The algorithm short circuits and returns
- * AssertionFailure after the first invariant callback returns an
- * AssertionFailure. Otherwise, if all invariant callbacks return an
+ * AssertionFailure after the first contract callback returns an
+ * AssertionFailure. Otherwise, if all contract callbacks return an
* AssertionSuccess, the reduced result is AssertionSuccess.
*
* Preconditions for tester.Test():
*
- * - May only be called after at least one invariant assertion callback, a
+ * - May only be called after at least one contract assertion callback, a
* factory or initial value and a testable operation have been provided.
*/
- template >
+ template <
+ typename LazyOperation = Operation,
+ typename = EnableIfTestable>
testing::AssertionResult Test() const {
- return TestImpl(operation_, absl::index_sequence_for());
+ return Test(operation_);
}
private:
template
- 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& i)
- : factory_(f), operation_(o), invariants_(i) {}
+ ExceptionSafetyTestBuilder(const Factory& f, const Operation& o,
+ const std::tuple& i)
+ : factory_(f), operation_(o), contracts_(i) {}
template
- testing::AssertionResult TestImpl(const SelectedOperation& selected_operation,
+ testing::AssertionResult TestImpl(SelectedOperation selected_operation,
absl::index_sequence) 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 =
- TestAllInvariantsAtCountdown(factory_, selected_operation, count,
- std::get(invariants_)...);
- // If there is no value in the optional, no invariants 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 invariant 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 invariants passed so the test must
- // continue to run.
- }
+ return ExceptionSafetyTest>(
+ factory_, selected_operation, std::get(contracts_)...)
+ .Test();
}
Factory factory_;
Operation operation_;
- std::tuple invariants_;
+ std::tuple contracts_;
};
} // 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 invariant 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/exception_testing.h b/absl/base/internal/exception_testing.h
index fd89a3f6..0cf7918e 100644
--- a/absl/base/internal/exception_testing.h
+++ b/absl/base/internal/exception_testing.h
@@ -35,7 +35,7 @@
EXPECT_DEATH(expr, ".*")
#else
#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \
- EXPECT_DEATH(expr, text)
+ EXPECT_DEATH_IF_SUPPORTED(expr, text)
#endif
diff --git a/absl/base/internal/hide_ptr.h b/absl/base/internal/hide_ptr.h
index a2694508..ce390dc4 100644
--- a/absl/base/internal/hide_ptr.h
+++ b/absl/base/internal/hide_ptr.h
@@ -18,7 +18,7 @@
#include
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
// Arbitrary value with high bits set. Xor'ing with it is unlikely
@@ -43,7 +43,7 @@ inline T* UnhidePtr(uintptr_t hidden) {
}
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_HIDE_PTR_H_
diff --git a/absl/base/internal/identity.h b/absl/base/internal/identity.h
index 2eaab453..d57c83f4 100644
--- a/absl/base/internal/identity.h
+++ b/absl/base/internal/identity.h
@@ -17,7 +17,7 @@
#define ABSL_BASE_INTERNAL_IDENTITY_H_
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace internal {
template
@@ -29,7 +29,7 @@ template
using identity_t = typename identity::type;
} // namespace internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_IDENTITY_H_
diff --git a/absl/base/internal/inline_variable_testing.h b/absl/base/internal/inline_variable_testing.h
index 49fa4ade..be0b0b96 100644
--- a/absl/base/internal/inline_variable_testing.h
+++ b/absl/base/internal/inline_variable_testing.h
@@ -18,7 +18,7 @@
#include "absl/base/internal/inline_variable.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace inline_variable_testing_internal {
struct Foo {
@@ -40,7 +40,7 @@ const int& get_int_a();
const int& get_int_b();
} // namespace inline_variable_testing_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INLINE_VARIABLE_TESTING_H_
diff --git a/absl/base/internal/invoke.h b/absl/base/internal/invoke.h
index bc05a0a3..1372ef50 100644
--- a/absl/base/internal/invoke.h
+++ b/absl/base/internal/invoke.h
@@ -43,7 +43,7 @@
// top of this file for the API documentation.
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
// The five classes below each implement one of the clauses from the definition
@@ -184,7 +184,7 @@ InvokeT Invoke(F&& f, Args&&... args) {
std::forward(args)...);
}
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_INVOKE_H_
diff --git a/absl/base/internal/low_level_alloc.cc b/absl/base/internal/low_level_alloc.cc
index ca6239ad..10d805cc 100644
--- a/absl/base/internal/low_level_alloc.cc
+++ b/absl/base/internal/low_level_alloc.cc
@@ -63,7 +63,7 @@
#endif // __APPLE__
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
// A first-fit allocator with amortized logarithmic free() time.
@@ -209,7 +209,7 @@ struct LowLevelAlloc::Arena {
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;
@@ -325,8 +325,10 @@ size_t GetPageSize() {
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
}
@@ -402,16 +404,20 @@ bool LowLevelAlloc::DeleteArena(Arena *arena) {
ABSL_RAW_CHECK(munmap_result != 0,
"LowLevelAlloc::DeleteArena: VitualFree failed");
#else
+#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {
munmap_result = munmap(region, size);
} else {
munmap_result = base_internal::DirectMunmap(region, size);
}
+#else
+ munmap_result = munmap(region, size);
+#endif // ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
if (munmap_result != 0) {
ABSL_RAW_LOG(FATAL, "LowLevelAlloc::DeleteArena: munmap failed: %d",
errno);
}
-#endif
+#endif // _WIN32
}
section.Leave();
arena->~Arena();
@@ -546,6 +552,7 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
ABSL_RAW_CHECK(new_pages != nullptr, "VirtualAlloc failed");
#else
+#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
new_pages = base_internal::DirectMmap(nullptr, new_pages_size,
PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
@@ -553,10 +560,15 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
}
+#else
+ new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+#endif // ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
if (new_pages == MAP_FAILED) {
ABSL_RAW_LOG(FATAL, "mmap error: %d", errno);
}
-#endif
+
+#endif // _WIN32
arena->mu.Lock();
s = reinterpret_cast(new_pages);
s->header.size = new_pages_size;
@@ -600,7 +612,7 @@ void *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) {
}
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_LOW_LEVEL_ALLOC_MISSING
diff --git a/absl/base/internal/low_level_alloc.h b/absl/base/internal/low_level_alloc.h
index 3f289571..87cfc934 100644
--- a/absl/base/internal/low_level_alloc.h
+++ b/absl/base/internal/low_level_alloc.h
@@ -39,10 +39,13 @@
#define ABSL_LOW_LEVEL_ALLOC_MISSING 1
#endif
-// Using LowLevelAlloc with kAsyncSignalSafe isn't supported on Windows.
+// Using LowLevelAlloc with kAsyncSignalSafe isn't supported on Windows or
+// asm.js / WebAssembly.
+// See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html
+// for more information.
#ifdef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
#error ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING cannot be directly set
-#elif defined(_WIN32)
+#elif defined(_WIN32) || defined(__asmjs__) || defined(__wasm__)
#define ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 1
#endif
@@ -51,7 +54,7 @@
#include "absl/base/port.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
class LowLevelAlloc {
@@ -116,6 +119,6 @@ class LowLevelAlloc {
};
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_
diff --git a/absl/base/internal/low_level_alloc_test.cc b/absl/base/internal/low_level_alloc_test.cc
index 15ffe298..65bb519d 100644
--- a/absl/base/internal/low_level_alloc_test.cc
+++ b/absl/base/internal/low_level_alloc_test.cc
@@ -22,7 +22,7 @@
#include
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
namespace {
@@ -149,7 +149,7 @@ static struct BeforeMain {
} // namespace
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
int main(int argc, char *argv[]) {
diff --git a/absl/base/internal/low_level_scheduling.h b/absl/base/internal/low_level_scheduling.h
index 2ae464b4..7cb6117e 100644
--- a/absl/base/internal/low_level_scheduling.h
+++ b/absl/base/internal/low_level_scheduling.h
@@ -28,7 +28,7 @@ extern "C" bool __google_disable_rescheduling(void);
extern "C" void __google_enable_rescheduling(bool disable_result);
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
class SchedulingHelper; // To allow use of SchedulingGuard.
@@ -101,6 +101,6 @@ inline void SchedulingGuard::EnableRescheduling(bool /* disable_result */) {
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc
index cd1bbc09..ed8b8d7c 100644
--- a/absl/base/internal/raw_logging.cc
+++ b/absl/base/internal/raw_logging.cc
@@ -139,7 +139,7 @@ void RawLogVA(absl::LogSeverity severity, const char* file, int line,
#endif
#ifdef ABSL_MIN_LOG_LEVEL
- if (static_cast(severity) < ABSL_MIN_LOG_LEVEL &&
+ if (severity < static_cast(ABSL_MIN_LOG_LEVEL) &&
severity < absl::LogSeverity::kFatal) {
enabled = false;
}
@@ -181,7 +181,7 @@ void RawLogVA(absl::LogSeverity severity, const char* file, int line,
} // namespace
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace raw_logging_internal {
void SafeWriteToStderr(const char *s, size_t len) {
#if defined(ABSL_HAVE_SYSCALL_WRITE)
@@ -207,6 +207,15 @@ void RawLog(absl::LogSeverity severity, const char* file, int line,
va_end(ap);
}
+// Non-formatting version of RawLog().
+//
+// TODO(gfalcon): When string_view no longer depends on base, change this
+// interface to take its message as a string_view instead.
+static void DefaultInternalLog(absl::LogSeverity severity, const char* file,
+ int line, const std::string& message) {
+ RawLog(severity, file, line, "%s", message.c_str());
+}
+
bool RawLoggingFullySupported() {
#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
return true;
@@ -215,6 +224,13 @@ bool RawLoggingFullySupported() {
#endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
}
+ABSL_CONST_INIT absl::base_internal::AtomicHook
+ internal_log_function(DefaultInternalLog);
+
+void RegisterInternalLogFunction(InternalLogFunction func) {
+ internal_log_function.Store(func);
+}
+
} // namespace raw_logging_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h
index 04ff0607..2786a3de 100644
--- a/absl/base/internal/raw_logging.h
+++ b/absl/base/internal/raw_logging.h
@@ -19,7 +19,10 @@
#ifndef ABSL_BASE_INTERNAL_RAW_LOGGING_H_
#define ABSL_BASE_INTERNAL_RAW_LOGGING_H_
+#include
+
#include "absl/base/attributes.h"
+#include "absl/base/internal/atomic_hook.h"
#include "absl/base/log_severity.h"
#include "absl/base/macros.h"
#include "absl/base/port.h"
@@ -57,6 +60,34 @@
} \
} while (0)
+// ABSL_INTERNAL_LOG and ABSL_INTERNAL_CHECK work like the RAW variants above,
+// except that if the richer log library is linked into the binary, we dispatch
+// to that instead. This is potentially useful for internal logging and
+// assertions, where we are using RAW_LOG neither for its async-signal-safety
+// nor for its non-allocating nature, but rather because raw logging has very
+// few other dependencies.
+//
+// The API is a subset of the above: each macro only takes two arguments. Use
+// StrCat if you need to build a richer message.
+#define ABSL_INTERNAL_LOG(severity, message) \
+ do { \
+ constexpr const char* absl_raw_logging_internal_basename = \
+ ::absl::raw_logging_internal::Basename(__FILE__, \
+ sizeof(__FILE__) - 1); \
+ ::absl::raw_logging_internal::internal_log_function( \
+ ABSL_RAW_LOGGING_INTERNAL_##severity, \
+ absl_raw_logging_internal_basename, __LINE__, message); \
+ } while (0)
+
+#define ABSL_INTERNAL_CHECK(condition, message) \
+ do { \
+ if (ABSL_PREDICT_FALSE(!(condition))) { \
+ std::string death_message = "Check " #condition " failed: "; \
+ death_message += std::string(message); \
+ ABSL_INTERNAL_LOG(FATAL, death_message); \
+ } \
+ } while (0)
+
#define ABSL_RAW_LOGGING_INTERNAL_INFO ::absl::LogSeverity::kInfo
#define ABSL_RAW_LOGGING_INTERNAL_WARNING ::absl::LogSeverity::kWarning
#define ABSL_RAW_LOGGING_INTERNAL_ERROR ::absl::LogSeverity::kError
@@ -65,7 +96,7 @@
::absl::NormalizeLogSeverity(severity)
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace raw_logging_internal {
// Helper function to implement ABSL_RAW_LOG
@@ -84,7 +115,7 @@ void SafeWriteToStderr(const char *s, size_t len);
// compile-time function to get the "base" filename, that is, the part of
// a filename after the last "/" or "\" path separator. The search starts at
-// the end of the std::string; the second parameter is the length of the std::string.
+// the end of the string; the second parameter is the length of the string.
constexpr const char* Basename(const char* fname, int offset) {
return offset == 0 || fname[offset - 1] == '/' || fname[offset - 1] == '\\'
? fname + offset
@@ -132,8 +163,20 @@ using LogPrefixHook = bool (*)(absl::LogSeverity severity, const char* file,
using AbortHook = void (*)(const char* file, int line, const char* buf_start,
const char* prefix_end, const char* buf_end);
+// Internal logging function for ABSL_INTERNAL_LOG to dispatch to.
+//
+// TODO(gfalcon): When string_view no longer depends on base, change this
+// interface to take its message as a string_view instead.
+using InternalLogFunction = void (*)(absl::LogSeverity severity,
+ const char* file, int line,
+ const std::string& message);
+
+extern base_internal::AtomicHook internal_log_function;
+
+void RegisterInternalLogFunction(InternalLogFunction func);
+
} // namespace raw_logging_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_RAW_LOGGING_H_
diff --git a/absl/base/internal/scheduling_mode.h b/absl/base/internal/scheduling_mode.h
index dd7df6bb..19a7514c 100644
--- a/absl/base/internal/scheduling_mode.h
+++ b/absl/base/internal/scheduling_mode.h
@@ -19,7 +19,7 @@
#define ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
// Used to describe how a thread may be scheduled. Typically associated with
@@ -50,7 +50,7 @@ enum SchedulingMode {
};
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_
diff --git a/absl/base/internal/spinlock.cc b/absl/base/internal/spinlock.cc
index 9d90b3cb..8f8eef82 100644
--- a/absl/base/internal/spinlock.cc
+++ b/absl/base/internal/spinlock.cc
@@ -54,7 +54,7 @@
// holder to acquire the lock. There may be outstanding waiter(s).
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
ABSL_CONST_INIT static base_internal::AtomicHook 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
@@ -142,7 +137,7 @@ void SpinLock::SlowLock() {
// 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.
@@ -171,7 +166,9 @@ void SpinLock::SlowLock() {
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);
}
}
@@ -207,14 +204,20 @@ uint32_t SpinLock::EncodeWaitCycles(int64_t wait_start_time,
(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(
+ // the lock word's upper bits.
+ uint32_t clamped = static_cast(
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) {
@@ -226,5 +229,5 @@ uint64_t SpinLock::DecodeWaitCycles(uint32_t lock_value) {
}
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/internal/spinlock.h b/absl/base/internal/spinlock.h
index 7b59fe26..d53878b2 100644
--- a/absl/base/internal/spinlock.h
+++ b/absl/base/internal/spinlock.h
@@ -45,7 +45,7 @@
#include "absl/base/thread_annotations.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
class LOCKABLE SpinLock {
@@ -102,8 +102,8 @@ class LOCKABLE SpinLock {
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);
@@ -162,7 +162,7 @@ class LOCKABLE SpinLock {
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);
@@ -235,7 +235,7 @@ inline uint32_t SpinLock::TryLockInternal(uint32_t lock_value,
}
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_SPINLOCK_H_
diff --git a/absl/base/internal/spinlock_benchmark.cc b/absl/base/internal/spinlock_benchmark.cc
new file mode 100644
index 00000000..907d3e27
--- /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
+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_linux.inc b/absl/base/internal/spinlock_linux.inc
new file mode 100644
index 00000000..94c861dc
--- /dev/null
+++ b/absl/base/internal/spinlock_linux.inc
@@ -0,0 +1,72 @@
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// This file is a Linux-specific part of spinlock_wait.cc
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "absl/base/attributes.h"
+
+// The SpinLock lockword is `std::atomic`. Here we assert that
+// `std::atomic` is bitwise equivalent of the `int` expected
+// by SYS_futex. We also assume that reads/writes done to the lockword
+// by SYS_futex have rational semantics with regard to the
+// std::atomic<> API. C++ provides no guarantees of these assumptions,
+// but they are believed to hold in practice.
+static_assert(sizeof(std::atomic) == sizeof(int),
+ "SpinLock lockword has the wrong size for a futex");
+
+// Some Android headers are missing these definitions even though they
+// support these futex operations.
+#ifdef __BIONIC__
+#ifndef SYS_futex
+#define SYS_futex __NR_futex
+#endif
+#ifndef FUTEX_PRIVATE_FLAG
+#define FUTEX_PRIVATE_FLAG 128
+#endif
+#endif
+
+extern "C" {
+
+ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay(
+ std::atomic *w, uint32_t value, int loop,
+ absl::base_internal::SchedulingMode) {
+ if (loop != 0) {
+ int save_errno = errno;
+ struct timespec tm;
+ tm.tv_sec = 0;
+ // Increase the delay; we expect (but do not rely on) explicit wakeups.
+ // We don't rely on explicit wakeups because we intentionally allow for
+ // a race on the kSpinLockSleeper bit.
+ tm.tv_nsec = 16 * absl::base_internal::SpinLockSuggestedDelayNS(loop);
+ syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, &tm);
+ errno = save_errno;
+ }
+}
+
+ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake(std::atomic *w,
+ bool all) {
+ syscall(SYS_futex, w, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, all ? INT_MAX : 1, 0);
+}
+
+} // extern "C"
diff --git a/absl/base/internal/spinlock_wait.cc b/absl/base/internal/spinlock_wait.cc
index 6709d01e..3f8e43f0 100644
--- a/absl/base/internal/spinlock_wait.cc
+++ b/absl/base/internal/spinlock_wait.cc
@@ -13,7 +13,7 @@
// limitations under the License.
// The OS-specific header included below must provide two calls:
-// base::subtle::SpinLockDelay() and base::subtle::SpinLockWake().
+// AbslInternalSpinLockDelay() and AbslInternalSpinLockWake().
// See spinlock_wait.h for the specs.
#include
@@ -23,6 +23,8 @@
#if defined(_WIN32)
#include "absl/base/internal/spinlock_win32.inc"
+#elif defined(__linux__)
+#include "absl/base/internal/spinlock_linux.inc"
#elif defined(__akaros__)
#include "absl/base/internal/spinlock_akaros.inc"
#else
@@ -30,21 +32,22 @@
#endif
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
// See spinlock_wait.h for spec.
uint32_t SpinLockWait(std::atomic *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)) {
@@ -77,5 +80,5 @@ int SpinLockSuggestedDelayNS(int loop) {
}
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/internal/spinlock_wait.h b/absl/base/internal/spinlock_wait.h
index 31aaa8c6..5eb727f1 100644
--- a/absl/base/internal/spinlock_wait.h
+++ b/absl/base/internal/spinlock_wait.h
@@ -24,7 +24,7 @@
#include "absl/base/internal/scheduling_mode.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
// SpinLockWait() waits until it can perform one of several transitions from
@@ -63,7 +63,7 @@ void SpinLockDelay(std::atomic *w, uint32_t value, int loop,
int SpinLockSuggestedDelayNS(int loop);
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
// In some build configurations we pass --detect-odr-violations to the
diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc
index 7db2e001..ce14fc0f 100644
--- a/absl/base/internal/sysinfo.cc
+++ b/absl/base/internal/sysinfo.cc
@@ -56,7 +56,7 @@
#include "absl/base/internal/unscaledcycleclock.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
static once_flag init_system_info_once;
@@ -402,5 +402,5 @@ pid_t GetTID() {
#endif
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/internal/sysinfo.h b/absl/base/internal/sysinfo.h
index 18aa2e29..79100f61 100644
--- a/absl/base/internal/sysinfo.h
+++ b/absl/base/internal/sysinfo.h
@@ -33,7 +33,7 @@
#include "absl/base/port.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
// Nominal core processor cycles per second of each processor. This is _not_
@@ -59,7 +59,7 @@ using pid_t = DWORD;
pid_t GetTID();
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_SYSINFO_H_
diff --git a/absl/base/internal/sysinfo_test.cc b/absl/base/internal/sysinfo_test.cc
index fdbbdf88..c072ebc2 100644
--- a/absl/base/internal/sysinfo_test.cc
+++ b/absl/base/internal/sysinfo_test.cc
@@ -28,7 +28,7 @@
#include "absl/synchronization/mutex.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
namespace {
@@ -96,5 +96,5 @@ TEST(SysinfoTest, LinuxGetTID) {
} // namespace
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/internal/thread_identity.cc b/absl/base/internal/thread_identity.cc
index aa1add8b..b35bee34 100644
--- a/absl/base/internal/thread_identity.cc
+++ b/absl/base/internal/thread_identity.cc
@@ -28,7 +28,7 @@
#include "absl/base/internal/spinlock.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
#if ABSL_THREAD_IDENTITY_MODE != ABSL_THREAD_IDENTITY_MODE_USE_CPP11
@@ -69,6 +69,14 @@ void SetCurrentThreadIdentity(
// NOTE: Not async-safe. But can be open-coded.
absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey,
reclaimer);
+
+#ifdef __EMSCRIPTEN__
+ // Emscripten PThread implementation does not support signals.
+ // See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html
+ // for more information.
+ pthread_setspecific(thread_identity_pthread_key,
+ reinterpret_cast(identity));
+#else
// We must mask signals around the call to setspecific as with current glibc,
// a concurrent getspecific (needed for GetCurrentThreadIdentityIfPresent())
// may zero our value.
@@ -82,6 +90,8 @@ void SetCurrentThreadIdentity(
pthread_setspecific(thread_identity_pthread_key,
reinterpret_cast(identity));
pthread_sigmask(SIG_SETMASK, &curr_signals, nullptr);
+#endif // !__EMSCRIPTEN__
+
#elif ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS
// NOTE: Not async-safe. But can be open-coded.
absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey,
@@ -121,5 +131,5 @@ ThreadIdentity* CurrentThreadIdentityIfPresent() {
#endif
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/internal/thread_identity.h b/absl/base/internal/thread_identity.h
index 18a5a750..17ac2a7c 100644
--- a/absl/base/internal/thread_identity.h
+++ b/absl/base/internal/thread_identity.h
@@ -33,7 +33,7 @@
#include "absl/base/internal/per_thread_tls.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
struct SynchLocksHeld;
struct SynchWaitParams;
@@ -237,6 +237,6 @@ inline ThreadIdentity* CurrentThreadIdentityIfPresent() {
#endif
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
diff --git a/absl/base/internal/thread_identity_test.cc b/absl/base/internal/thread_identity_test.cc
index f39f11d2..ec93fc27 100644
--- a/absl/base/internal/thread_identity_test.cc
+++ b/absl/base/internal/thread_identity_test.cc
@@ -25,7 +25,7 @@
#include "absl/synchronization/mutex.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
namespace {
@@ -124,5 +124,5 @@ TEST(ThreadIdentityTest, ReusedThreadIdentityMutexTest) {
} // namespace
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/internal/throw_delegate.cc b/absl/base/internal/throw_delegate.cc
index 5466e0f3..0f73c3eb 100644
--- a/absl/base/internal/throw_delegate.cc
+++ b/absl/base/internal/throw_delegate.cc
@@ -22,7 +22,7 @@
#include "absl/base/internal/raw_logging.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
namespace {
@@ -31,8 +31,8 @@ template
#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
@@ -104,5 +104,5 @@ void ThrowStdBadFunctionCall() { Throw(std::bad_function_call()); }
void ThrowStdBadAlloc() { Throw(std::bad_alloc()); }
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/internal/throw_delegate.h b/absl/base/internal/throw_delegate.h
index d34ff79c..7e5510c0 100644
--- a/absl/base/internal/throw_delegate.h
+++ b/absl/base/internal/throw_delegate.h
@@ -20,7 +20,7 @@
#include
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
// Helper functions that allow throwing exceptions consistently from anywhere.
@@ -67,7 +67,7 @@ namespace base_internal {
// [[noreturn]] void ThrowStdBadArrayNewLength();
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_THROW_DELEGATE_H_
diff --git a/absl/base/internal/unaligned_access.h b/absl/base/internal/unaligned_access.h
index f20a8694..07a64bba 100644
--- a/absl/base/internal/unaligned_access.h
+++ b/absl/base/internal/unaligned_access.h
@@ -65,7 +65,8 @@ void __sanitizer_unaligned_store64(void *p, uint64_t v);
} // extern "C"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
+namespace base_internal {
inline uint16_t UnalignedLoad16(const void *p) {
return __sanitizer_unaligned_load16(p);
@@ -91,19 +92,71 @@ inline void UnalignedStore64(void *p, uint64_t v) {
__sanitizer_unaligned_store64(p, v);
}
-} // inline namespace lts_2018_06_20
+} // namespace base_internal
+} // inline namespace lts_2018_12_18
} // namespace absl
-#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) (absl::UnalignedLoad16(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) (absl::UnalignedLoad32(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
+ (absl::base_internal::UnalignedLoad16(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
+ (absl::base_internal::UnalignedLoad32(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
+ (absl::base_internal::UnalignedLoad64(_p))
+
+#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
+ (absl::base_internal::UnalignedStore16(_p, _val))
+#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
+ (absl::base_internal::UnalignedStore32(_p, _val))
+#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
+ (absl::base_internal::UnalignedStore64(_p, _val))
+
+#elif defined(UNDEFINED_BEHAVIOR_SANITIZER)
+
+namespace absl {
+inline namespace lts_2018_12_18 {
+namespace base_internal {
+
+inline uint16_t UnalignedLoad16(const void *p) {
+ uint16_t t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint32_t UnalignedLoad32(const void *p) {
+ uint32_t t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint64_t UnalignedLoad64(const void *p) {
+ uint64_t t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline void UnalignedStore16(void *p, uint16_t v) { memcpy(p, &v, sizeof v); }
+
+inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); }
+
+inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
+
+} // namespace base_internal
+} // inline namespace lts_2018_12_18
+} // namespace absl
+
+#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
+ (absl::base_internal::UnalignedLoad16(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
+ (absl::base_internal::UnalignedLoad32(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
+ (absl::base_internal::UnalignedLoad64(_p))
#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
- (absl::UnalignedStore16(_p, _val))
+ (absl::base_internal::UnalignedStore16(_p, _val))
#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
- (absl::UnalignedStore32(_p, _val))
+ (absl::base_internal::UnalignedStore32(_p, _val))
#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
- (absl::UnalignedStore64(_p, _val))
+ (absl::base_internal::UnalignedStore64(_p, _val))
#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386) || \
defined(_M_IX86) || defined(__ppc__) || defined(__PPC__) || \
@@ -160,8 +213,8 @@ inline void UnalignedStore64(void *p, uint64_t v) {
// so we do that.
namespace absl {
-inline namespace lts_2018_06_20 {
-namespace internal {
+inline namespace lts_2018_12_18 {
+namespace base_internal {
struct Unaligned16Struct {
uint16_t value;
@@ -173,24 +226,27 @@ struct Unaligned32Struct {
uint8_t dummy; // To make the size non-power-of-two.
} ABSL_ATTRIBUTE_PACKED;
-} // namespace internal
-} // inline namespace lts_2018_06_20
+} // namespace base_internal
+} // inline namespace lts_2018_12_18
} // namespace absl
-#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
- ((reinterpret_cast(_p))->value)
-#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
- ((reinterpret_cast(_p))->value)
+#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
+ ((reinterpret_cast(_p)) \
+ ->value)
+#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
+ ((reinterpret_cast(_p)) \
+ ->value)
-#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
- ((reinterpret_cast< ::absl::internal::Unaligned16Struct *>(_p))->value = \
- (_val))
-#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
- ((reinterpret_cast< ::absl::internal::Unaligned32Struct *>(_p))->value = \
- (_val))
+#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
+ ((reinterpret_cast< ::absl::base_internal::Unaligned16Struct *>(_p)) \
+ ->value = (_val))
+#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
+ ((reinterpret_cast< ::absl::base_internal::Unaligned32Struct *>(_p)) \
+ ->value = (_val))
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
+namespace base_internal {
inline uint64_t UnalignedLoad64(const void *p) {
uint64_t t;
@@ -200,12 +256,14 @@ inline uint64_t UnalignedLoad64(const void *p) {
inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
-} // inline namespace lts_2018_06_20
+} // namespace base_internal
+} // inline namespace lts_2018_12_18
} // namespace absl
-#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
+ (absl::base_internal::UnalignedLoad64(_p))
#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
- (absl::UnalignedStore64(_p, _val))
+ (absl::base_internal::UnalignedStore64(_p, _val))
#else
@@ -217,7 +275,8 @@ inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
// unaligned loads and stores.
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
+namespace base_internal {
inline uint16_t UnalignedLoad16(const void *p) {
uint16_t t;
@@ -243,19 +302,23 @@ inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); }
inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
-} // inline namespace lts_2018_06_20
+} // namespace base_internal
+} // inline namespace lts_2018_12_18
} // namespace absl
-#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) (absl::UnalignedLoad16(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) (absl::UnalignedLoad32(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
+ (absl::base_internal::UnalignedLoad16(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
+ (absl::base_internal::UnalignedLoad32(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
+ (absl::base_internal::UnalignedLoad64(_p))
#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
- (absl::UnalignedStore16(_p, _val))
+ (absl::base_internal::UnalignedStore16(_p, _val))
#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
- (absl::UnalignedStore32(_p, _val))
+ (absl::base_internal::UnalignedStore32(_p, _val))
#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
- (absl::UnalignedStore64(_p, _val))
+ (absl::base_internal::UnalignedStore64(_p, _val))
#endif
diff --git a/absl/base/internal/unscaledcycleclock.cc b/absl/base/internal/unscaledcycleclock.cc
index e0798eb9..888caf1e 100644
--- a/absl/base/internal/unscaledcycleclock.cc
+++ b/absl/base/internal/unscaledcycleclock.cc
@@ -27,7 +27,7 @@
#include "absl/base/internal/sysinfo.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
#if defined(__i386__)
@@ -97,7 +97,7 @@ double UnscaledCycleClock::Frequency() {
#endif
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_USE_UNSCALED_CYCLECLOCK
diff --git a/absl/base/internal/unscaledcycleclock.h b/absl/base/internal/unscaledcycleclock.h
index 9da14d0b..c71674f3 100644
--- a/absl/base/internal/unscaledcycleclock.h
+++ b/absl/base/internal/unscaledcycleclock.h
@@ -84,7 +84,7 @@
#define ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY
#endif
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace time_internal {
class UnscaledCycleClockWrapperForGetCurrentTime;
} // namespace time_internal
@@ -114,7 +114,7 @@ class UnscaledCycleClock {
};
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_USE_UNSCALED_CYCLECLOCK
diff --git a/absl/base/invoke_test.cc b/absl/base/invoke_test.cc
index 2c04b591..4df637ac 100644
--- a/absl/base/invoke_test.cc
+++ b/absl/base/invoke_test.cc
@@ -25,7 +25,7 @@
#include "absl/strings/str_cat.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
namespace {
@@ -198,5 +198,5 @@ TEST(InvokeTest, SfinaeFriendly) {
} // namespace
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/log_severity.h b/absl/base/log_severity.h
index 8b7a66ba..c24fad79 100644
--- a/absl/base/log_severity.h
+++ b/absl/base/log_severity.h
@@ -21,7 +21,7 @@
#include "absl/base/attributes.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
// Four severity levels are defined. Logging APIs should terminate the program
// when a message is logged at severity `kFatal`; the other levels have no
@@ -40,7 +40,7 @@ constexpr std::array LogSeverities() {
absl::LogSeverity::kError, absl::LogSeverity::kFatal}};
}
-// Returns the all-caps std::string representation (e.g. "INFO") of the specified
+// Returns the all-caps string representation (e.g. "INFO") of the specified
// severity level if it is one of the normal levels and "UNKNOWN" otherwise.
constexpr const char* LogSeverityName(absl::LogSeverity s) {
return s == absl::LogSeverity::kInfo
@@ -63,7 +63,7 @@ constexpr absl::LogSeverity NormalizeLogSeverity(int s) {
return NormalizeLogSeverity(static_cast(s));
}
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_BASE_INTERNAL_LOG_SEVERITY_H_
diff --git a/absl/base/macros.h b/absl/base/macros.h
index aabe8db4..14c4b0a3 100644
--- a/absl/base/macros.h
+++ b/absl/base/macros.h
@@ -43,14 +43,14 @@
(sizeof(::absl::macros_internal::ArraySizeHelper(array)))
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace macros_internal {
// Note: this internal template function declaration is used by ABSL_ARRAYSIZE.
// The function doesn't need a definition, as we only use its type.
template
auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N];
} // namespace macros_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
// kLinkerInitialized
@@ -74,13 +74,13 @@ auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N];
// // Invocation
// static MyClass my_global(absl::base_internal::kLinkerInitialized);
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
enum LinkerInitialized {
kLinkerInitialized = 0,
};
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
// ABSL_FALLTHROUGH_INTENDED
@@ -203,4 +203,14 @@ enum LinkerInitialized {
: [] { 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/raw_logging_test.cc b/absl/base/raw_logging_test.cc
index dae4b351..b21cf651 100644
--- a/absl/base/raw_logging_test.cc
+++ b/absl/base/raw_logging_test.cc
@@ -18,12 +18,20 @@
#include "absl/base/internal/raw_logging.h"
+#include
+
#include "gtest/gtest.h"
+#include "absl/strings/str_cat.h"
namespace {
TEST(RawLoggingCompilationTest, Log) {
ABSL_RAW_LOG(INFO, "RAW INFO: %d", 1);
+ ABSL_RAW_LOG(INFO, "RAW INFO: %d %d", 1, 2);
+ ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d", 1, 2, 3);
+ ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d %d", 1, 2, 3, 4);
+ ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d %d %d", 1, 2, 3, 4, 5);
+ ABSL_RAW_LOG(WARNING, "RAW WARNING: %d", 1);
ABSL_RAW_LOG(ERROR, "RAW ERROR: %d", 1);
}
@@ -32,7 +40,7 @@ TEST(RawLoggingCompilationTest, PassingCheck) {
}
// Not all platforms support output from raw log, so we don't verify any
-// particular output for RAW check failures (expecting the empty std::string
+// particular output for RAW check failures (expecting the empty string
// accomplishes this). This test is primarily a compilation test, but we
// are verifying process death when EXPECT_DEATH works for a platform.
const char kExpectedDeathOutput[] = "";
@@ -47,4 +55,25 @@ TEST(RawLoggingDeathTest, LogFatal) {
kExpectedDeathOutput);
}
+TEST(InternalLog, CompilationTest) {
+ ABSL_INTERNAL_LOG(INFO, "Internal Log");
+ std::string log_msg = "Internal Log";
+ ABSL_INTERNAL_LOG(INFO, log_msg);
+
+ ABSL_INTERNAL_LOG(INFO, log_msg + " 2");
+
+ float d = 1.1f;
+ ABSL_INTERNAL_LOG(INFO, absl::StrCat("Internal log ", 3, " + ", d));
+}
+
+TEST(InternalLogDeathTest, FailingCheck) {
+ EXPECT_DEATH_IF_SUPPORTED(ABSL_INTERNAL_CHECK(1 == 0, "explanation"),
+ kExpectedDeathOutput);
+}
+
+TEST(InternalLogDeathTest, LogFatal) {
+ EXPECT_DEATH_IF_SUPPORTED(ABSL_INTERNAL_LOG(FATAL, "my dog has fleas"),
+ kExpectedDeathOutput);
+}
+
} // namespace
diff --git a/absl/base/spinlock_test_common.cc b/absl/base/spinlock_test_common.cc
index d04ee366..95382977 100644
--- a/absl/base/spinlock_test_common.cc
+++ b/absl/base/spinlock_test_common.cc
@@ -36,7 +36,7 @@ constexpr int32_t kNumThreads = 10;
constexpr int32_t kIters = 1000;
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace base_internal {
// This is defined outside of anonymous namespace so that it can be
@@ -156,7 +156,8 @@ TEST(SpinLock, WaitCyclesEncoding) {
// 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,
@@ -264,5 +265,5 @@ TEST(SpinLockWithThreads, DoesNotDeadlock) {
} // namespace
} // namespace base_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/base/thread_annotations.h b/absl/base/thread_annotations.h
index 8d30b932..2241ace4 100644
--- a/absl/base/thread_annotations.h
+++ b/absl/base/thread_annotations.h
@@ -31,7 +31,6 @@
// that evaluate to a concrete mutex object whenever possible. If the mutex
// you want to refer to is not in scope, you may use a member pointer
// (e.g. &MyClass::mutex_) to refer to a mutex in some (unknown) object.
-//
#ifndef ABSL_BASE_THREAD_ANNOTATIONS_H_
#define ABSL_BASE_THREAD_ANNOTATIONS_H_
@@ -109,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/compiler_config_setting.bzl b/absl/compiler_config_setting.bzl
new file mode 100644
index 00000000..b77c4f56
--- /dev/null
+++ b/absl/compiler_config_setting.bzl
@@ -0,0 +1,39 @@
+#
+# 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.
+#
+
+"""Creates config_setting that allows selecting based on 'compiler' value."""
+
+def create_llvm_config(name, visibility):
+ # The "do_not_use_tools_cpp_compiler_present" attribute exists to
+ # distinguish between older versions of Bazel that do not support
+ # "@bazel_tools//tools/cpp:compiler" flag_value, and newer ones that do.
+ # In the future, the only way to select on the compiler will be through
+ # flag_values{"@bazel_tools//tools/cpp:compiler"} and the else branch can
+ # be removed.
+ if hasattr(cc_common, "do_not_use_tools_cpp_compiler_present"):
+ native.config_setting(
+ name = name,
+ flag_values = {
+ "@bazel_tools//tools/cpp:compiler": "llvm",
+ },
+ visibility = visibility,
+ )
+ else:
+ native.config_setting(
+ name = name,
+ values = {"compiler": "llvm"},
+ visibility = visibility,
+ )
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index 119d5c88..afc869f4 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -19,17 +19,38 @@ load(
"ABSL_DEFAULT_COPTS",
"ABSL_TEST_COPTS",
"ABSL_EXCEPTIONS_FLAG",
+ "ABSL_EXCEPTIONS_FLAG_LINKOPTS",
)
package(default_visibility = ["//visibility:public"])
licenses(["notice"]) # Apache 2.0
+cc_library(
+ name = "compressed_tuple",
+ hdrs = ["internal/compressed_tuple.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ "//absl/utility",
+ ],
+)
+
+cc_test(
+ name = "compressed_tuple_test",
+ srcs = ["internal/compressed_tuple_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":compressed_tuple",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
cc_library(
name = "fixed_array",
hdrs = ["fixed_array.h"],
copts = ABSL_DEFAULT_COPTS,
deps = [
+ ":compressed_tuple",
"//absl/algorithm",
"//absl/base:core_headers",
"//absl/base:dynamic_annotations",
@@ -42,9 +63,11 @@ cc_test(
name = "fixed_array_test",
srcs = ["fixed_array_test.cc"],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":fixed_array",
"//absl/base:exception_testing",
+ "//absl/hash:hash_testing",
"//absl/memory",
"@com_google_googletest//:gtest_main",
],
@@ -57,11 +80,24 @@ cc_test(
deps = [
":fixed_array",
"//absl/base:exception_testing",
+ "//absl/hash:hash_testing",
"//absl/memory",
"@com_google_googletest//:gtest_main",
],
)
+cc_test(
+ name = "fixed_array_exception_safety_test",
+ srcs = ["fixed_array_exception_safety_test.cc"],
+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+ deps = [
+ ":fixed_array",
+ "//absl/base:exception_safety_testing",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
cc_test(
name = "fixed_array_benchmark",
srcs = ["fixed_array_benchmark.cc"],
@@ -89,12 +125,14 @@ cc_test(
name = "inlined_vector_test",
srcs = ["inlined_vector_test.cc"],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":inlined_vector",
":test_instance_tracker",
"//absl/base",
"//absl/base:core_headers",
"//absl/base:exception_testing",
+ "//absl/hash:hash_testing",
"//absl/memory",
"//absl/strings",
"@com_google_googletest//:gtest_main",
@@ -111,6 +149,7 @@ cc_test(
"//absl/base",
"//absl/base:core_headers",
"//absl/base:exception_testing",
+ "//absl/hash:hash_testing",
"//absl/memory",
"//absl/strings",
"@com_google_googletest//:gtest_main",
@@ -150,3 +189,462 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)
+
+NOTEST_TAGS_NONMOBILE = [
+ "no_test_darwin_x86_64",
+ "no_test_loonix",
+]
+
+NOTEST_TAGS_MOBILE = [
+ "no_test_android_arm",
+ "no_test_android_arm64",
+ "no_test_android_x86",
+ "no_test_ios_x86_64",
+]
+
+NOTEST_TAGS = NOTEST_TAGS_MOBILE + NOTEST_TAGS_NONMOBILE
+
+cc_library(
+ name = "flat_hash_map",
+ hdrs = ["flat_hash_map.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ ":container_memory",
+ ":hash_function_defaults",
+ ":raw_hash_map",
+ "//absl/algorithm:container",
+ "//absl/memory",
+ ],
+)
+
+cc_test(
+ name = "flat_hash_map_test",
+ srcs = ["flat_hash_map_test.cc"],
+ copts = ABSL_TEST_COPTS + ["-DUNORDERED_MAP_CXX17"],
+ tags = NOTEST_TAGS_NONMOBILE,
+ deps = [
+ ":flat_hash_map",
+ ":hash_generator_testing",
+ ":unordered_map_constructor_test",
+ ":unordered_map_lookup_test",
+ ":unordered_map_modifiers_test",
+ "//absl/types:any",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "flat_hash_set",
+ hdrs = ["flat_hash_set.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ ":container_memory",
+ ":hash_function_defaults",
+ ":raw_hash_set",
+ "//absl/algorithm:container",
+ "//absl/base:core_headers",
+ "//absl/memory",
+ ],
+)
+
+cc_test(
+ name = "flat_hash_set_test",
+ srcs = ["flat_hash_set_test.cc"],
+ copts = ABSL_TEST_COPTS + ["-DUNORDERED_SET_CXX17"],
+ tags = NOTEST_TAGS_NONMOBILE,
+ deps = [
+ ":flat_hash_set",
+ ":hash_generator_testing",
+ ":unordered_set_constructor_test",
+ ":unordered_set_lookup_test",
+ ":unordered_set_modifiers_test",
+ "//absl/memory",
+ "//absl/strings",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "node_hash_map",
+ hdrs = ["node_hash_map.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ ":container_memory",
+ ":hash_function_defaults",
+ ":node_hash_policy",
+ ":raw_hash_map",
+ "//absl/algorithm:container",
+ "//absl/memory",
+ ],
+)
+
+cc_test(
+ name = "node_hash_map_test",
+ srcs = ["node_hash_map_test.cc"],
+ copts = ABSL_TEST_COPTS + ["-DUNORDERED_MAP_CXX17"],
+ tags = NOTEST_TAGS_NONMOBILE,
+ deps = [
+ ":hash_generator_testing",
+ ":node_hash_map",
+ ":tracked",
+ ":unordered_map_constructor_test",
+ ":unordered_map_lookup_test",
+ ":unordered_map_modifiers_test",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "node_hash_set",
+ hdrs = ["node_hash_set.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ ":hash_function_defaults",
+ ":node_hash_policy",
+ ":raw_hash_set",
+ "//absl/algorithm:container",
+ "//absl/memory",
+ ],
+)
+
+cc_test(
+ name = "node_hash_set_test",
+ srcs = ["node_hash_set_test.cc"],
+ copts = ABSL_TEST_COPTS + ["-DUNORDERED_SET_CXX17"],
+ tags = NOTEST_TAGS_NONMOBILE,
+ deps = [
+ ":hash_generator_testing",
+ ":node_hash_set",
+ ":unordered_set_constructor_test",
+ ":unordered_set_lookup_test",
+ ":unordered_set_modifiers_test",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "container_memory",
+ hdrs = ["internal/container_memory.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ "//absl/memory",
+ "//absl/utility",
+ ],
+)
+
+cc_test(
+ name = "container_memory_test",
+ srcs = ["internal/container_memory_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ tags = NOTEST_TAGS_NONMOBILE,
+ deps = [
+ ":container_memory",
+ "//absl/strings",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "hash_function_defaults",
+ hdrs = ["internal/hash_function_defaults.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ "//absl/base:config",
+ "//absl/hash",
+ "//absl/strings",
+ ],
+)
+
+cc_test(
+ name = "hash_function_defaults_test",
+ srcs = ["internal/hash_function_defaults_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ tags = NOTEST_TAGS,
+ deps = [
+ ":hash_function_defaults",
+ "//absl/hash",
+ "//absl/strings",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "hash_generator_testing",
+ testonly = 1,
+ srcs = ["internal/hash_generator_testing.cc"],
+ hdrs = ["internal/hash_generator_testing.h"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":hash_policy_testing",
+ "//absl/meta:type_traits",
+ "//absl/strings",
+ ],
+)
+
+cc_library(
+ name = "hash_policy_testing",
+ testonly = 1,
+ hdrs = ["internal/hash_policy_testing.h"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ "//absl/hash",
+ "//absl/strings",
+ ],
+)
+
+cc_test(
+ name = "hash_policy_testing_test",
+ srcs = ["internal/hash_policy_testing_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":hash_policy_testing",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "hash_policy_traits",
+ hdrs = ["internal/hash_policy_traits.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = ["//absl/meta:type_traits"],
+)
+
+cc_test(
+ name = "hash_policy_traits_test",
+ srcs = ["internal/hash_policy_traits_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":hash_policy_traits",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "hashtable_debug",
+ hdrs = ["internal/hashtable_debug.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ ":hashtable_debug_hooks",
+ ],
+)
+
+cc_library(
+ name = "hashtable_debug_hooks",
+ hdrs = ["internal/hashtable_debug_hooks.h"],
+ copts = ABSL_DEFAULT_COPTS,
+)
+
+cc_library(
+ name = "node_hash_policy",
+ hdrs = ["internal/node_hash_policy.h"],
+ copts = ABSL_DEFAULT_COPTS,
+)
+
+cc_test(
+ name = "node_hash_policy_test",
+ srcs = ["internal/node_hash_policy_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":hash_policy_traits",
+ ":node_hash_policy",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "raw_hash_map",
+ hdrs = ["internal/raw_hash_map.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ ":container_memory",
+ ":raw_hash_set",
+ ],
+)
+
+cc_library(
+ name = "raw_hash_set",
+ srcs = ["internal/raw_hash_set.cc"],
+ hdrs = ["internal/raw_hash_set.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ ":compressed_tuple",
+ ":container_memory",
+ ":hash_policy_traits",
+ ":hashtable_debug_hooks",
+ ":layout",
+ "//absl/base:bits",
+ "//absl/base:config",
+ "//absl/base:core_headers",
+ "//absl/base:endian",
+ "//absl/memory",
+ "//absl/meta:type_traits",
+ "//absl/types:optional",
+ "//absl/utility",
+ ],
+)
+
+cc_test(
+ name = "raw_hash_set_test",
+ srcs = ["internal/raw_hash_set_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ linkstatic = 1,
+ tags = NOTEST_TAGS,
+ deps = [
+ ":container_memory",
+ ":hash_function_defaults",
+ ":hash_policy_testing",
+ ":hashtable_debug",
+ ":raw_hash_set",
+ "//absl/base",
+ "//absl/base:core_headers",
+ "//absl/strings",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_test(
+ name = "raw_hash_set_allocator_test",
+ size = "small",
+ srcs = ["internal/raw_hash_set_allocator_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":raw_hash_set",
+ ":tracked",
+ "//absl/base:core_headers",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "layout",
+ hdrs = ["internal/layout.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ "//absl/base:core_headers",
+ "//absl/meta:type_traits",
+ "//absl/strings",
+ "//absl/types:span",
+ "//absl/utility",
+ ],
+)
+
+cc_test(
+ name = "layout_test",
+ size = "small",
+ srcs = ["internal/layout_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ tags = NOTEST_TAGS,
+ visibility = ["//visibility:private"],
+ deps = [
+ ":layout",
+ "//absl/base",
+ "//absl/base:core_headers",
+ "//absl/types:span",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "tracked",
+ testonly = 1,
+ hdrs = ["internal/tracked.h"],
+ copts = ABSL_TEST_COPTS,
+)
+
+cc_library(
+ name = "unordered_map_constructor_test",
+ testonly = 1,
+ hdrs = ["internal/unordered_map_constructor_test.h"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":hash_generator_testing",
+ ":hash_policy_testing",
+ "@com_google_googletest//:gtest",
+ ],
+)
+
+cc_library(
+ name = "unordered_map_lookup_test",
+ testonly = 1,
+ hdrs = ["internal/unordered_map_lookup_test.h"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":hash_generator_testing",
+ ":hash_policy_testing",
+ "@com_google_googletest//:gtest",
+ ],
+)
+
+cc_library(
+ name = "unordered_map_modifiers_test",
+ testonly = 1,
+ hdrs = ["internal/unordered_map_modifiers_test.h"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":hash_generator_testing",
+ ":hash_policy_testing",
+ "@com_google_googletest//:gtest",
+ ],
+)
+
+cc_library(
+ name = "unordered_set_constructor_test",
+ testonly = 1,
+ hdrs = ["internal/unordered_set_constructor_test.h"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":hash_generator_testing",
+ ":hash_policy_testing",
+ "@com_google_googletest//:gtest",
+ ],
+)
+
+cc_library(
+ name = "unordered_set_lookup_test",
+ testonly = 1,
+ hdrs = ["internal/unordered_set_lookup_test.h"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":hash_generator_testing",
+ ":hash_policy_testing",
+ "@com_google_googletest//:gtest",
+ ],
+)
+
+cc_library(
+ name = "unordered_set_modifiers_test",
+ testonly = 1,
+ hdrs = ["internal/unordered_set_modifiers_test.h"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":hash_generator_testing",
+ ":hash_policy_testing",
+ "@com_google_googletest//:gtest",
+ ],
+)
+
+cc_test(
+ name = "unordered_set_test",
+ srcs = ["internal/unordered_set_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ tags = NOTEST_TAGS_NONMOBILE,
+ deps = [
+ ":unordered_set_constructor_test",
+ ":unordered_set_lookup_test",
+ ":unordered_set_modifiers_test",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_test(
+ name = "unordered_map_test",
+ srcs = ["internal/unordered_map_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ tags = NOTEST_TAGS_NONMOBILE,
+ deps = [
+ ":unordered_map_constructor_test",
+ ":unordered_map_lookup_test",
+ ":unordered_map_modifiers_test",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index f56ce92d..8605facc 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -14,113 +14,674 @@
# limitations under the License.
#
+# 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
+)
-list(APPEND CONTAINER_PUBLIC_HEADERS
- "fixed_array.h"
- "inlined_vector.h"
+absl_cc_library(
+ NAME
+ compressed_tuple
+ HDRS
+ "internal/compressed_tuple.h"
+ DEPS
+ absl::utility
+ PUBLIC
)
+absl_cc_test(
+ NAME
+ compressed_tuple_test
+ SRCS
+ "internal/compressed_tuple_test.cc"
+ DEPS
+ absl::compressed_tuple
+ gmock_main
+)
-list(APPEND CONTAINER_INTERNAL_HEADERS
- "internal/test_instance_tracker.h"
+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
)
+absl_cc_test(
+ NAME
+ fixed_array_test
+ 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_header_library(
- TARGET
- absl_container
- EXPORT_NAME
- container
+absl_cc_test(
+ NAME
+ fixed_array_test_noexceptions
+ SRCS
+ "fixed_array_test.cc"
+ DEPS
+ absl::fixed_array
+ absl::exception_testing
+ absl::hash_testing
+ absl::memory
+ gmock_main
)
+absl_cc_test(
+ NAME
+ fixed_array_exception_safety_test
+ 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
+)
-#
-## TESTS
-#
+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
+)
+
+absl_cc_test(
+ NAME
+ inlined_vector_test
+ 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_cc_test(
+ NAME
+ inlined_vector_test_noexceptions
+ 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
+)
-list(APPEND TEST_INSTANCE_TRACKER_LIB_SRC
- "internal/test_instance_tracker.cc"
- ${CONTAINER_PUBLIC_HEADERS}
- ${CONTAINER_INTERNAL_HEADERS}
+absl_cc_library(
+ NAME
+ test_instance_tracker
+ HDRS
+ "internal/test_instance_tracker.h"
+ SRCS
+ "internal/test_instance_tracker.cc"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
+ TESTONLY
)
+absl_cc_test(
+ NAME
+ test_instance_tracker_test
+ SRCS
+ "internal/test_instance_tracker_test.cc"
+ DEPS
+ absl::test_instance_tracker
+ gmock_main
+)
-absl_library(
- TARGET
- test_instance_tracker_lib
- SOURCES
- ${TEST_INSTANCE_TRACKER_LIB_SRC}
- PUBLIC_LIBRARIES
- absl::container
- DISABLE_INSTALL
+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_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
+)
-# 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_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_test(
- TARGET
- fixed_array_test
- SOURCES
- ${FIXED_ARRAY_TEST_SRC}
- PUBLIC_LIBRARIES
- ${FIXED_ARRAY_TEST_PUBLIC_LIBRARIES}
- PRIVATE_COMPILE_FLAGS
- ${ABSL_EXCEPTIONS_FLAG}
+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_test(
- TARGET
- fixed_array_test_noexceptions
- SOURCES
- ${FIXED_ARRAY_TEST_SRC}
- PUBLIC_LIBRARIES
- ${FIXED_ARRAY_TEST_PUBLIC_LIBRARIES}
+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
+)
-# 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_cc_test(
+ NAME
+ container_memory_test
+ SRCS
+ "internal/container_memory_test.cc"
+ DEPS
+ absl::container_memory
+ absl::strings
+ gmock_main
+)
-absl_test(
- TARGET
- inlined_vector_test
- SOURCES
- ${INLINED_VECTOR_TEST_SRC}
- PUBLIC_LIBRARIES
- ${INLINED_VECTOR_TEST_PUBLIC_LIBRARIES}
+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_test(
- TARGET
- inlined_vector_test_noexceptions
- SOURCES
- ${INLINED_VECTOR_TEST_SRC}
- PUBLIC_LIBRARIES
- ${INLINED_VECTOR_TEST_PUBLIC_LIBRARIES}
- PRIVATE_COMPILE_FLAGS
- ${ABSL_NOEXCEPTION_CXXFLAGS}
+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
+)
-# 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_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_test(
- TARGET
- test_instance_tracker_test
- SOURCES
- ${TEST_INSTANCE_TRACKER_TEST_SRC}
- PUBLIC_LIBRARIES
- ${TEST_INSTANCE_TRACKER_TEST_PUBLIC_LIBRARIES}
+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
+ SRCS
+ "internal/raw_hash_set_test.cc"
+ 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 daa4eb22..7f6a3afd 100644
--- a/absl/container/fixed_array.h
+++ b/absl/container/fixed_array.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.
@@ -47,10 +47,11 @@
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
+#include "absl/container/internal/compressed_tuple.h"
#include "absl/memory/memory.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
constexpr static auto kFixedArrayUseDefault = static_cast(-1);
@@ -58,13 +59,13 @@ constexpr static auto kFixedArrayUseDefault = static_cast(-1);
// FixedArray
// -----------------------------------------------------------------------------
//
-// A `FixedArray` provides a run-time fixed-size array, allocating small arrays
-// inline for efficiency and correctness.
+// A `FixedArray` provides a run-time fixed-size array, allocating a small array
+// inline for efficiency.
//
// Most users should not specify an `inline_elements` argument and let
-// `FixedArray<>` automatically determine the number of elements
+// `FixedArray` automatically determine the number of elements
// to store inline based on `sizeof(T)`. If `inline_elements` is specified, the
-// `FixedArray<>` implementation will inline arrays of
+// `FixedArray` implementation will use inline storage for arrays with a
// length <= `inline_elements`.
//
// Note that a `FixedArray` constructed with a `size_type` argument will
@@ -77,65 +78,100 @@ constexpr static auto kFixedArrayUseDefault = static_cast(-1);
// heap allocation, it will do so with global `::operator new[]()` and
// `::operator delete[]()`, even if T provides class-scope overrides for these
// operators.
-template